From 276c5de0d86abab52a19f489dd74565fdec0d3ca Mon Sep 17 00:00:00 2001 From: Anatoliy Belsky Date: Fri, 19 Oct 2012 09:49:28 +0200 Subject: [PATCH] Fixed bug #63284 PCRE upgrade to 8.31 --- ext/pcre/config.w32 | 2 +- ext/pcre/config0.m4 | 4 +- ext/pcre/pcrelib/AUTHORS | 26 +- ext/pcre/pcrelib/ChangeLog | 693 ++ ext/pcre/pcrelib/HACKING | 280 +- ext/pcre/pcrelib/LICENCE | 30 +- ext/pcre/pcrelib/NEWS | 76 + ext/pcre/pcrelib/NON-UNIX-USE | 500 +- ext/pcre/pcrelib/README | 419 +- ext/pcre/pcrelib/config.h | 6 +- ext/pcre/pcrelib/dftables.c | 4 +- ext/pcre/pcrelib/doc/pcre.txt | 6279 ++++++++++------- ext/pcre/pcrelib/pcre.h | 269 +- ext/pcre/pcrelib/pcre_compile.c | 3214 ++++++--- ext/pcre/pcrelib/pcre_config.c | 48 +- ext/pcre/pcrelib/pcre_exec.c | 3630 ++++++---- ext/pcre/pcrelib/pcre_fullinfo.c | 66 +- ext/pcre/pcrelib/pcre_get.c | 196 +- ext/pcre/pcrelib/pcre_globals.c | 22 +- ext/pcre/pcrelib/pcre_info.c | 91 - ext/pcre/pcrelib/pcre_internal.h | 1141 ++- ext/pcre/pcrelib/pcre_maketables.c | 13 +- ext/pcre/pcrelib/pcre_newline.c | 50 +- ext/pcre/pcrelib/pcre_ord2utf8.c | 30 +- ext/pcre/pcrelib/pcre_refcount.c | 11 +- ext/pcre/pcrelib/pcre_study.c | 733 +- ext/pcre/pcrelib/pcre_tables.c | 340 +- ext/pcre/pcrelib/pcre_try_flipped.c | 137 - ext/pcre/pcrelib/pcre_ucd.c | 4735 +++++++------ ext/pcre/pcrelib/pcre_valid_utf8.c | 253 +- ext/pcre/pcrelib/pcre_version.c | 7 +- ext/pcre/pcrelib/pcre_xclass.c | 54 +- ext/pcre/pcrelib/pcredemo.c | 2 +- ext/pcre/pcrelib/pcreposix.c | 20 +- ext/pcre/pcrelib/pcreposix.h | 2 +- ext/pcre/pcrelib/testdata/grepinput | 2 + ext/pcre/pcrelib/testdata/grepinput8 | 3 +- ext/pcre/pcrelib/testdata/grepoutput | 99 +- ext/pcre/pcrelib/testdata/grepoutput8 | 5 +- ext/pcre/pcrelib/testdata/grepoutputN | 16 +- ext/pcre/pcrelib/testdata/testinput1 | 1185 +++- ext/pcre/pcrelib/testdata/testinput10 | 1070 ++- ext/pcre/pcrelib/testdata/testinput2 | 1133 +-- ext/pcre/pcrelib/testdata/testinput4 | 53 +- ext/pcre/pcrelib/testdata/testinput5 | 393 +- ext/pcre/pcrelib/testdata/testinput6 | 17 +- ext/pcre/pcrelib/testdata/testinput7 | 5133 ++------------ ext/pcre/pcrelib/testdata/testinput8 | 5210 ++++++++++++-- ext/pcre/pcrelib/testdata/testinput9 | 1628 ++--- ext/pcre/pcrelib/testdata/testoutput1 | 2069 +++++- ext/pcre/pcrelib/testdata/testoutput10 | 2746 ++++++-- ext/pcre/pcrelib/testdata/testoutput2 | 2584 +++++-- ext/pcre/pcrelib/testdata/testoutput4 | 79 +- ext/pcre/pcrelib/testdata/testoutput5 | 1334 ++-- ext/pcre/pcrelib/testdata/testoutput6 | 28 +- ext/pcre/pcrelib/testdata/testoutput7 | 8854 ++++------------------- ext/pcre/pcrelib/testdata/testoutput8 | 8978 +++++++++++++++++++++--- ext/pcre/pcrelib/testdata/testoutput9 | 3236 ++++----- ext/pcre/pcrelib/ucp.h | 14 +- 59 files changed, 40225 insertions(+), 29027 deletions(-) delete mode 100644 ext/pcre/pcrelib/pcre_info.c delete mode 100644 ext/pcre/pcrelib/pcre_try_flipped.c diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index 5d6fa90594e..52673f5d508 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -3,7 +3,7 @@ EXTENSION("pcre", "php_pcre.c", false /* never shared */, "-Iext/pcre/pcrelib"); -ADD_SOURCES("ext/pcre/pcrelib", "pcre_chartables.c pcre_ucd.c pcre_compile.c pcre_config.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_try_flipped.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c", "pcre"); +ADD_SOURCES("ext/pcre/pcrelib", "pcre_chartables.c pcre_ucd.c pcre_compile.c pcre_config.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_maketables.c pcre_newline.c pcre_ord2utf8.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c", "pcre"); ADD_DEF_FILE("ext\\pcre\\php_pcre.def"); AC_DEFINE('HAVE_BUNDLED_PCRE', 1, 'Using bundled PCRE library'); diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 644ebbd3286..f1ce0661ec7 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -55,9 +55,9 @@ PHP_ARG_WITH(pcre-regex,, pcrelib_sources="pcrelib/pcre_chartables.c pcrelib/pcre_ucd.c \ pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_exec.c \ pcrelib/pcre_fullinfo.c pcrelib/pcre_get.c pcrelib/pcre_globals.c \ - pcrelib/pcre_info.c pcrelib/pcre_maketables.c pcrelib/pcre_newline.c \ + pcrelib/pcre_maketables.c pcrelib/pcre_newline.c \ pcrelib/pcre_ord2utf8.c pcrelib/pcre_refcount.c pcrelib/pcre_study.c \ - pcrelib/pcre_tables.c pcrelib/pcre_try_flipped.c pcrelib/pcre_valid_utf8.c \ + pcrelib/pcre_tables.c pcrelib/pcre_valid_utf8.c \ pcrelib/pcre_version.c pcrelib/pcre_xclass.c" PHP_NEW_EXTENSION(pcre, $pcrelib_sources php_pcre.c, no,,-I@ext_srcdir@/pcrelib) PHP_ADD_BUILD_DIR($ext_builddir/pcrelib) diff --git a/ext/pcre/pcrelib/AUTHORS b/ext/pcre/pcrelib/AUTHORS index 88db849d4dd..ba4753d8583 100644 --- a/ext/pcre/pcrelib/AUTHORS +++ b/ext/pcre/pcrelib/AUTHORS @@ -8,16 +8,38 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2010 University of Cambridge +Copyright (c) 1997-2012 University of Cambridge All rights reserved +PCRE JUST-IN-TIME COMPILATION SUPPORT +------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2012 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2012 Zoltan Herczeg +All rights reserved. + + THE C++ WRAPPER LIBRARY ----------------------- Written by: Google Inc. -Copyright (c) 2007-2010 Google Inc +Copyright (c) 2007-2012 Google Inc All rights reserved #### diff --git a/ext/pcre/pcrelib/ChangeLog b/ext/pcre/pcrelib/ChangeLog index 8a301403603..fe85d671deb 100644 --- a/ext/pcre/pcrelib/ChangeLog +++ b/ext/pcre/pcrelib/ChangeLog @@ -1,6 +1,699 @@ ChangeLog for PCRE ------------------ +Version 8.31 06-July-2012 +------------------------- + +1. Fixing a wrong JIT test case and some compiler warnings. + +2. Removed a bashism from the RunTest script. + +3. Add a cast to pcre_exec.c to fix the warning "unary minus operator applied + to unsigned type, result still unsigned" that was given by an MS compiler + on encountering the code "-sizeof(xxx)". + +4. Partial matching support is added to the JIT compiler. + +5. Fixed several bugs concerned with partial matching of items that consist + of more than one character: + + (a) /^(..)\1/ did not partially match "aba" because checking references was + done on an "all or nothing" basis. This also applied to repeated + references. + + (b) \R did not give a hard partial match if \r was found at the end of the + subject. + + (c) \X did not give a hard partial match after matching one or more + characters at the end of the subject. + + (d) When newline was set to CRLF, a pattern such as /a$/ did not recognize + a partial match for the string "\r". + + (e) When newline was set to CRLF, the metacharacter "." did not recognize + a partial match for a CR character at the end of the subject string. + +6. If JIT is requested using /S++ or -s++ (instead of just /S+ or -s+) when + running pcretest, the text "(JIT)" added to the output whenever JIT is + actually used to run the match. + +7. Individual JIT compile options can be set in pcretest by following -s+[+] + or /S+[+] with a digit between 1 and 7. + +8. OP_NOT now supports any UTF character not just single-byte ones. + +9. (*MARK) control verb is now supported by the JIT compiler. + +10. The command "./RunTest list" lists the available tests without actually + running any of them. (Because I keep forgetting what they all are.) + +11. Add PCRE_INFO_MAXLOOKBEHIND. + +12. Applied a (slightly modified) user-supplied patch that improves performance + when the heap is used for recursion (compiled with --disable-stack-for- + recursion). Instead of malloc and free for each heap frame each time a + logical recursion happens, frames are retained on a chain and re-used where + possible. This sometimes gives as much as 30% improvement. + +13. As documented, (*COMMIT) is now confined to within a recursive subpattern + call. + +14. As documented, (*COMMIT) is now confined to within a positive assertion. + +15. It is now possible to link pcretest with libedit as an alternative to + libreadline. + +16. (*COMMIT) control verb is now supported by the JIT compiler. + +17. The Unicode data tables have been updated to Unicode 6.1.0. + +18. Added --file-list option to pcregrep. + +19. Added binary file support to pcregrep, including the -a, --binary-files, + -I, and --text options. + +20. The madvise function is renamed for posix_madvise for QNX compatibility + reasons. Fixed by Giuseppe D'Angelo. + +21. Fixed a bug for backward assertions with REVERSE 0 in the JIT compiler. + +22. Changed the option for creating symbolic links for 16-bit man pages from + -s to -sf so that re-installing does not cause issues. + +23. Support PCRE_NO_START_OPTIMIZE in JIT as (*MARK) support requires it. + +24. Fixed a very old bug in pcretest that caused errors with restarted DFA + matches in certain environments (the workspace was not being correctly + retained). Also added to pcre_dfa_exec() a simple plausibility check on + some of the workspace data at the beginning of a restart. + +25. \s*\R was auto-possessifying the \s* when it should not, whereas \S*\R + was not doing so when it should - probably a typo introduced by SVN 528 + (change 8.10/14). + +26. When PCRE_UCP was not set, \w+\x{c4} was incorrectly auto-possessifying the + \w+ when the character tables indicated that \x{c4} was a word character. + There were several related cases, all because the tests for doing a table + lookup were testing for characters less than 127 instead of 255. + +27. If a pattern contains capturing parentheses that are not used in a match, + their slots in the ovector are set to -1. For those that are higher than + any matched groups, this happens at the end of processing. In the case when + there were back references that the ovector was too small to contain + (causing temporary malloc'd memory to be used during matching), and the + highest capturing number was not used, memory off the end of the ovector + was incorrectly being set to -1. (It was using the size of the temporary + memory instead of the true size.) + +28. To catch bugs like 27 using valgrind, when pcretest is asked to specify an + ovector size, it uses memory at the end of the block that it has got. + +29. Check for an overlong MARK name and give an error at compile time. The + limit is 255 for the 8-bit library and 65535 for the 16-bit library. + +30. JIT compiler update. + +31. JIT is now supported on jailbroken iOS devices. Thanks for Ruiger + Rill for the patch. + +32. Put spaces around SLJIT_PRINT_D in the JIT compiler. Required by CXX11. + +33. Variable renamings in the PCRE-JIT compiler. No functionality change. + +34. Fixed typos in pcregrep: in two places there was SUPPORT_LIBZ2 instead of + SUPPORT_LIBBZ2. This caused a build problem when bzip2 but not gzip (zlib) + was enabled. + +35. Improve JIT code generation for greedy plus quantifier. + +36. When /((?:a?)*)*c/ or /((?>a?)*)*c/ was matched against "aac", it set group + 1 to "aa" instead of to an empty string. The bug affected repeated groups + that could potentially match an empty string. + +37. Optimizing single character iterators in JIT. + +38. Wide characters specified with \uxxxx in JavaScript mode are now subject to + the same checks as \x{...} characters in non-JavaScript mode. Specifically, + codepoints that are too big for the mode are faulted, and in a UTF mode, + disallowed codepoints are also faulted. + +39. If PCRE was compiled with UTF support, in three places in the DFA + matcher there was code that should only have been obeyed in UTF mode, but + was being obeyed unconditionally. In 8-bit mode this could cause incorrect + processing when bytes with values greater than 127 were present. In 16-bit + mode the bug would be provoked by values in the range 0xfc00 to 0xdc00. In + both cases the values are those that cannot be the first data item in a UTF + character. The three items that might have provoked this were recursions, + possessively repeated groups, and atomic groups. + +40. Ensure that libpcre is explicitly listed in the link commands for pcretest + and pcregrep, because some OS require shared objects to be explicitly + passed to ld, causing the link step to fail if they are not. + +41. There were two incorrect #ifdefs in pcre_study.c, meaning that, in 16-bit + mode, patterns that started with \h* or \R* might be incorrectly matched. + + +Version 8.30 04-February-2012 +----------------------------- + +1. Renamed "isnumber" as "is_a_number" because in some Mac environments this + name is defined in ctype.h. + +2. Fixed a bug in fixed-length calculation for lookbehinds that would show up + only in quite long subpatterns. + +3. Removed the function pcre_info(), which has been obsolete and deprecated + since it was replaced by pcre_fullinfo() in February 2000. + +4. For a non-anchored pattern, if (*SKIP) was given with a name that did not + match a (*MARK), and the match failed at the start of the subject, a + reference to memory before the start of the subject could occur. This bug + was introduced by fix 17 of release 8.21. + +5. A reference to an unset group with zero minimum repetition was giving + totally wrong answers (in non-JavaScript-compatibility mode). For example, + /(another)?(\1?)test/ matched against "hello world test". This bug was + introduced in release 8.13. + +6. Add support for 16-bit character strings (a large amount of work involving + many changes and refactorings). + +7. RunGrepTest failed on msys because \r\n was replaced by whitespace when the + command "pattern=`printf 'xxx\r\njkl'`" was run. The pattern is now taken + from a file. + +8. Ovector size of 2 is also supported by JIT based pcre_exec (the ovector size + rounding is not applied in this particular case). + +9. The invalid Unicode surrogate codepoints U+D800 to U+DFFF are now rejected + if they appear, or are escaped, in patterns. + +10. Get rid of a number of -Wunused-but-set-variable warnings. + +11. The pattern /(?=(*:x))(q|)/ matches an empty string, and returns the mark + "x". The similar pattern /(?=(*:x))((*:y)q|)/ did not return a mark at all. + Oddly, Perl behaves the same way. PCRE has been fixed so that this pattern + also returns the mark "x". This bug applied to capturing parentheses, + non-capturing parentheses, and atomic parentheses. It also applied to some + assertions. + +12. Stephen Kelly's patch to CMakeLists.txt allows it to parse the version + information out of configure.ac instead of relying on pcre.h.generic, which + is not stored in the repository. + +13. Applied Dmitry V. Levin's patch for a more portable method for linking with + -lreadline. + +14. ZH added PCRE_CONFIG_JITTARGET; added its output to pcretest -C. + +15. Applied Graycode's patch to put the top-level frame on the stack rather + than the heap when not using the stack for recursion. This gives a + performance improvement in many cases when recursion is not deep. + +16. Experimental code added to "pcretest -C" to output the stack frame size. + + +Version 8.21 12-Dec-2011 +------------------------ + +1. Updating the JIT compiler. + +2. JIT compiler now supports OP_NCREF, OP_RREF and OP_NRREF. New test cases + are added as well. + +3. Fix cache-flush issue on PowerPC (It is still an experimental JIT port). + PCRE_EXTRA_TABLES is not suported by JIT, and should be checked before + calling _pcre_jit_exec. Some extra comments are added. + +4. (*MARK) settings inside atomic groups that do not contain any capturing + parentheses, for example, (?>a(*:m)), were not being passed out. This bug + was introduced by change 18 for 8.20. + +5. Supporting of \x, \U and \u in JavaScript compatibility mode based on the + ECMA-262 standard. + +6. Lookbehinds such as (?<=a{2}b) that contained a fixed repetition were + erroneously being rejected as "not fixed length" if PCRE_CASELESS was set. + This bug was probably introduced by change 9 of 8.13. + +7. While fixing 6 above, I noticed that a number of other items were being + incorrectly rejected as "not fixed length". This arose partly because newer + opcodes had not been added to the fixed-length checking code. I have (a) + corrected the bug and added tests for these items, and (b) arranged for an + error to occur if an unknown opcode is encountered while checking for fixed + length instead of just assuming "not fixed length". The items that were + rejected were: (*ACCEPT), (*COMMIT), (*FAIL), (*MARK), (*PRUNE), (*SKIP), + (*THEN), \h, \H, \v, \V, and single character negative classes with fixed + repetitions, e.g. [^a]{3}, with and without PCRE_CASELESS. + +8. A possessively repeated conditional subpattern such as (?(?=c)c|d)++ was + being incorrectly compiled and would have given unpredicatble results. + +9. A possessively repeated subpattern with minimum repeat count greater than + one behaved incorrectly. For example, (A){2,}+ behaved as if it was + (A)(A)++ which meant that, after a subsequent mismatch, backtracking into + the first (A) could occur when it should not. + +10. Add a cast and remove a redundant test from the code. + +11. JIT should use pcre_malloc/pcre_free for allocation. + +12. Updated pcre-config so that it no longer shows -L/usr/lib, which seems + best practice nowadays, and helps with cross-compiling. (If the exec_prefix + is anything other than /usr, -L is still shown). + +13. In non-UTF-8 mode, \C is now supported in lookbehinds and DFA matching. + +14. Perl does not support \N without a following name in a [] class; PCRE now + also gives an error. + +15. If a forward reference was repeated with an upper limit of around 2000, + it caused the error "internal error: overran compiling workspace". The + maximum number of forward references (including repeats) was limited by the + internal workspace, and dependent on the LINK_SIZE. The code has been + rewritten so that the workspace expands (via pcre_malloc) if necessary, and + the default depends on LINK_SIZE. There is a new upper limit (for safety) + of around 200,000 forward references. While doing this, I also speeded up + the filling in of repeated forward references. + +16. A repeated forward reference in a pattern such as (a)(?2){2}(.) was + incorrectly expecting the subject to contain another "a" after the start. + +17. When (*SKIP:name) is activated without a corresponding (*MARK:name) earlier + in the match, the SKIP should be ignored. This was not happening; instead + the SKIP was being treated as NOMATCH. For patterns such as + /A(*MARK:A)A+(*SKIP:B)Z|AAC/ this meant that the AAC branch was never + tested. + +18. The behaviour of (*MARK), (*PRUNE), and (*THEN) has been reworked and is + now much more compatible with Perl, in particular in cases where the result + is a non-match for a non-anchored pattern. For example, if + /b(*:m)f|a(*:n)w/ is matched against "abc", the non-match returns the name + "m", where previously it did not return a name. A side effect of this + change is that for partial matches, the last encountered mark name is + returned, as for non matches. A number of tests that were previously not + Perl-compatible have been moved into the Perl-compatible test files. The + refactoring has had the pleasing side effect of removing one argument from + the match() function, thus reducing its stack requirements. + +19. If the /S+ option was used in pcretest to study a pattern using JIT, + subsequent uses of /S (without +) incorrectly behaved like /S+. + +21. Retrieve executable code size support for the JIT compiler and fixing + some warnings. + +22. A caseless match of a UTF-8 character whose other case uses fewer bytes did + not work when the shorter character appeared right at the end of the + subject string. + +23. Added some (int) casts to non-JIT modules to reduce warnings on 64-bit + systems. + +24. Added PCRE_INFO_JITSIZE to pass on the value from (21) above, and also + output it when the /M option is used in pcretest. + +25. The CheckMan script was not being included in the distribution. Also, added + an explicit "perl" to run Perl scripts from the PrepareRelease script + because this is reportedly needed in Windows. + +26. If study data was being save in a file and studying had not found a set of + "starts with" bytes for the pattern, the data written to the file (though + never used) was taken from uninitialized memory and so caused valgrind to + complain. + +27. Updated RunTest.bat as provided by Sheri Pierce. + +28. Fixed a possible uninitialized memory bug in pcre_jit_compile.c. + +29. Computation of memory usage for the table of capturing group names was + giving an unnecessarily large value. + + +Version 8.20 21-Oct-2011 +------------------------ + +1. Change 37 of 8.13 broke patterns like [:a]...[b:] because it thought it had + a POSIX class. After further experiments with Perl, which convinced me that + Perl has bugs and confusions, a closing square bracket is no longer allowed + in a POSIX name. This bug also affected patterns with classes that started + with full stops. + +2. If a pattern such as /(a)b|ac/ is matched against "ac", there is no + captured substring, but while checking the failing first alternative, + substring 1 is temporarily captured. If the output vector supplied to + pcre_exec() was not big enough for this capture, the yield of the function + was still zero ("insufficient space for captured substrings"). This cannot + be totally fixed without adding another stack variable, which seems a lot + of expense for a edge case. However, I have improved the situation in cases + such as /(a)(b)x|abc/ matched against "abc", where the return code + indicates that fewer than the maximum number of slots in the ovector have + been set. + +3. Related to (2) above: when there are more back references in a pattern than + slots in the output vector, pcre_exec() uses temporary memory during + matching, and copies in the captures as far as possible afterwards. It was + using the entire output vector, but this conflicts with the specification + that only 2/3 is used for passing back captured substrings. Now it uses + only the first 2/3, for compatibility. This is, of course, another edge + case. + +4. Zoltan Herczeg's just-in-time compiler support has been integrated into the + main code base, and can be used by building with --enable-jit. When this is + done, pcregrep automatically uses it unless --disable-pcregrep-jit or the + runtime --no-jit option is given. + +5. When the number of matches in a pcre_dfa_exec() run exactly filled the + ovector, the return from the function was zero, implying that there were + other matches that did not fit. The correct "exactly full" value is now + returned. + +6. If a subpattern that was called recursively or as a subroutine contained + (*PRUNE) or any other control that caused it to give a non-standard return, + invalid errors such as "Error -26 (nested recursion at the same subject + position)" or even infinite loops could occur. + +7. If a pattern such as /a(*SKIP)c|b(*ACCEPT)|/ was studied, it stopped + computing the minimum length on reaching *ACCEPT, and so ended up with the + wrong value of 1 rather than 0. Further investigation indicates that + computing a minimum subject length in the presence of *ACCEPT is difficult + (think back references, subroutine calls), and so I have changed the code + so that no minimum is registered for a pattern that contains *ACCEPT. + +8. If (*THEN) was present in the first (true) branch of a conditional group, + it was not handled as intended. [But see 16 below.] + +9. Replaced RunTest.bat and CMakeLists.txt with improved versions provided by + Sheri Pierce. + +10. A pathological pattern such as /(*ACCEPT)a/ was miscompiled, thinking that + the first byte in a match must be "a". + +11. Change 17 for 8.13 increased the recursion depth for patterns like + /a(?:.)*?a/ drastically. I've improved things by remembering whether a + pattern contains any instances of (*THEN). If it does not, the old + optimizations are restored. It would be nice to do this on a per-group + basis, but at the moment that is not feasible. + +12. In some environments, the output of pcretest -C is CRLF terminated. This + broke RunTest's code that checks for the link size. A single white space + character after the value is now allowed for. + +13. RunTest now checks for the "fr" locale as well as for "fr_FR" and "french". + For "fr", it uses the Windows-specific input and output files. + +14. If (*THEN) appeared in a group that was called recursively or as a + subroutine, it did not work as intended. [But see next item.] + +15. Consider the pattern /A (B(*THEN)C) | D/ where A, B, C, and D are complex + pattern fragments (but not containing any | characters). If A and B are + matched, but there is a failure in C so that it backtracks to (*THEN), PCRE + was behaving differently to Perl. PCRE backtracked into A, but Perl goes to + D. In other words, Perl considers parentheses that do not contain any | + characters to be part of a surrounding alternative, whereas PCRE was + treading (B(*THEN)C) the same as (B(*THEN)C|(*FAIL)) -- which Perl handles + differently. PCRE now behaves in the same way as Perl, except in the case + of subroutine/recursion calls such as (?1) which have in any case always + been different (but PCRE had them first :-). + +16. Related to 15 above: Perl does not treat the | in a conditional group as + creating alternatives. Such a group is treated in the same way as an + ordinary group without any | characters when processing (*THEN). PCRE has + been changed to match Perl's behaviour. + +17. If a user had set PCREGREP_COLO(U)R to something other than 1:31, the + RunGrepTest script failed. + +18. Change 22 for version 13 caused atomic groups to use more stack. This is + inevitable for groups that contain captures, but it can lead to a lot of + stack use in large patterns. The old behaviour has been restored for atomic + groups that do not contain any capturing parentheses. + +19. If the PCRE_NO_START_OPTIMIZE option was set for pcre_compile(), it did not + suppress the check for a minimum subject length at run time. (If it was + given to pcre_exec() or pcre_dfa_exec() it did work.) + +20. Fixed an ASCII-dependent infelicity in pcretest that would have made it + fail to work when decoding hex characters in data strings in EBCDIC + environments. + +21. It appears that in at least one Mac OS environment, the isxdigit() function + is implemented as a macro that evaluates to its argument more than once, + contravening the C 90 Standard (I haven't checked a later standard). There + was an instance in pcretest which caused it to go wrong when processing + \x{...} escapes in subject strings. The has been rewritten to avoid using + things like p++ in the argument of isxdigit(). + + +Version 8.13 16-Aug-2011 +------------------------ + +1. The Unicode data tables have been updated to Unicode 6.0.0. + +2. Two minor typos in pcre_internal.h have been fixed. + +3. Added #include to pcre_scanner_unittest.cc, pcrecpp.cc, and + pcrecpp_unittest.cc. They are needed for strcmp(), memset(), and strchr() + in some environments (e.g. Solaris 10/SPARC using Sun Studio 12U2). + +4. There were a number of related bugs in the code for matching backrefences + caselessly in UTF-8 mode when codes for the characters concerned were + different numbers of bytes. For example, U+023A and U+2C65 are an upper + and lower case pair, using 2 and 3 bytes, respectively. The main bugs were: + (a) A reference to 3 copies of a 2-byte code matched only 2 of a 3-byte + code. (b) A reference to 2 copies of a 3-byte code would not match 2 of a + 2-byte code at the end of the subject (it thought there wasn't enough data + left). + +5. Comprehensive information about what went wrong is now returned by + pcre_exec() and pcre_dfa_exec() when the UTF-8 string check fails, as long + as the output vector has at least 2 elements. The offset of the start of + the failing character and a reason code are placed in the vector. + +6. When the UTF-8 string check fails for pcre_compile(), the offset that is + now returned is for the first byte of the failing character, instead of the + last byte inspected. This is an incompatible change, but I hope it is small + enough not to be a problem. It makes the returned offset consistent with + pcre_exec() and pcre_dfa_exec(). + +7. pcretest now gives a text phrase as well as the error number when + pcre_exec() or pcre_dfa_exec() fails; if the error is a UTF-8 check + failure, the offset and reason code are output. + +8. When \R was used with a maximizing quantifier it failed to skip backwards + over a \r\n pair if the subsequent match failed. Instead, it just skipped + back over a single character (\n). This seems wrong (because it treated the + two characters as a single entity when going forwards), conflicts with the + documentation that \R is equivalent to (?>\r\n|\n|...etc), and makes the + behaviour of \R* different to (\R)*, which also seems wrong. The behaviour + has been changed. + +9. Some internal refactoring has changed the processing so that the handling + of the PCRE_CASELESS and PCRE_MULTILINE options is done entirely at compile + time (the PCRE_DOTALL option was changed this way some time ago: version + 7.7 change 16). This has made it possible to abolish the OP_OPT op code, + which was always a bit of a fudge. It also means that there is one less + argument for the match() function, which reduces its stack requirements + slightly. This change also fixes an incompatibility with Perl: the pattern + (?i:([^b]))(?1) should not match "ab", but previously PCRE gave a match. + +10. More internal refactoring has drastically reduced the number of recursive + calls to match() for possessively repeated groups such as (abc)++ when + using pcre_exec(). + +11. While implementing 10, a number of bugs in the handling of groups were + discovered and fixed: + + (?<=(a)+) was not diagnosed as invalid (non-fixed-length lookbehind). + (a|)*(?1) gave a compile-time internal error. + ((a|)+)+ did not notice that the outer group could match an empty string. + (^a|^)+ was not marked as anchored. + (.*a|.*)+ was not marked as matching at start or after a newline. + +12. Yet more internal refactoring has removed another argument from the match() + function. Special calls to this function are now indicated by setting a + value in a variable in the "match data" data block. + +13. Be more explicit in pcre_study() instead of relying on "default" for + opcodes that mean there is no starting character; this means that when new + ones are added and accidentally left out of pcre_study(), testing should + pick them up. + +14. The -s option of pcretest has been documented for ages as being an old + synonym of -m (show memory usage). I have changed it to mean "force study + for every regex", that is, assume /S for every regex. This is similar to -i + and -d etc. It's slightly incompatible, but I'm hoping nobody is still + using it. It makes it easier to run collections of tests with and without + study enabled, and thereby test pcre_study() more easily. All the standard + tests are now run with and without -s (but some patterns can be marked as + "never study" - see 20 below). + +15. When (*ACCEPT) was used in a subpattern that was called recursively, the + restoration of the capturing data to the outer values was not happening + correctly. + +16. If a recursively called subpattern ended with (*ACCEPT) and matched an + empty string, and PCRE_NOTEMPTY was set, pcre_exec() thought the whole + pattern had matched an empty string, and so incorrectly returned a no + match. + +17. There was optimizing code for the last branch of non-capturing parentheses, + and also for the obeyed branch of a conditional subexpression, which used + tail recursion to cut down on stack usage. Unfortunately, now that there is + the possibility of (*THEN) occurring in these branches, tail recursion is + no longer possible because the return has to be checked for (*THEN). These + two optimizations have therefore been removed. [But see 8.20/11 above.] + +18. If a pattern containing \R was studied, it was assumed that \R always + matched two bytes, thus causing the minimum subject length to be + incorrectly computed because \R can also match just one byte. + +19. If a pattern containing (*ACCEPT) was studied, the minimum subject length + was incorrectly computed. + +20. If /S is present twice on a test pattern in pcretest input, it now + *disables* studying, thereby overriding the use of -s on the command line + (see 14 above). This is necessary for one or two tests to keep the output + identical in both cases. + +21. When (*ACCEPT) was used in an assertion that matched an empty string and + PCRE_NOTEMPTY was set, PCRE applied the non-empty test to the assertion. + +22. When an atomic group that contained a capturing parenthesis was + successfully matched, but the branch in which it appeared failed, the + capturing was not being forgotten if a higher numbered group was later + captured. For example, /(?>(a))b|(a)c/ when matching "ac" set capturing + group 1 to "a", when in fact it should be unset. This applied to multi- + branched capturing and non-capturing groups, repeated or not, and also to + positive assertions (capturing in negative assertions does not happen + in PCRE) and also to nested atomic groups. + +23. Add the ++ qualifier feature to pcretest, to show the remainder of the + subject after a captured substring, to make it easier to tell which of a + number of identical substrings has been captured. + +24. The way atomic groups are processed by pcre_exec() has been changed so that + if they are repeated, backtracking one repetition now resets captured + values correctly. For example, if ((?>(a+)b)+aabab) is matched against + "aaaabaaabaabab" the value of captured group 2 is now correctly recorded as + "aaa". Previously, it would have been "a". As part of this code + refactoring, the way recursive calls are handled has also been changed. + +25. If an assertion condition captured any substrings, they were not passed + back unless some other capturing happened later. For example, if + (?(?=(a))a) was matched against "a", no capturing was returned. + +26. When studying a pattern that contained subroutine calls or assertions, + the code for finding the minimum length of a possible match was handling + direct recursions such as (xxx(?1)|yyy) but not mutual recursions (where + group 1 called group 2 while simultaneously a separate group 2 called group + 1). A stack overflow occurred in this case. I have fixed this by limiting + the recursion depth to 10. + +27. Updated RunTest.bat in the distribution to the version supplied by Tom + Fortmann. This supports explicit test numbers on the command line, and has + argument validation and error reporting. + +28. An instance of \X with an unlimited repeat could fail if at any point the + first character it looked at was a mark character. + +29. Some minor code refactoring concerning Unicode properties and scripts + should reduce the stack requirement of match() slightly. + +30. Added the '=' option to pcretest to check the setting of unused capturing + slots at the end of the pattern, which are documented as being -1, but are + not included in the return count. + +31. If \k was not followed by a braced, angle-bracketed, or quoted name, PCRE + compiled something random. Now it gives a compile-time error (as does + Perl). + +32. A *MARK encountered during the processing of a positive assertion is now + recorded and passed back (compatible with Perl). + +33. If --only-matching or --colour was set on a pcregrep call whose pattern + had alternative anchored branches, the search for a second match in a line + was done as if at the line start. Thus, for example, /^01|^02/ incorrectly + matched the line "0102" twice. The same bug affected patterns that started + with a backwards assertion. For example /\b01|\b02/ also matched "0102" + twice. + +34. Previously, PCRE did not allow quantification of assertions. However, Perl + does, and because of capturing effects, quantifying parenthesized + assertions may at times be useful. Quantifiers are now allowed for + parenthesized assertions. + +35. A minor code tidy in pcre_compile() when checking options for \R usage. + +36. \g was being checked for fancy things in a character class, when it should + just be a literal "g". + +37. PCRE was rejecting [:a[:digit:]] whereas Perl was not. It seems that the + appearance of a nested POSIX class supersedes an apparent external class. + For example, [:a[:digit:]b:] matches "a", "b", ":", or a digit. Also, + unescaped square brackets may also appear as part of class names. For + example, [:a[:abc]b:] gives unknown class "[:abc]b:]". PCRE now behaves + more like Perl. (But see 8.20/1 above.) + +38. PCRE was giving an error for \N with a braced quantifier such as {1,} (this + was because it thought it was \N{name}, which is not supported). + +39. Add minix to OS list not supporting the -S option in pcretest. + +40. PCRE tries to detect cases of infinite recursion at compile time, but it + cannot analyze patterns in sufficient detail to catch mutual recursions + such as ((?1))((?2)). There is now a runtime test that gives an error if a + subgroup is called recursively as a subpattern for a second time at the + same position in the subject string. In previous releases this might have + been caught by the recursion limit, or it might have run out of stack. + +41. A pattern such as /(?(R)a+|(?R)b)/ is quite safe, as the recursion can + happen only once. PCRE was, however incorrectly giving a compile time error + "recursive call could loop indefinitely" because it cannot analyze the + pattern in sufficient detail. The compile time test no longer happens when + PCRE is compiling a conditional subpattern, but actual runaway loops are + now caught at runtime (see 40 above). + +42. It seems that Perl allows any characters other than a closing parenthesis + to be part of the NAME in (*MARK:NAME) and other backtracking verbs. PCRE + has been changed to be the same. + +43. Updated configure.ac to put in more quoting round AC_LANG_PROGRAM etc. so + as not to get warnings when autogen.sh is called. Also changed + AC_PROG_LIBTOOL (deprecated) to LT_INIT (the current macro). + +44. To help people who use pcregrep to scan files containing exceedingly long + lines, the following changes have been made: + + (a) The default value of the buffer size parameter has been increased from + 8K to 20K. (The actual buffer used is three times this size.) + + (b) The default can be changed by ./configure --with-pcregrep-bufsize when + PCRE is built. + + (c) A --buffer-size=n option has been added to pcregrep, to allow the size + to be set at run time. + + (d) Numerical values in pcregrep options can be followed by K or M, for + example --buffer-size=50K. + + (e) If a line being scanned overflows pcregrep's buffer, an error is now + given and the return code is set to 2. + +45. Add a pointer to the latest mark to the callout data block. + +46. The pattern /.(*F)/, when applied to "abc" with PCRE_PARTIAL_HARD, gave a + partial match of an empty string instead of no match. This was specific to + the use of ".". + +47. The pattern /f.*/8s, when applied to "for" with PCRE_PARTIAL_HARD, gave a + complete match instead of a partial match. This bug was dependent on both + the PCRE_UTF8 and PCRE_DOTALL options being set. + +48. For a pattern such as /\babc|\bdef/ pcre_study() was failing to set up the + starting byte set, because \b was not being ignored. + + Version 8.12 15-Jan-2011 ------------------------ diff --git a/ext/pcre/pcrelib/HACKING b/ext/pcre/pcrelib/HACKING index ee0913214c2..87b88191ad3 100644 --- a/ext/pcre/pcrelib/HACKING +++ b/ext/pcre/pcrelib/HACKING @@ -2,7 +2,8 @@ Technical Notes about PCRE -------------------------- These are very rough technical notes that record potentially useful information -about PCRE internals. +about PCRE internals. For information about testing PCRE, see the pcretest +documentation and the comment at the head of the RunTest file. Historical note 1 @@ -48,6 +49,18 @@ complexity in Perl regular expressions, I couldn't do this. In any case, a first pass through the pattern is helpful for other reasons. +Support for 16-bit data strings +------------------------------- + +From release 8.30, PCRE supports 16-bit as well as 8-bit data strings, by being +compilable in either 8-bit or 16-bit modes, or both. Thus, two different +libraries can be created. 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 and a short in 16-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 -------------------------------------------- @@ -68,7 +81,7 @@ things I did for 6.8 was to fix Yet Another Bug in the memory computation. Then I had a flash of inspiration as to how I could run the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory, and without too -many tests of the mode that might slow it down. So I re-factored the compiling +many tests of the mode that might slow it down. So I refactored the compiling functions to work this way. This got rid of about 600 lines of source. It should make future maintenance and development easier. As this was such a major change, I never released 6.8, instead upping the number to 7.0 (other quite @@ -88,7 +101,10 @@ The "traditional", and original, matching function is called pcre_exec(), and it implements an NFA algorithm, similar to the original Henry Spencer algorithm and the way that Perl works. This is not surprising, since it is intended to be as compatible with Perl as possible. This is the function most users of PCRE -will use most of the time. +will use most of the time. From release 8.20, if PCRE is compiled with +just-in-time (JIT) support, and studying a compiled pattern with JIT is +successful, the JIT code is run instead of the normal pcre_exec() code, but the +result is the same. Supplementary matching function @@ -108,28 +124,38 @@ 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. +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. + + Format of compiled patterns --------------------------- -The compiled form of a pattern is a vector of bytes, containing items of -variable length. The first byte in an item is an opcode, and the length of the -item is either implicit in the opcode or contained in the data bytes that -follow it. +The compiled form of a pattern is a vector of units (bytes in 8-bit mode, or +shorts in 16-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 below LINK_SIZE data values are specified for offsets within the -compiled pattern. The default value for LINK_SIZE is 2, but PCRE can be -compiled to use 3-byte or 4-byte values for these offsets (impairing the -performance). This 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. - -A list of the opcodes follows: +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 +default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or +4-byte values for these offsets, although this impairs the performance. (3-byte +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). Opcodes with no following data ------------------------------ -These items are all just one byte long +These items are all just one unit long OP_END end of pattern OP_ANY match any one character other than newline @@ -138,7 +164,8 @@ These items are all just one byte long OP_SOD match start of data: \A OP_SOM, start of match (subject + offset): \G OP_SET_SOM, set start of match (\K) - OP_CIRC ^ (start of data, or after \n in multiline) + OP_CIRC ^ (start of data) + OP_CIRCM ^ multiline mode (start of data or after newline) OP_NOT_WORD_BOUNDARY \W OP_WORD_BOUNDARY \w OP_NOT_DIGIT \D @@ -153,7 +180,8 @@ These items are all just one byte long OP_WORDCHAR \w OP_EODN match end of data or \n at end: \Z OP_EOD match end of data: \z - OP_DOLL $ (end of data, or before \n in multiline) + 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_ANYNL match any Unicode newline sequence @@ -164,49 +192,57 @@ These items are all just one byte long OP_SKIP ) indicating which parentheses must be closed. -Backtracking control verbs with data ------------------------------------- - -OP_THEN is followed by a LINK_SIZE offset, which is the distance back to the -start of the current branch. +Backtracking control verbs with (optional) data +----------------------------------------------- -OP_MARK is followed by the mark name, preceded by a one-byte 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. For the first -two, the name follows immediately; for OP_THEN_ARG, it follows the LINK_SIZE -offset value. +(*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. +Matching literal characters +--------------------------- + +The OP_CHAR opcode is followed by a single character that is to be matched +casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, +the character may be more than one unit long. + + Repeating single characters --------------------------- -The common repeats (*, +, ?) when applied to a single character use the -following opcodes: +The common repeats (*, +, ?), when applied to a single character, use the +following opcodes, which come in caseful and caseless versions: - OP_STAR - OP_MINSTAR - OP_POSSTAR - OP_PLUS - OP_MINPLUS - OP_POSPLUS - OP_QUERY - OP_MINQUERY - OP_POSQUERY + Caseful Caseless + OP_STAR OP_STARI + OP_MINSTAR OP_MINSTARI + OP_POSSTAR OP_POSSTARI + OP_PLUS OP_PLUSI + OP_MINPLUS OP_MINPLUSI + OP_POSPLUS OP_POSPLUSI + OP_QUERY OP_QUERYI + OP_MINQUERY OP_MINQUERYI + OP_POSQUERY OP_POSQUERYI -In ASCII mode, these are two-byte items; in UTF-8 mode, the length is variable. -Those with "MIN" in their name are the minimizing versions. Those with "POS" in -their names are possessive versions. Each is followed by the character that is -to be repeated. Other repeats make use of +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. +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: - OP_UPTO - OP_MINUPTO - OP_POSUPTO - OP_EXACT + Caseful Caseless + OP_UPTO OP_UPTOI + OP_MINUPTO OP_MINUPTOI + OP_POSUPTO OP_POSUPTOI + OP_EXACT OP_EXACTI -which are followed by a two-byte count (most significant first) and 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 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). Repeating character types @@ -214,7 +250,7 @@ Repeating character types Repeats of things like \d are done exactly as for single characters, except that instead of a character, the opcode for the type is stored in the data -byte. The opcodes are: +unit. The opcodes are: OP_TYPESTAR OP_TYPEMINSTAR @@ -236,65 +272,58 @@ 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 bytes that encode the desired property as a type and a +Each is followed by two units that encode the desired property as a type and a value. -Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by -three bytes: OP_PROP or OP_NOTPROP and then the desired property type and +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 value. -Matching literal characters ---------------------------- - -The OP_CHAR opcode is followed by a single character that is to be matched -casefully. For caseless matching, OP_CHARNC is used. In UTF-8 mode, the -character may be more than one byte long. (Earlier versions of PCRE used -multi-character strings, but this was changed to allow some new features to be -added.) - - Character classes ----------------- -If there is only one character, OP_CHAR or OP_CHARNC is used for a positive -class, and OP_NOT for a negative one (that is, for something like [^a]). -However, in UTF-8 mode, the use of OP_NOT applies only to characters with -values < 128, because OP_NOT is confined to single bytes. +If there is only one character in the 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 repeating opcodes (OP_NOTSTAR etc.) are used for a repeated, -negated, single-character class. The normal ones (OP_STAR etc.) are used for a -repeated positive single-character class. +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. -When there's more than one character in a class and all the characters 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 bit map containing a 1 -bit for every character that is acceptable. The bits are counted from the least -significant end of each byte. +When there is more than one character in a class and all the characters 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. -The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode, -subject characters with values greater than 256 can be handled correctly. For -OP_CLASS they don't match, whereas for OP_NCLASS they do. +The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16 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 > 255, OP_XCLASS is used. It -optionally uses a bit map (if any characters lie within it), followed by a list -of pairs and single characters. There is a flag character than indicates -whether it's a positive or a negative class. +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. Back references --------------- -OP_REF is followed by two bytes containing the reference number. +OP_REF (caseful) or OP_REFI (caseless) is followed by two bytes (one short) +containing the reference number. Repeating character classes and back references ----------------------------------------------- Single-character classes are handled specially (see above). This section -applies to OP_CLASS and OP_REF. 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 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 OP_CRSTAR OP_CRMINSTAR @@ -305,10 +334,10 @@ one of OP_CRRANGE OP_CRMINRANGE -All but the last two are just single-byte items. The others are followed by -four bytes 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 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. Brackets and alternation @@ -318,7 +347,8 @@ 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 -myself, can be round, square, curly, or pointy. Hence this usage.] +myself, can be round, square, curly, or pointy. Hence this usage rather than +"parentheses".] Non-capturing brackets use the opcode OP_BRA. Originally PCRE was limited to 99 capturing brackets and it used a different opcode for each one. From release @@ -330,16 +360,17 @@ 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 item. +number immediately follows the offset, always as a 2-byte (one short) item. -OP_KET is used for subpatterns that do not repeat indefinitely, while +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. All three are followed by LINK_SIZE bytes giving (as a -positive number) the offset back to the matching bracket opcode. +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-byte opcodes that tell the matcher that skipping the following +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, @@ -362,6 +393,15 @@ 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 +------------------- + +When a repeated group (capturing or non-capturing) is marked as possessive by +the "+" notation, e.g. (abc)++, different opcodes are used. Their names all +have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCPBRPOS instead +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 ---------- @@ -369,11 +409,11 @@ Assertions 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 count of the number of characters to move -back the pointer in the subject string. When operating in UTF-8 mode, the count -is a character count rather than a byte count. A separate count is present in -each alternative of a lookbehind assertion, allowing them to have different -fixed lengths. +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. A separate count is present in each alternative of a lookbehind +assertion, allowing them to have different fixed lengths. Once-only (atomic) subpatterns @@ -390,14 +430,15 @@ 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 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 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). 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 byte +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. @@ -416,25 +457,12 @@ are not strictly a recursion. Callout ------- -OP_CALLOUT is followed by one byte of data that holds a callout number in the +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 value giving the offset in the pattern to the -start of the following item, and another two-byte item giving the length of the -next item. +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. -Changing options ----------------- - -If any of the /i, /m, or /s options are changed within a pattern, an OP_OPT -opcode is compiled, followed by one byte containing the new settings of these -flags. If there are several alternatives, there is an occurrence of OP_OPT at -the start of all those following the first options change, to set appropriate -options for the start of the alternative. Immediately after the end of the -group there is another such item to reset the flags to their previous values. A -change of flag right at the very start of the pattern can be handled entirely -at compile time, and so does not cause anything to be put into the compiled -data. - Philip Hazel -October 2010 +February 2012 diff --git a/ext/pcre/pcrelib/LICENCE b/ext/pcre/pcrelib/LICENCE index 0dd22571adc..5ce31a828d3 100644 --- a/ext/pcre/pcrelib/LICENCE +++ b/ext/pcre/pcrelib/LICENCE @@ -9,7 +9,9 @@ specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. The basic library functions are written in C and are freestanding. Also -included in the distribution is a set of C++ wrapper functions. +included in the distribution is a set of C++ wrapper functions, and a +just-in-time compiler that can be used to optimize pattern matching. These +are both optional features that can be omitted when the library is built. THE BASIC LIBRARY FUNCTIONS @@ -22,7 +24,29 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2010 University of Cambridge +Copyright (c) 1997-2012 University of Cambridge +All rights reserved. + + +PCRE JUST-IN-TIME COMPILATION SUPPORT +------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2012 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2012 Zoltan Herczeg All rights reserved. @@ -31,7 +55,7 @@ THE C++ WRAPPER FUNCTIONS Contributed by: Google Inc. -Copyright (c) 2007-2010, Google Inc. +Copyright (c) 2007-2012, Google Inc. All rights reserved. diff --git a/ext/pcre/pcrelib/NEWS b/ext/pcre/pcrelib/NEWS index 5f2b29bd22c..3c932a46418 100644 --- a/ext/pcre/pcrelib/NEWS +++ b/ext/pcre/pcrelib/NEWS @@ -1,6 +1,82 @@ News about PCRE releases ------------------------ +Release 8.31 06-July-2012 +------------------------- + +This is mainly a bug-fixing release, with a small number of developments: + +. The JIT compiler now supports partial matching and the (*MARK) and + (*COMMIT) verbs. + +. PCRE_INFO_MAXLOOKBEHIND can be used to find the longest lookbehing in a + pattern. + +. There should be a performance improvement when using the heap instead of the + stack for recursion. + +. pcregrep can now be linked with libedit as an alternative to libreadline. + +. pcregrep now has a --file-list option where the list of files to scan is + given as a file. + +. pcregrep now recognizes binary files and there are related options. + +. The Unicode tables have been updated to 6.1.0. + +As always, the full list of changes is in the ChangeLog file. + + +Release 8.30 04-February-2012 +----------------------------- + +Release 8.30 introduces a major new feature: support for 16-bit character +strings, compiled as a separate library. There are a few changes to the +8-bit library, in addition to some bug fixes. + +. The pcre_info() function, which has been obsolete for over 10 years, has + been removed. + +. When a compiled pattern was saved to a file and later reloaded on a host + with different endianness, PCRE used automatically to swap the bytes in some + of the data fields. With the advent of the 16-bit library, where more of this + swapping is needed, it is no longer done automatically. Instead, the bad + endianness is detected and a specific error is given. The user can then call + a new function called pcre_pattern_to_host_byte_order() (or an equivalent + 16-bit function) to do the swap. + +. In UTF-8 mode, the values 0xd800 to 0xdfff are not legal Unicode + code points and are now faulted. (They are the so-called "surrogates" + that are reserved for coding high values in UTF-16.) + + +Release 8.21 12-Dec-2011 +------------------------ + +This is almost entirely a bug-fix release. The only new feature is the ability +to obtain the size of the memory used by the JIT compiler. + + +Release 8.20 21-Oct-2011 +------------------------ + +The main change in this release is the inclusion of Zoltan Herczeg's +just-in-time compiler support, which can be accessed by building PCRE with +--enable-jit. Large performance benefits can be had in many situations. 8.20 +also fixes an unfortunate bug that was introduced in 8.13 as well as tidying up +a number of infelicities and differences from Perl. + + +Release 8.13 16-Aug-2011 +------------------------ + +This is mainly a bug-fix release. There has been a lot of internal refactoring. +The Unicode tables have been updated. The only new feature in the library is +the passing of *MARK information to callouts. Some additions have been made to +pcretest to make testing easier and more comprehensive. There is a new option +for pcregrep to adjust its internal buffer size. + + Release 8.12 15-Jan-2011 ------------------------ diff --git a/ext/pcre/pcrelib/NON-UNIX-USE b/ext/pcre/pcrelib/NON-UNIX-USE index 8619b584644..a25546b6ff5 100644 --- a/ext/pcre/pcrelib/NON-UNIX-USE +++ b/ext/pcre/pcrelib/NON-UNIX-USE @@ -1,501 +1,7 @@ Compiling PCRE on non-Unix systems ---------------------------------- -This document contains the following sections: +This has been renamed to better reflect its contents. Please see the file +NON-AUTOTOOLS-BUILD for details of how to build PCRE without using autotools. - General - Generic instructions for the PCRE C library - The C++ wrapper functions - Building for virtual Pascal - Stack size in Windows environments - Linking programs in Windows environments - Comments about Win32 builds - Building PCRE on Windows with CMake - Use of relative paths with CMake on Windows - Testing with RunTest.bat - Building under Windows with BCC5.5 - Building PCRE on OpenVMS - Building PCRE on Stratus OpenVOS - - -GENERAL - -I (Philip Hazel) have no experience of Windows or VMS sytems and how their -libraries work. The items in the PCRE distribution and Makefile that relate to -anything other than Unix-like systems are untested by me. - -There are some other comments and files (including some documentation in CHM -format) in the Contrib directory on the FTP site: - - ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib - -If you want to compile PCRE for a non-Unix system (especially for a system that -does not support "configure" and "make" files), note that the basic PCRE -library consists entirely of code written in Standard C, and so should compile -successfully on any system that has a Standard C compiler and library. The C++ -wrapper functions are a separate issue (see below). - -The PCRE distribution includes a "configure" file for use by the Configure/Make -build system, as found in many Unix-like environments. There is also support -support for CMake, which some users prefer, especially in Windows environments. -There are some instructions for CMake under Windows in the section entitled -"Building PCRE with CMake" below. CMake can also be used to build PCRE in -Unix-like systems. - - -GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY - -The following are generic comments about building the PCRE C library "by hand". - - (1) Copy or rename the file config.h.generic as config.h, and edit the macro - settings that it contains to whatever is appropriate for your environment. - In particular, if you want to force a specific value for newline, you can - define the NEWLINE macro. When you compile any of the PCRE modules, you - must specify -DHAVE_CONFIG_H to your compiler so that config.h is included - in the sources. - - An alternative approach is not to edit config.h, but to use -D on the - compiler command line to make any changes that you need to the - configuration options. In this case -DHAVE_CONFIG_H must not be set. - - NOTE: There have been occasions when the way in which certain parameters - in config.h are used has changed between releases. (In the configure/make - world, this is handled automatically.) When upgrading to a new release, - you are strongly advised to review config.h.generic before re-using what - you had previously. - - (2) Copy or rename the file pcre.h.generic as pcre.h. - - (3) EITHER: - Copy or rename file pcre_chartables.c.dist as pcre_chartables.c. - - OR: - Compile dftables.c as a stand-alone program (using -DHAVE_CONFIG_H if - you have set up config.h), and then run it with the single argument - "pcre_chartables.c". This generates a set of standard character tables - and writes them to that file. The tables are generated using the default - C locale for your system. If you want to use a locale that is specified - by LC_xxx environment variables, add the -L option to the dftables - command. You must use this method if you are building on a system that - uses EBCDIC code. - - The tables in pcre_chartables.c are defaults. The caller of PCRE can - specify alternative tables at run time. - - (4) Ensure that you have the following header files: - - pcre_internal.h - ucp.h - - (5) Also ensure that you have the following file, which is #included as source - when building a debugging version of PCRE, and is also used by pcretest. - - pcre_printint.src - - (6) Compile the following source files, setting -DHAVE_CONFIG_H as a compiler - option if you have set up config.h with your configuration, or else use - other -D settings to change the configuration as required. - - pcre_chartables.c - pcre_compile.c - pcre_config.c - pcre_dfa_exec.c - pcre_exec.c - pcre_fullinfo.c - pcre_get.c - pcre_globals.c - pcre_info.c - pcre_maketables.c - pcre_newline.c - pcre_ord2utf8.c - pcre_refcount.c - pcre_study.c - pcre_tables.c - pcre_try_flipped.c - pcre_ucd.c - pcre_valid_utf8.c - pcre_version.c - pcre_xclass.c - - Make sure that you include -I. in the compiler command (or equivalent for - an unusual compiler) so that all included PCRE header files are first - sought in the current directory. Otherwise you run the risk of picking up - a previously-installed file from somewhere else. - - (7) Now link all the compiled code into an object library in whichever form - your system keeps such libraries. This is the basic PCRE C library. If - your system has static and shared libraries, you may have to do this once - for each type. - - (8) Similarly, if you want to build the POSIX wrapper functions, ensure that - you have the pcreposix.h file and then compile pcreposix.c (remembering - -DHAVE_CONFIG_H if necessary). Link the result (on its own) as the - pcreposix library. - - (9) Compile the test program pcretest.c (again, don't forget -DHAVE_CONFIG_H). - This needs the functions in the PCRE library when linking. It also needs - the pcreposix wrapper functions unless you compile it with -DNOPOSIX. The - pcretest.c program also needs the pcre_printint.src source file, which it - #includes. - -(10) Run pcretest on the testinput files in the testdata directory, and check - that the output matches the corresponding testoutput files. Note that the - supplied files are in Unix format, with just LF characters as line - terminators. You may need to edit them to change this if your system uses - a different convention. If you are using Windows, you probably should use - the wintestinput3 file instead of testinput3 (and the corresponding output - file). This is a locale test; wintestinput3 sets the locale to "french" - rather than "fr_FR", and there some minor output differences. - -(11) If you want to use the pcregrep command, compile and link pcregrep.c; it - uses only the basic PCRE library (it does not need the pcreposix library). - - -THE C++ WRAPPER FUNCTIONS - -The PCRE distribution also contains some C++ wrapper functions and tests, -contributed by Google Inc. On a system that can use "configure" and "make", -the functions are automatically built into a library called pcrecpp. It should -be straightforward to compile the .cc files manually on other systems. The -files called xxx_unittest.cc are test programs for each of the corresponding -xxx.cc files. - - -BUILDING FOR VIRTUAL PASCAL - -A script for building PCRE using Borland's C++ compiler for use with VPASCAL -was contributed by Alexander Tokarev. Stefan Weber updated the script and added -additional files. The following files in the distribution are for building PCRE -for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas. - - -STACK SIZE IN WINDOWS ENVIRONMENTS - -The default processor stack size of 1Mb in some Windows environments is too -small for matching patterns that need much recursion. In particular, test 2 may -fail because of this. Normally, running out of stack causes a crash, but there -have been cases where the test program has just died silently. See your linker -documentation for how to increase stack size if you experience problems. The -Linux default of 8Mb is a reasonable choice for the stack, though even that can -be too small for some pattern/subject combinations. - -PCRE has a compile configuration option to disable the use of stack for -recursion so that heap is used instead. However, pattern matching is -significantly slower when this is done. There is more about stack usage in the -"pcrestack" documentation. - - -LINKING PROGRAMS IN WINDOWS ENVIRONMENTS - -If you want to statically link a program against a PCRE library in the form of -a non-dll .a file, you must define PCRE_STATIC before including pcre.h or -pcrecpp.h, otherwise the pcre_malloc() and pcre_free() exported functions will -be declared __declspec(dllimport), with unwanted results. - - -CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS - -It is possible to compile programs to use different calling conventions using -MSVC. Search the web for "calling conventions" for more information. To make it -easier to change the calling convention for the exported functions in the -PCRE library, the macro PCRE_CALL_CONVENTION is present in all the external -definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is -not set, it defaults to empty; the default calling convention is then used -(which is what is wanted most of the time). - - -COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE WITH CMAKE" below) - -There are two ways of building PCRE using the "configure, make, make install" -paradigm on Windows systems: using MinGW or using Cygwin. These are not at all -the same thing; they are completely different from each other. There is also -support for building using CMake, which some users find a more straightforward -way of building PCRE under Windows. However, the tests are not run -automatically when CMake is used. - -The MinGW home page (http://www.mingw.org/) says this: - - MinGW: A collection of freely available and freely distributable Windows - specific header files and import libraries combined with GNU toolsets that - allow one to produce native Windows programs that do not rely on any - 3rd-party C runtime DLLs. - -The Cygwin home page (http://www.cygwin.com/) says this: - - Cygwin is a Linux-like environment for Windows. It consists of two parts: - - . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing - substantial Linux API functionality - - . A collection of tools which provide Linux look and feel. - - The Cygwin DLL currently works with all recent, commercially released x86 32 - bit and 64 bit versions of Windows, with the exception of Windows CE. - -On both MinGW and Cygwin, PCRE should build correctly using: - - ./configure && make && make install - -This should create two libraries called libpcre and libpcreposix, and, if you -have enabled building the C++ wrapper, a third one called libpcrecpp. These are -independent libraries: when you like with libpcreposix or libpcrecpp you must -also link with libpcre, which contains the basic functions. (Some earlier -releases of PCRE included the basic libpcre functions in libpcreposix. This no -longer happens.) - -A user submitted a special-purpose patch that makes it easy to create -"pcre.dll" under mingw32 using the "msys" environment. It provides "pcre.dll" -as a special target. If you use this target, no other files are built, and in -particular, the pcretest and pcregrep programs are not built. An example of how -this might be used is: - - ./configure --enable-utf --disable-cpp CFLAGS="-03 -s"; make pcre.dll - -Using Cygwin's compiler generates libraries and executables that depend on -cygwin1.dll. If a library that is generated this way is distributed, -cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL -licence, this forces not only PCRE to be under the GPL, but also the entire -application. A distributor who wants to keep their own code proprietary must -purchase an appropriate Cygwin licence. - -MinGW has no such restrictions. The MinGW compiler generates a library or -executable that can run standalone on Windows without any third party dll or -licensing issues. - -But there is more complication: - -If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is -to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a -front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's -gcc and MinGW's gcc). So, a user can: - -. Build native binaries by using MinGW or by getting Cygwin and using - -mno-cygwin. - -. Build binaries that depend on cygwin1.dll by using Cygwin with the normal - compiler flags. - -The test files that are supplied with PCRE are in Unix format, with LF -characters as line terminators. It may be necessary to change the line -terminators in order to get some of the tests to work. - - -BUILDING PCRE ON WINDOWS WITH CMAKE - -CMake is an alternative configuration facility that can be used instead of the -traditional Unix "configure". CMake creates project files (make files, solution -files, etc.) tailored to numerous development environments, including Visual -Studio, Borland, Msys, MinGW, NMake, and Unix. The following instructions -were contributed by a PCRE user. - -1. Install the latest CMake version available from http://www.cmake.org/, and - ensure that cmake\bin is on your path. - -2. Unzip (retaining folder structure) the PCRE source tree into a source - directory such as C:\pcre. - -3. Create a new, empty build directory, for example C:\pcre\build\ - -4. Run cmake-gui from the Shell envirornment of your build tool, for example, - Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. - -5. Enter C:\pcre\pcre-xx and C:\pcre\build for the source and build - directories, respectively. - -6. Hit the "Configure" button. - -7. Select the particular IDE / build tool that you are using (Visual - Studio, MSYS makefiles, MinGW makefiles, etc.) - -8. The GUI will then list several configuration options. This is where - you can enable UTF-8 support or other PCRE optional features. - -9. Hit "Configure" again. The adjacent "Generate" button should now be - active. - -10. Hit "Generate". - -11. The build directory should now contain a usable build system, be it a - solution file for Visual Studio, makefiles for MinGW, etc. Exit from - cmake-gui and use the generated build system with your compiler or IDE. - - -USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS - -A PCRE user comments as follows: - -I thought that others may want to know the current state of -CMAKE_USE_RELATIVE_PATHS support on Windows. - -Here it is: --- AdditionalIncludeDirectories is only partially modified (only the -first path - see below) --- Only some of the contained file paths are modified - shown below for -pcre.vcproj --- It properly modifies - -I am sure CMake people can fix that if they want to. Until then one will -need to replace existing absolute paths in project files with relative -paths manually (e.g. from VS) - relative to project file location. I did -just that before being told to try CMAKE_USE_RELATIVE_PATHS. Not a big -deal. - -AdditionalIncludeDirectories="E:\builds\pcre\build;E:\builds\pcre\pcre-7.5;" -AdditionalIncludeDirectories=".;E:\builds\pcre\pcre-7.5;" - -RelativePath="pcre.h"> -RelativePath="pcre_chartables.c"> -RelativePath="pcre_chartables.c.rule"> - - -TESTING WITH RUNTEST.BAT - -1. Copy RunTest.bat into the directory where pcretest.exe has been created. - -2. Edit RunTest.bat and insert a line that indentifies the relative location of - the pcre source, e.g.: - - set srcdir=..\pcre-7.4-RC3 - -3. Run RunTest.bat from a command shell environment. Test outputs will - automatically be compared to expected results, and discrepancies will - identified in the console output. - -4. To test pcrecpp, run pcrecpp_unittest.exe, pcre_stringpiece_unittest.exe and - pcre_scanner_unittest.exe. - - -BUILDING UNDER WINDOWS WITH BCC5.5 - -Michael Roy sent these comments about building PCRE under Windows with BCC5.5: - - Some of the core BCC libraries have a version of PCRE from 1998 built in, - which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a - version mismatch. I'm including an easy workaround below, if you'd like to - include it in the non-unix instructions: - - When linking a project with BCC5.5, pcre.lib must be included before any of - the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command - line. - - -BUILDING UNDER WINDOWS CE WITH VISUAL STUDIO 200x - -Vincent Richomme sent a zip archive of files to help with this process. They -can be found in the file "pcre-vsbuild.zip" in the Contrib directory of the FTP -site. - - -BUILDING PCRE ON OPENVMS - -Dan Mooney sent the following comments about building PCRE on OpenVMS. They -relate to an older version of PCRE that used fewer source files, so the exact -commands will need changing. See the current list of source files above. - -"It was quite easy to compile and link the library. I don't have a formal -make file but the attached file [reproduced below] contains the OpenVMS DCL -commands I used to build the library. I had to add #define -POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. - -The library was built on: -O/S: HP OpenVMS v7.3-1 -Compiler: Compaq C v6.5-001-48BCD -Linker: vA13-01 - -The test results did not match 100% due to the issues you mention in your -documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I -modified some of the character tables temporarily and was able to get the -results to match. Tests using the fr locale did not match since I don't have -that locale loaded. The study size was always reported to be 3 less than the -value in the standard test output files." - -========================= -$! This DCL procedure builds PCRE on OpenVMS -$! -$! I followed the instructions in the non-unix-use file in the distribution. -$! -$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES -$ COMPILE DFTABLES.C -$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ -$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C -$ COMPILE MAKETABLES.C -$ COMPILE GET.C -$ COMPILE STUDY.C -$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol -$! did not seem to be defined anywhere. -$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. -$ COMPILE PCRE.C -$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ -$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol -$! did not seem to be defined anywhere. -$ COMPILE PCREPOSIX.C -$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ -$ COMPILE PCRETEST.C -$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB -$! C programs that want access to command line arguments must be -$! defined as a symbol -$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" -$! Arguments must be enclosed in quotes. -$ PCRETEST "-C" -$! Test results: -$! -$! The test results did not match 100%. The functions isprint(), iscntrl(), -$! isgraph() and ispunct() on OpenVMS must not produce the same results -$! as the system that built the test output files provided with the -$! distribution. -$! -$! The study size did not match and was always 3 less on OpenVMS. -$! -$! Locale could not be set to fr -$! -========================= - - -BUILDING PCRE ON STRATUS OPENVOS - -These notes on the port of PCRE to VOS (lightly edited) were supplied by -Ashutosh Warikoo, whose email address has the local part awarikoo and the -domain nse.co.in. The port was for version 7.9 in August 2009. - -1. Building PCRE - -I built pcre on OpenVOS Release 17.0.1at using GNU Tools 3.4a without any -problems. I used the following packages to build PCRE: - - ftp://ftp.stratus.com/pub/vos/posix/ga/posix.save.evf.gz - -Please read and follow the instructions that come with these packages. To start -the build of pcre, from the root of the package type: - - ./build.sh - -2. Installing PCRE - -Once you have successfully built PCRE, login to the SysAdmin group, switch to -the root user, and type - - [ !create_dir (master_disk)>usr --if needed ] - [ !create_dir (master_disk)>usr>local --if needed ] - !gmake install - -This installs PCRE and its man pages into /usr/local. You can add -(master_disk)>usr>local>bin to your command search paths, or if you are in -BASH, add /usr/local/bin to the PATH environment variable. - -4. Restrictions - -This port requires readline library optionally. However during the build I -faced some yet unexplored errors while linking with readline. As it was an -optional component I chose to disable it. - -5. Known Problems - -I ran a the test suite, but you will have to be your own judge of whether this -command, and this port, suits your purposes. If you find any problems that -appear to be related to the port itself, please let me know. Please see the -build.log file in the root of the package also. - - -========================= -Last Updated: 26 May 2010 -**** +#### diff --git a/ext/pcre/pcrelib/README b/ext/pcre/pcrelib/README index 2f3e9269469..8b67f100196 100644 --- a/ext/pcre/pcrelib/README +++ b/ext/pcre/pcrelib/README @@ -18,11 +18,12 @@ The contents of this README file are: The PCRE APIs Documentation for PCRE Contributions by users of PCRE - Building PCRE on non-Unix systems - Building PCRE on Unix-like systems - Retrieving configuration information on Unix-like systems - Shared libraries on Unix-like systems - Cross-compiling on Unix-like systems + Building PCRE on non-Unix-like systems + Building PCRE without using autotools + Building PCRE using autotools + Retrieving configuration information + Shared libraries + Cross-compiling using autotools Using HP's ANSI C++ compiler (aCC) Using PCRE from MySQL Making new tarballs @@ -34,16 +35,19 @@ The contents of this README file are: The PCRE APIs ------------- -PCRE is written in C, and it has its own API. The distribution also includes a -set of C++ wrapper functions (see the pcrecpp man page for details), courtesy -of Google Inc. +PCRE is written in C, and it has its own API. There are two sets of functions, +one for the 8-bit library, which processes strings of bytes, and one for the +16-bit library, which processes strings of 16-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++. -In addition, there is a set of C wrapper functions that are based on the POSIX -regular expression API (see the pcreposix man page). These end up in the -library called libpcreposix. Note that this just provides a POSIX calling -interface to PCRE; the regular expressions themselves still follow Perl syntax -and semantics. The POSIX API is restricted, and does not give full access to -all of PCRE's facilities. +In addition, there is a set of C wrapper functions (again, just for the 8-bit +library) that are based on the POSIX regular expression API (see the pcreposix +man page). These end up in the library called libpcreposix. Note that this just +provides a POSIX calling interface to PCRE; the regular expressions themselves +still follow Perl syntax and semantics. The POSIX API is restricted, and does +not give full access to all of PCRE's facilities. The header file for the POSIX-style functions is called pcreposix.h. The official POSIX name is regex.h, but I did not want to risk possible problems @@ -106,36 +110,45 @@ Windows (I myself do not use Windows). Nowadays there is more Windows support in the standard distribution, so these contibutions have been archived. -Building PCRE on non-Unix systems ---------------------------------- +Building PCRE on non-Unix-like systems +-------------------------------------- -For a non-Unix system, please read the comments in the file NON-UNIX-USE, -though if your system supports the use of "configure" and "make" you may be -able to build PCRE in the same way as for Unix-like systems. PCRE can also be -configured in many platform environments using the GUI facility provided by -CMake's cmake-gui command. This creates Makefiles, solution files, etc. +For a non-Unix-like system, please read the comments in the file +NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and +"make" you may be able to build PCRE using autotools in the same way as for +many Unix-like systems. + +PCRE can also be configured using the GUI facility provided by CMake's +cmake-gui command. This creates Makefiles, solution files, etc. The file +NON-AUTOTOOLS-BUILD has information about CMake. PCRE has been compiled on many different operating systems. It should be straightforward to build PCRE on any system that has a Standard C compiler and library, because it uses only Standard C functions. -Building PCRE on Unix-like systems ----------------------------------- +Building PCRE without using autotools +------------------------------------- + +The use of autotools (in particular, libtool) is problematic in some +environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD +file for ways of building PCRE without using autotools. + + +Building PCRE using autotools +----------------------------- If you are using HP's ANSI C++ compiler (aCC), please see the special note in the section entitled "Using HP's ANSI C++ compiler (aCC)" below. -The following instructions assume the use of the widely used "configure, make, -make install" process. There is also support for CMake in the PCRE -distribution; there are some comments about using CMake in the NON-UNIX-USE -file, though it can also be used in Unix-like systems. +The following instructions assume the use of the widely used "configure; make; +make install" (autotools) process. -To build PCRE on a Unix-like system, first run the "configure" command from the -PCRE distribution directory, with your current directory set to the directory -where you want the files to be created. This command is a standard GNU -"autoconf" configuration script, for which generic instructions are supplied in -the file INSTALL. +To build PCRE on system that supports autotools, first run the "configure" +command from the PCRE distribution directory, with your current directory set +to the directory where you want the files to be created. This command is a +standard GNU "autoconf" configuration script, for which generic instructions +are supplied in the file INSTALL. Most commonly, people build PCRE within its own distribution directory, and in this case, on many systems, just running "./configure" is sufficient. However, @@ -143,9 +156,9 @@ the usual methods of changing standard defaults are available. For example: CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local -specifies that the C compiler should be run with the flags '-O2 -Wall' instead -of the default, and that "make install" should install PCRE under /opt/local -instead of the default /usr/local. +This command specifies that the C compiler should be run with the flags '-O2 +-Wall' instead of the default, and that "make install" should install PCRE +under /opt/local instead of the default /usr/local. If you want to build in a different directory, just run "configure" with that directory as current. For example, suppose you have unpacked the PCRE source @@ -159,27 +172,59 @@ possible to build it as a C++ library, though the provided building apparatus does not have any features to support this. There are some optional features that can be included or omitted from the PCRE -library. You can read more about them in the pcrebuild man page. +library. They are also documented in the pcrebuild man page. -. If you want to suppress the building of the C++ wrapper library, you can add - --disable-cpp to the "configure" command. Otherwise, when "configure" is run, - it will try to find a C++ compiler and C++ header files, and if it succeeds, - it will try to build the C++ wrapper. +. By default, both shared and static libraries are built. You can change this + by adding one of these options to the "configure" command: + + --disable-shared + --disable-static + + (See also "Shared libraries on Unix-like systems" below.) + +. By default, only the 8-bit library is built. If you add --enable-pcre16 to + the "configure" command, the 16-bit library is also built. If you want only + the 16-bit library, use "./configure --enable-pcre16 --disable-pcre8". + +. If you are building the 8-bit library and want to suppress the building of + the C++ wrapper library, you can add --disable-cpp to the "configure" + command. Otherwise, when "configure" is run without --disable-pcre8, it will + try to find a C++ compiler and C++ header files, and if it succeeds, it will + try to build the C++ wrapper. + +. If you want to include support for just-in-time compiling, which can give + large performance improvements on certain platforms, add --enable-jit to the + "configure" command. This support is available only for certain hardware + architectures. If you try to enable it on an unsupported architecture, there + will be a compile time error. + +. When JIT support is enabled, pcregrep automatically makes use of it, unless + you add --disable-pcregrep-jit to the "configure" command. . If you want to make use of the support for UTF-8 Unicode character strings in - PCRE, you must add --enable-utf8 to the "configure" command. Without it, the - code for handling UTF-8 is not included in the library. Even when included, - it still has to be enabled by an option at run time. When PCRE is compiled - with this option, its input can only either be ASCII or UTF-8, even when - running on EBCDIC platforms. It is not possible to use both --enable-utf8 and - --enable-ebcdic at the same time. + the 8-bit library, or UTF-16 Unicode character strings in the 16-bit library, + you must add --enable-utf to the "configure" command. Without it, the code + for handling UTF-8 and UTF-16 is not included in the relevant library. Even + when --enable-utf is included, the use of a UTF encoding still has to be + enabled by an option at run time. When PCRE is compiled with this option, its + input can only either be ASCII or UTF-8/16, even when running on EBCDIC + platforms. It is not possible to use both --enable-utf and --enable-ebcdic at + the same time. -. If, in addition to support for UTF-8 character strings, you want to include - support for the \P, \p, and \X sequences that recognize Unicode character - properties, you must add --enable-unicode-properties to the "configure" - command. This adds about 30K to the size of the library (in the form of a - property table); only the basic two-letter properties such as Lu are - supported. +. There are no separate options for enabling UTF-8 and UTF-16 independently + because that would allow ridiculous settings such as requesting UTF-16 + support while building only the 8-bit library. However, the option + --enable-utf8 is retained for backwards compatibility with earlier releases + that did not support 16-bit character strings. It is synonymous with + --enable-utf. It is not possible to configure one library with UTF support + and the other without in the same configuration. + +. If, in addition to support for UTF-8/16 character strings, you want to + include support for the \P, \p, and \X sequences that recognize Unicode + character properties, you must add --enable-unicode-properties to the + "configure" command. This adds about 30K to the size of the library (in the + form of a property table); only the basic two-letter properties such as Lu + are supported. . You can build PCRE to recognize either CR or LF or the sequence CRLF or any of the preceding, or any of the Unicode newline sequences as indicating the @@ -232,10 +277,11 @@ library. You can read more about them in the pcrebuild man page. sizes in the pcrestack man page. . The default maximum compiled pattern size is around 64K. You can increase - this by adding --with-link-size=3 to the "configure" command. You can - increase it even more by setting --with-link-size=4, but this is unlikely - ever to be necessary. Increasing the internal link size will reduce - performance. + this by adding --with-link-size=3 to the "configure" command. In the 8-bit + library, PCRE then uses three bytes instead of two for offsets to different + parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is + the same as --with-link-size=4, which (in both libraries) uses four-byte + offsets. Increasing the internal link size reduces performance. . You can build PCRE so that its internal match() function that is called from pcre_exec() does not call itself recursively. Instead, it uses memory blocks @@ -247,9 +293,10 @@ library. You can read more about them in the pcrebuild man page. on the "configure" command. PCRE runs more slowly in this mode, but it may be necessary in environments with limited stack sizes. This applies only to the - pcre_exec() function; it does not apply to pcre_dfa_exec(), which does not - use deeply nested recursion. There is a discussion about stack sizes in the - pcrestack man page. + normal execution of the pcre_exec() function; if JIT support is being + successfully used, it is not relevant. Equally, it does not apply to + pcre_dfa_exec(), which does not use deeply nested recursion. There is a + discussion about stack sizes in the pcrestack man page. . For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. By default, it uses a set of @@ -269,27 +316,37 @@ library. You can read more about them in the pcrebuild man page. This automatically implies --enable-rebuild-chartables (see above). However, when PCRE is built this way, it always operates in EBCDIC. It cannot support - both EBCDIC and UTF-8. + both EBCDIC and UTF-8/16. -. It is possible to compile pcregrep to use libz and/or libbz2, in order to - read .gz and .bz2 files (respectively), by specifying one or both of +. 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 + libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by + specifying one or both of --enable-pcregrep-libz --enable-pcregrep-libbz2 Of course, the relevant libraries must be installed on your system. -. It is possible to compile pcretest so that it links with the libreadline - library, by specifying +. The default size of internal buffer used by pcregrep can be set by, for + example: - --enable-pcretest-libreadline + --with-pcregrep-bufsize=50K + + The default value is 20K. + +. It is possible to compile pcretest so that it links with the libreadline + or libedit libraries, by specifying, respectively, + + --enable-pcretest-libreadline or --enable-pcretest-libedit If this is done, when pcretest's input is from a terminal, it reads it using the readline() function. This provides line-editing and history facilities. Note that libreadline is GPL-licenced, so if you distribute a binary of - pcretest linked in this way, there may be licensing issues. + pcretest linked in this way, there may be licensing issues. These can be + avoided by linking with libedit (which has a BSD licence) instead. - Setting this option causes the -lreadline option to be added to the pcretest + Enabling libreadline causes the -lreadline option to be added to the pcretest build. In many operating environments with a sytem-installed readline library this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), it may be necessary @@ -302,37 +359,42 @@ library. You can read more about them in the pcrebuild man page. The "configure" script builds the following files for the basic C library: -. Makefile is the makefile that builds the library -. config.h contains build-time configuration options for the library -. pcre.h is the public PCRE header file -. pcre-config is a script that shows the settings of "configure" options -. libpcre.pc is data for the pkg-config command -. libtool is a script that builds shared and/or static libraries -. RunTest is a script for running tests on the basic C library -. RunGrepTest is a script for running tests on the pcregrep command +. Makefile the makefile that builds the library +. config.h build-time configuration options for the library +. pcre.h the public PCRE header file +. pcre-config script that shows the building settings such as CFLAGS + that were set for "configure" +. libpcre.pc ) data for the pkg-config command +. libpcre16.pc ) +. libpcreposix.pc ) +. libtool script that builds shared and/or static libraries Versions of config.h and pcre.h are distributed in the PCRE tarballs under the names config.h.generic and pcre.h.generic. These are provided for those who have to built PCRE without using "configure" or CMake. If you use "configure" or CMake, the .generic versions are not used. -If a C++ compiler is found, the following files are also built: +When building the 8-bit library, if a C++ compiler is found, the following +files are also built: -. libpcrecpp.pc is data for the pkg-config command -. pcrecpparg.h is a header file for programs that call PCRE via the C++ wrapper -. pcre_stringpiece.h is the header for the C++ "stringpiece" functions +. libpcrecpp.pc data for the pkg-config command +. pcrecpparg.h header file for calling PCRE via the C++ wrapper +. pcre_stringpiece.h header for the C++ "stringpiece" functions The "configure" script also creates config.status, which is an executable script that can be run to recreate the configuration, and config.log, which contains compiler output from tests that "configure" runs. -Once "configure" has run, you can run "make". It builds two libraries, called -libpcre and libpcreposix, a test program called pcretest, and the pcregrep -command. If a C++ compiler was found on your system, "make" also builds the C++ -wrapper library, which is called libpcrecpp, and some test programs called -pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest. -Building the C++ wrapper can be disabled by adding --disable-cpp to the -"configure" command. +Once "configure" has run, you can run "make". This builds either or both of the +libraries libpcre and libpcre16, and a test program called pcretest. If you +enabled JIT support with --enable-jit, a test program called pcre_jit_test is +built as well. + +If the 8-bit library is built, libpcreposix and the pcregrep command are also +built, and if a C++ compiler was found on your system, and you did not disable +it with --disable-cpp, "make" builds the C++ wrapper library, which is called +libpcrecpp, as well as some test programs called pcrecpp_unittest, +pcre_scanner_unittest, and pcre_stringpiece_unittest. The command "make check" runs all the appropriate tests. Details of the PCRE tests are given below in a separate section of this document. @@ -343,16 +405,19 @@ system. The following are installed (file names are all relative to the Commands (bin): pcretest - pcregrep + pcregrep (if 8-bit support is enabled) pcre-config Libraries (lib): - libpcre - libpcreposix - libpcrecpp (if C++ support is enabled) + libpcre16 (if 16-bit support is enabled) + libpcre (if 8-bit support is enabled) + libpcreposix (if 8-bit support is enabled) + libpcrecpp (if 8-bit and C++ support is enabled) Configuration information (lib/pkgconfig): + libpcre16.pc libpcre.pc + libpcreposix.pc libpcrecpp.pc (if C++ support is enabled) Header files (include): @@ -366,6 +431,7 @@ system. The following are installed (file names are all relative to the Man pages (share/man/man{1,3}): pcregrep.1 pcretest.1 + pcre-config.1 pcre.3 pcre*.3 (lots more pages, all starting "pcre") @@ -380,17 +446,18 @@ system. The following are installed (file names are all relative to the LICENCE NEWS README - pcre.txt (a concatenation of the man(3) pages) - pcretest.txt the pcretest man page - pcregrep.txt the pcregrep man page + pcre.txt (a concatenation of the man(3) pages) + pcretest.txt the pcretest man page + pcregrep.txt the pcregrep man page + pcre-config.txt the pcre-config man page If you want to remove PCRE from your system, you can run "make uninstall". This removes all the files that "make install" installed. However, it does not remove any directories, because these are often shared with other programs. -Retrieving configuration information on Unix-like systems ---------------------------------------------------------- +Retrieving configuration information +------------------------------------ Running "make install" installs the command pcre-config, which can be used to recall information about the PCRE configuration and installation. For example: @@ -415,8 +482,8 @@ The data is held in *.pc files that are installed in a directory called /lib/pkgconfig. -Shared libraries on Unix-like systems -------------------------------------- +Shared libraries +---------------- The default distribution builds PCRE as shared libraries and static libraries, as long as the operating system supports shared libraries. Shared library @@ -441,8 +508,8 @@ Then run "make" in the usual way. Similarly, you can use --disable-static to build only shared libraries. -Cross-compiling on Unix-like systems ------------------------------------- +Cross-compiling using autotools +------------------------------- You can specify CC and CFLAGS in the normal way to the "configure" command, in order to cross-compile PCRE for some other host. However, you should NOT @@ -514,30 +581,49 @@ script creates the .txt and HTML forms of the documentation from the man pages. Testing PCRE ------------ -To test the basic PCRE library on a Unix system, run the RunTest script that is -created by the configuring process. There is also a script called RunGrepTest -that tests the options of the pcregrep command. If the C++ wrapper library is -built, three test programs called pcrecpp_unittest, pcre_scanner_unittest, and -pcre_stringpiece_unittest are also built. +To test the basic PCRE library on a Unix-like system, run the RunTest script. +There is another script called RunGrepTest that tests the options of the +pcregrep command. If the C++ wrapper library is built, three test programs +called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest +are also built. When JIT support is enabled, another test program called +pcre_jit_test is built. Both the scripts and all the program tests are run if you obey "make check" or -"make test". For other systems, see the instructions in NON-UNIX-USE. +"make test". For other environments, see the instructions in +NON-AUTOTOOLS-BUILD. The RunTest script runs the pcretest test program (which is documented in its -own man page) on each of the testinput files in the testdata directory in -turn, and compares the output with the contents of the corresponding testoutput -files. A file called testtry is used to hold the main output from pcretest -(testsavedregex is also used as a working file). To run pcretest on just one of -the test files, give its number as an argument to RunTest, for example: +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 support are run only if +--enable-utf was used. RunTest outputs a comment when it skips a test. - RunTest 2 +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. -The first test file can also be fed directly into the perltest.pl script to -check that Perl gives the same results. The only difference you should see is -in the first few lines, where the Perl version is given instead of the PCRE -version. +When both 8-bit and 16-bit support is enabled, the entire set of tests is run +twice, once for each library. If you want to run just one set of tests, call +RunTest with either the -8 or -16 option. -The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(), +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: + + RunTest 2 7 11 + +You can also call RunTest with the single argument "list" to cause it to output +a list of tests. + +The first test file can be fed directly into the perltest.pl script to check +that Perl gives the same results. The only difference you should see is in the +first few lines, where the Perl version is given instead of the PCRE version. + +The second set of tests check pcre_fullinfo(), pcre_study(), pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error detection, and run-time flags that are specific to PCRE, as well as the POSIX wrapper API. It also uses the debugging flags to check some of the internals of @@ -572,33 +658,32 @@ RunTest.bat. The version of RunTest.bat included with PCRE 7.4 and above uses Windows versions of test 2. More info on using RunTest.bat is included in the document entitled NON-UNIX-USE.] -The fourth test checks the UTF-8 support. It is not run automatically unless -PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when -running "configure". This file can be also fed directly to the perltest.pl -script, provided you are running Perl 5.8 or higher. +The fourth and fifth tests check the UTF-8/16 support and error handling and +internal UTF features of PCRE that are not relevant to Perl, respectively. The +sixth and seventh tests do the same for Unicode character properties support. -The fifth test checks error handling with UTF-8 encoding, and internal UTF-8 -features of PCRE that are not relevant to Perl. +The eighth, ninth, and tenth tests check the pcre_dfa_exec() alternative +matching function, in non-UTF-8/16 mode, UTF-8/16 mode, and UTF-8/16 mode with +Unicode property support, respectively. -The sixth test (which is Perl-5.10 compatible) checks the support for Unicode -character properties. It it not run automatically unless PCRE is built with -Unicode property support. To to this you must set --enable-unicode-properties -when running "configure". +The eleventh test checks some internal offsets and code size features; it is +run only when the default "link size" of 2 is set (in other cases the sizes +change) and when Unicode property support is enabled. -The seventh, eighth, and ninth tests check the pcre_dfa_exec() alternative -matching function, in non-UTF-8 mode, UTF-8 mode, and UTF-8 mode with Unicode -property support, respectively. The eighth and ninth tests are not run -automatically unless PCRE is build with the relevant support. +The twelfth test is run only when JIT support is available, and the thirteenth +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 tenth test checks some internal offsets and code size features; it is run -only when the default "link size" of 2 is set (in other cases the sizes -change). +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-bit mode. +These are tests that generate different output in the two modes. They are for +general cases, UTF-8/16 support, and Unicode property support, respectively. -The eleventh test checks out features that are new in Perl 5.10, and the -twelfth test checks a number internals and non-Perl features concerned with -Unicode property support. It it not run automatically unless PCRE is built with -Unicode property support. To to this you must set --enable-unicode-properties -when running "configure". +The twentieth test is run only in 16-bit mode. It tests some specific 16-bit +features of the DFA matching engine. + +The twenty-first and twenty-second tests are run only in 16-bit mode, when the +link size is set to 2. They test reloading pre-compiled patterns. Character tables @@ -658,7 +743,9 @@ will cause PCRE to malfunction. File manifest ------------- -The distribution should contain the following files: +The distribution should contain the files listed below. Where a file name is +given as pcre[16]_xxx it means that there are two files, one with the name +pcre_xxx and the other with the name pcre16_xxx. (A) Source files of the PCRE library functions and their headers: @@ -667,33 +754,40 @@ The distribution should contain the following files: 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_chartables.c + specified, by copying to pcre[16]_chartables.c pcreposix.c ) - pcre_compile.c ) - pcre_config.c ) - pcre_dfa_exec.c ) - pcre_exec.c ) - pcre_fullinfo.c ) - pcre_get.c ) sources for the functions in the library, - pcre_globals.c ) and some internal functions that they use - pcre_info.c ) - pcre_maketables.c ) - pcre_newline.c ) + pcre[16]_byte_order.c ) + pcre[16]_compile.c ) + pcre[16]_config.c ) + pcre[16]_dfa_exec.c ) + pcre[16]_exec.c ) + pcre[16]_fullinfo.c ) + pcre[16]_get.c ) sources for the functions in the library, + pcre[16]_globals.c ) and some internal functions that they use + pcre[16]_jit_compile.c ) + pcre[16]_maketables.c ) + pcre[16]_newline.c ) + pcre[16]_refcount.c ) + pcre[16]_string_utils.c ) + pcre[16]_study.c ) + pcre[16]_tables.c ) + pcre[16]_ucd.c ) + pcre[16]_version.c ) + pcre[16]_xclass.c ) pcre_ord2utf8.c ) - pcre_refcount.c ) - pcre_study.c ) - pcre_tables.c ) - pcre_try_flipped.c ) - pcre_ucd.c ) pcre_valid_utf8.c ) - pcre_version.c ) - pcre_xclass.c ) - pcre_printint.src ) debugging function that is #included in pcretest, + pcre16_ord2utf16.c ) + pcre16_utf16_utils.c ) + pcre16_valid_utf16.c ) + + pcre[16]_printint.c ) debugging function that is used by pcretest, ) and can also be #included in pcre_compile() + pcre.h.in template for pcre.h when built by "configure" pcreposix.h header for the external POSIX wrapper API pcre_internal.h header for internal use + sljit/* 16 files that make up the JIT compiler ucp.h header for Unicode property handling config.h.in template for config.h, which is built by "configure" @@ -730,7 +824,8 @@ The distribution should contain the following files: Makefile.am ) the automake input that was used to create ) Makefile.in NEWS important changes in this release - NON-UNIX-USE notes on building PCRE on non-Unix systems + NON-UNIX-USE the previous name for NON-AUTOTOOLS-BUILD + NON-AUTOTOOLS-BUILD notes on building PCRE without using autotools PrepareRelease script to make preparations for "make dist" README this file RunTest a Unix shell script for running tests @@ -751,6 +846,7 @@ The distribution should contain the following files: doc/pcretest.txt plain text documentation of test program doc/perltest.txt plain text documentation of Perl test program install-sh a shell script for installing files + libpcre16.pc.in template for libpcre16.pc for pkg-config libpcre.pc.in template for libpcre.pc for pkg-config libpcreposix.pc.in template for libpcreposix.pc for pkg-config libpcrecpp.pc.in template for libpcrecpp.pc for pkg-config @@ -760,17 +856,20 @@ The distribution should contain the following files: mkinstalldirs script for making install directories perltest.pl Perl test program pcre-config.in source of script which retains PCRE information + pcre_jit_test.c test program for the JIT compiler pcrecpp_unittest.cc ) pcre_scanner_unittest.cc ) test programs for the C++ wrapper pcre_stringpiece_unittest.cc ) testdata/testinput* test data for main library tests testdata/testoutput* expected test results testdata/grep* input and output for pcregrep tests + testdata/* other supporting test files (D) Auxiliary files for cmake support cmake/COPYING-CMAKE-SCRIPTS cmake/FindPackageHandleStandardArgs.cmake + cmake/FindEditline.cmake cmake/FindReadline.cmake CMakeLists.txt config-cmake.h.in @@ -796,4 +895,4 @@ The distribution should contain the following files: Philip Hazel Email local part: ph10 Email domain: cam.ac.uk -Last updated: 19 January 2010 +Last updated: 18 June 2012 diff --git a/ext/pcre/pcrelib/config.h b/ext/pcre/pcrelib/config.h index 46e0625fa01..64e155784b8 100644 --- a/ext/pcre/pcrelib/config.h +++ b/ext/pcre/pcrelib/config.h @@ -282,7 +282,7 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE 8.12" +#define PACKAGE_STRING "PCRE 8.31" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -291,7 +291,7 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "8.12" +#define PACKAGE_VERSION "8.31" /* If you are compiling for a system other than a Unix-like system or @@ -347,7 +347,7 @@ them both to 0; an emulation function will be used. */ /* Version number of package */ #ifndef VERSION -#define VERSION "8.12" +#define VERSION "8.31" #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/ext/pcre/pcrelib/dftables.c b/ext/pcre/pcrelib/dftables.c index 63fc7074ec9..763ac8c64fc 100644 --- a/ext/pcre/pcrelib/dftables.c +++ b/ext/pcre/pcrelib/dftables.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -112,7 +112,7 @@ fprintf(f, "#endif\n\n" "#include \"pcre_internal.h\"\n\n"); fprintf(f, - "const unsigned char _pcre_default_tables[] = {\n\n" + "const pcre_uint8 PRIV(default_tables)[] = {\n\n" "/* This table is a lower casing table. */\n\n"); fprintf(f, " "); diff --git a/ext/pcre/pcrelib/doc/pcre.txt b/ext/pcre/pcrelib/doc/pcre.txt index ac4254ec99d..19f04f275a0 100644 --- a/ext/pcre/pcrelib/doc/pcre.txt +++ b/ext/pcre/pcrelib/doc/pcre.txt @@ -25,11 +25,27 @@ INTRODUCTION items, and there is an option for requesting some minor changes that give better JavaScript compatibility. + Starting with release 8.30, it is possible to compile two separate PCRE + libraries: the original, which supports 8-bit character strings + (including UTF-8 strings), and a second library that supports 16-bit + character strings (including UTF-16 strings). The build process allows + either one or both to be built. The majority of the work to make this + possible was done by Zoltan Herczeg. + + The two libraries contain identical sets of functions, except that the + names in the 16-bit library start with pcre16_ instead of pcre_. To + avoid over-complication and reduce the documentation maintenance load, + most of the documentation describes the 8-bit library, with the differ- + ences for the 16-bit library described separately in the pcre16 page. + References to functions or structures of the form pcre[16]_xxx should + be read as meaning "pcre_xxx when using the 8-bit library and + pcre16_xxx when using the 16-bit library". + The current implementation of PCRE corresponds approximately with Perl - 5.12, including support for UTF-8 encoded strings and Unicode general - category properties. However, UTF-8 and Unicode support has to be - explicitly enabled; it is not the default. The Unicode tables corre- - spond to Unicode release 5.2.0. + 5.12, including support for UTF-8/16 encoded strings and Unicode gen- + eral category properties. However, UTF-8/16 and Unicode support has to + be explicitly enabled; it is not the default. The Unicode tables corre- + spond to Unicode release 6.0.0. In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a dif- @@ -39,218 +55,71 @@ INTRODUCTION PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, - Google Inc. have provided a comprehensive C++ wrapper. This is now - included as part of the PCRE distribution. The pcrecpp page has details - of this interface. Other people's contributions can be found in the - Contrib directory at the primary FTP site, which is: + Google Inc. have provided a comprehensive C++ wrapper for the 8-bit + library. This is now included as part of the PCRE distribution. The + pcrecpp page has details of this interface. Other people's contribu- + tions can be found in the Contrib directory at the primary FTP site, + which is: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre - Details of exactly which Perl regular expression features are and are + Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the pcrepat- - tern and pcrecompat pages. There is a syntax summary in the pcresyntax + tern and pcrecompat pages. There is a syntax summary in the pcresyntax page. - Some features of PCRE can be included, excluded, or changed when the - library is built. The pcre_config() function makes it possible for a - client to discover which features are available. The features them- - selves are described in the pcrebuild page. Documentation about build- - ing PCRE for various operating systems can be found in the README and + Some features of PCRE can be included, excluded, or changed when the + library is built. The pcre_config() function makes it possible for a + client to discover which features are available. The features them- + selves are described in the pcrebuild page. Documentation about build- + ing PCRE for various operating systems can be found in the README and NON-UNIX-USE files in the source distribution. - The library contains a number of undocumented internal functions and - data tables that are used by more than one of the exported external - functions, but which are not intended for use by external callers. - Their names all begin with "_pcre_", which hopefully will not provoke - any name clashes. In some environments, it is possible to control which - external symbols are exported when a shared library is built, and in - these cases the undocumented symbols are not exported. + The libraries contains a number of undocumented internal functions and + data tables that are used by more than one of the exported external + functions, but which are not intended for use by external callers. + Their names all begin with "_pcre_" or "_pcre16_", which hopefully will + not provoke any name clashes. In some environments, it is possible to + control which external symbols are exported when a shared library is + built, and in these cases the undocumented symbols are not exported. USER DOCUMENTATION - The user documentation for PCRE comprises a number of different sec- - tions. In the "man" format, each of these is a separate "man page". In - the HTML format, each is a separate page, linked from the index page. - In the plain text format, all the sections, except the pcredemo sec- + The user documentation for PCRE comprises a number of different sec- + tions. In the "man" format, each of these is a separate "man page". In + the HTML format, each is a separate page, linked from the index page. + In the plain text format, all the sections, except the pcredemo sec- tion, are concatenated, for ease of searching. The sections are as fol- lows: pcre this document + pcre16 details of the 16-bit library pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API pcrebuild options for building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility - pcrecpp details of the C++ wrapper + pcrecpp details of the C++ wrapper for the 8-bit library pcredemo a demonstration C program that uses PCRE - pcregrep description of the pcregrep command + pcregrep description of the pcregrep command (8-bit only) + pcrejit discussion of the just-in-time optimization support + pcrelimits details of size and other limits pcrematching discussion of the two matching algorithms pcrepartial details of the partial matching facility pcrepattern syntax and semantics of supported regular expressions pcreperform discussion of performance issues - pcreposix the POSIX-compatible C API + pcreposix the POSIX-compatible C API for the 8-bit library pcreprecompile details of saving and re-using precompiled patterns pcresample discussion of the pcredemo program pcrestack discussion of stack usage pcresyntax quick syntax reference pcretest description of the pcretest testing command + pcreunicode discussion of Unicode and UTF-8/16 support - In addition, in the "man" and HTML formats, there is a short page for - each C library function, listing its arguments and results. - - -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 65539 (sic) bytes if PCRE - is compiled with the default internal linkage size of 2. If you want to - process regular expressions that are truly enormous, you can compile - PCRE with an internal linkage size of 3 or 4 (see the README file in - the source distribution and the pcrebuild documentation for details). - In these cases the limit is substantially larger. However, the speed - of execution is slower. - - All values in repeating quantifiers must be less than 65536. - - There is no limit to the number of parenthesized subpatterns, but there - can be no more than 65535 capturing subpatterns. - - The maximum length of name for a named subpattern is 32 characters, and - the maximum number of named subpatterns is 10000. - - The maximum length of a subject string is the largest positive number - that an integer variable can hold. However, when using the traditional - matching function, PCRE uses recursion to handle subpatterns and indef- - inite repetition. This means that the available stack space may limit - the size of a subject string that can be processed by certain patterns. - For a discussion of stack issues, see the pcrestack documentation. - - -UTF-8 AND UNICODE PROPERTY SUPPORT - - From release 3.3, PCRE has had some support for character strings - encoded in the UTF-8 format. For release 4.0 this was greatly extended - to cover most common requirements, and in release 5.0 additional sup- - port for Unicode general category properties was added. - - In order process UTF-8 strings, you must build PCRE to include UTF-8 - support in the code, and, in addition, you must call pcre_compile() - with the PCRE_UTF8 option flag, or the pattern must start with the - sequence (*UTF8). When either of these is the case, both the pattern - and any subject strings that are matched against it are treated as - UTF-8 strings instead of strings of 1-byte characters. - - If you compile PCRE with UTF-8 support, but do not use it at run time, - the library will be a bit bigger, but the additional run time overhead - is limited to testing the PCRE_UTF8 flag occasionally, so should not be - very big. - - If PCRE is built with Unicode character property support (which implies - UTF-8 support), the escape sequences \p{..}, \P{..}, and \X are sup- - ported. The available properties that can be tested are limited to the - general category properties such as Lu for an upper case letter or Nd - for a decimal number, the Unicode script names such as Arabic or Han, - and the derived properties Any and L&. A full list is given in the - pcrepattern documentation. Only the short names for properties are sup- - ported. For example, \p{L} matches a letter. Its Perl synonym, \p{Let- - ter}, is not supported. Furthermore, in Perl, many properties may - optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE - does not support this. - - Validity of UTF-8 strings - - When you set the PCRE_UTF8 flag, the strings passed as patterns and - subjects are (by default) checked for validity on entry to the relevant - functions. From release 7.3 of PCRE, the check is according the rules - of RFC 3629, which are themselves derived from the Unicode specifica- - tion. Earlier releases of PCRE followed the rules of RFC 2279, which - allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current - check allows only values in the range U+0 to U+10FFFF, excluding U+D800 - to U+DFFF. - - The excluded code points are the "Low Surrogate Area" of Unicode, of - which the Unicode Standard says this: "The Low Surrogate Area does not - contain any character assignments, consequently no character code - charts or namelists are provided for this area. Surrogates are reserved - for use with UTF-16 and then must be used in pairs." The code points - that are encoded by UTF-16 pairs are available as independent code - points in the UTF-8 encoding. (In other words, the whole surrogate - thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) - - If an invalid UTF-8 string is passed to PCRE, an error return - (PCRE_ERROR_BADUTF8) is given. In some situations, you may already know - that your strings are valid, and therefore want to skip these checks in - order to improve performance. If you set the PCRE_NO_UTF8_CHECK flag at - compile time or at run time, PCRE assumes that the pattern or subject - it is given (respectively) contains only valid UTF-8 codes. In this - case, it does not diagnose an invalid UTF-8 string. - - If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, - what happens depends on why the string is invalid. If the string con- - forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a - string of characters in the range 0 to 0x7FFFFFFF. In other words, - apart from the initial validity test, PCRE (when in UTF-8 mode) handles - strings according to the more liberal rules of RFC 2279. However, if - the string does not even conform to RFC 2279, the result is undefined. - Your program may crash. - - If you want to process strings of values in the full range 0 to - 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can - set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in - this situation, you will have to apply your own validity check. - - General comments about UTF-8 mode - - 1. An unbraced hexadecimal escape sequence (such as \xb3) matches a - two-byte UTF-8 character if the value is greater than 127. - - 2. Octal numbers up to \777 are recognized, and match two-byte UTF-8 - characters for values greater than \177. - - 3. Repeat quantifiers apply to complete UTF-8 characters, not to indi- - vidual bytes, for example: \x{100}{3}. - - 4. The dot metacharacter matches one UTF-8 character instead of a sin- - gle byte. - - 5. The escape sequence \C can be used to match a single byte in UTF-8 - mode, but its use can lead to some strange effects. This facility is - not available in the alternative matching function, pcre_dfa_exec(). - - 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly - test characters of any code value, but, by default, the characters that - PCRE recognizes as digits, spaces, or word characters remain the same - set as before, all with values less than 256. This remains true even - when PCRE is built to include Unicode property support, because to do - otherwise would slow down PCRE in many common cases. Note in particular - that this applies to \b and \B, because they are defined in terms of \w - and \W. If you really want to test for a wider sense of, say, "digit", - you can use explicit Unicode property tests such as \p{Nd}. Alterna- - tively, if you set the PCRE_UCP option, the way that the character - escapes work is changed so that Unicode properties are used to deter- - mine which characters match. There are more details in the section on - generic character types in the pcrepattern documentation. - - 7. Similarly, characters that match the POSIX named character classes - are all low-valued characters, unless the PCRE_UCP option is set. - - 8. However, the horizontal and vertical whitespace matching escapes - (\h, \H, \v, and \V) do match all the appropriate Unicode characters, - whether or not PCRE_UCP is set. - - 9. Case-insensitive matching applies only to characters whose values - are less than 128, unless PCRE is built with Unicode property support. - Even when Unicode property support is available, PCRE still uses its - own character tables when checking the case of low-valued characters, - so as not to degrade performance. The Unicode property information is - used only for characters with higher values. Furthermore, PCRE supports - case-insensitive matching only when there is a one-to-one mapping - between a letter's cases. There are a small number of many-to-one map- - pings in Unicode; these are not supported by PCRE. + In addition, in the "man" and HTML formats, there is a short page for + each 8-bit C library function, listing its arguments and results. AUTHOR @@ -259,15 +128,341 @@ 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: 13 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCRE(3) PCRE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + #include + + +PCRE 16-BIT API BASIC FUNCTIONS + + pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); + + pcre16_extra *pcre16_study(const pcre16 *code, int options, + const char **errptr); + + void pcre16_free_study(pcre16_extra *extra); + + int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); + + int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); + + +PCRE 16-BIT API STRING EXTRACTION FUNCTIONS + + int pcre16_copy_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int buffersize); + + int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, + int buffersize); + + int pcre16_get_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr); + + int pcre16_get_stringnumber(const pcre16 *code, + PCRE_SPTR16 name); + + int pcre16_get_stringtable_entries(const pcre16 *code, + PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); + + int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, + PCRE_SPTR16 *stringptr); + + int pcre16_get_substring_list(PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 **listptr); + + void pcre16_free_substring(PCRE_SPTR16 stringptr); + + void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); + + +PCRE 16-BIT API AUXILIARY FUNCTIONS + + pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize); + + void pcre16_jit_stack_free(pcre16_jit_stack *stack); + + void pcre16_assign_jit_stack(pcre16_extra *extra, + pcre16_jit_callback callback, void *data); + + const unsigned char *pcre16_maketables(void); + + int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, + int what, void *where); + + int pcre16_refcount(pcre16 *code, int adjust); + + int pcre16_config(int what, void *where); + + const char *pcre16_version(void); + + int pcre16_pattern_to_host_byte_order(pcre16 *code, + pcre16_extra *extra, const unsigned char *tables); + + +PCRE 16-BIT API INDIRECTED FUNCTIONS + + void *(*pcre16_malloc)(size_t); + + void (*pcre16_free)(void *); + + void *(*pcre16_stack_malloc)(size_t); + + void (*pcre16_stack_free)(void *); + + int (*pcre16_callout)(pcre16_callout_block *); + + +PCRE 16-BIT API 16-BIT-ONLY FUNCTION + + int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, + PCRE_SPTR16 input, int length, int *byte_order, + int keep_boms); + + +THE PCRE 16-BIT LIBRARY + + Starting with release 8.30, it is possible to compile a PCRE library + that supports 16-bit character strings, including UTF-16 strings, as + well as or instead of the original 8-bit library. The majority of the + work to make this possible was done by Zoltan Herczeg. The two + libraries contain identical sets of functions, used in exactly the same + way. Only the names of the functions and the data types of their argu- + ments and results are different. To avoid over-complication and reduce + the documentation maintenance load, most of the PCRE documentation + describes the 8-bit library, with only occasional references to the + 16-bit library. This page describes what is different when you use the + 16-bit library. + + WARNING: A single application can be linked with both libraries, but + you must take care when processing any particular pattern to use func- + tions from just one library. For example, if you want to study a pat- + tern that was compiled with pcre16_compile(), you must do so with + pcre16_study(), not pcre_study(), and you must free the study data with + pcre16_free_study(). + + +THE HEADER FILE + + There is only one header file, pcre.h. It contains prototypes for all + the functions in both libraries, as well as definitions of flags, + structures, error codes, etc. + + +THE LIBRARY NAME + + In Unix-like systems, the 16-bit library is called libpcre16, and can + normally be accesss by adding -lpcre16 to the command for linking an + application that uses PCRE. + + +STRING TYPES + + In the 8-bit library, strings are passed to PCRE library functions as + vectors of bytes with the C type "char *". In the 16-bit library, + strings are passed as vectors of unsigned 16-bit quantities. The macro + PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is + defined as "const PCRE_UCHAR16 *". In very many environments, "short + int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 + as "short int", but checks that it really is a 16-bit data type. If it + is not, the build fails with an error message telling the maintainer to + modify the definition appropriately. + + +STRUCTURE TYPES + + The types of the opaque structures that are used for compiled 16-bit + patterns and JIT stacks are pcre16 and pcre16_jit_stack respectively. + The type of the user-accessible structure that is returned by + pcre16_study() is pcre16_extra, and the type of the structure that is + used for passing data to a callout function is pcre16_callout_block. + These structures contain the same fields, with the same names, as their + 8-bit counterparts. The only difference is that pointers to character + strings are 16-bit instead of 8-bit types. + + +16-BIT FUNCTIONS + + For every function in the 8-bit library there is a corresponding func- + tion in the 16-bit library with a name that starts with pcre16_ instead + of pcre_. The prototypes are listed above. In addition, there is one + extra function, pcre16_utf16_to_host_byte_order(). This is a utility + function that converts a UTF-16 character string to host byte order if + necessary. The other 16-bit functions expect the strings they are + passed to be in host byte order. + + The input and output arguments of pcre16_utf16_to_host_byte_order() may + point to the same address, that is, conversion in place is supported. + The output buffer must be at least as long as the input. + + The length argument specifies the number of 16-bit data units in the + input string; a negative value specifies a zero-terminated string. + + If byte_order is NULL, it is assumed that the string starts off in host + byte order. This may be changed by byte-order marks (BOMs) anywhere in + the string (commonly as the first character). + + If byte_order is not NULL, a non-zero value of the integer to which it + points means that the input starts off in host byte order, otherwise + the opposite order is assumed. Again, BOMs in the string can change + this. The final byte order is passed back at the end of processing. + + If keep_boms is not zero, byte-order mark characters (0xfeff) are + copied into the output string. Otherwise they are discarded. + + The result of the function is the number of 16-bit units placed into + the output buffer, including the zero terminator if the string was + zero-terminated. + + +SUBJECT STRING OFFSETS + + The offsets within subject strings that are returned by the matching + functions are in 16-bit units rather than bytes. + + +NAMED SUBPATTERNS + + The name-to-number translation table that is maintained for named sub- + patterns uses 16-bit characters. The pcre16_get_stringtable_entries() + function returns the length of each entry in the table as the number of + 16-bit data units. + + +OPTION NAMES + + There are two new general option names, PCRE_UTF16 and + PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and + PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options + define the same bits in the options word. There is a discussion about + the validity of UTF-16 strings in the pcreunicode page. + + For the pcre16_config() function there is an option PCRE_CONFIG_UTF16 + that returns 1 if UTF-16 support is configured, otherwise 0. If this + option is given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is + given to pcre16_config(), the result is the PCRE_ERROR_BADOPTION error. + + +CHARACTER CODES + + In 16-bit mode, when PCRE_UTF16 is not set, character values are + treated in the same way as in 8-bit, non UTF-8 mode, except, of course, + that they can range from 0 to 0xffff instead of 0 to 0xff. Character + types for characters less than 0xff can therefore be influenced by the + locale in the same way as before. Characters greater than 0xff have + only one case, and no "type" (such as letter or digit). + + In UTF-16 mode, the character code is Unicode, in the range 0 to + 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff + because those are "surrogate" values that are used in pairs to encode + values greater than 0xffff. + + A UTF-16 string can indicate its endianness by special code knows as a + byte-order mark (BOM). The PCRE functions do not handle this, expecting + strings to be in host byte order. A utility function called + pcre16_utf16_to_host_byte_order() is provided to help with this (see + above). + + +ERROR NAMES + + The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 corre- + spond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is + given when a compiled pattern is passed to a function that processes + patterns in the other mode, for example, if a pattern compiled with + pcre_compile() is passed to pcre16_exec(). + + There are new error codes whose names begin with PCRE_UTF16_ERR for + invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for + UTF-8 strings that are described in the section entitled "Reason codes + for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors + are: + + PCRE_UTF16_ERR1 Missing low surrogate at end of string + PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate + PCRE_UTF16_ERR3 Isolated low surrogate + PCRE_UTF16_ERR4 Invalid character 0xfffe + + +ERROR TEXTS + + If there is an error while compiling a pattern, the error text that is + passed back by pcre16_compile() or pcre16_compile2() is still an 8-bit + character string, zero-terminated. + + +CALLOUTS + + The subject and mark fields in the callout block that is passed to a + callout function point to 16-bit vectors. + + +TESTING + + The pcretest program continues to operate with 8-bit input and output + files, but it can be used for testing the 16-bit library. If it is run + with the command line option -16, patterns and subject strings are con- + verted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit + library functions are used instead of the 8-bit ones. Returned 16-bit + strings are converted to 8-bit for output. If the 8-bit library was not + compiled, pcretest defaults to 16-bit and the -16 option is ignored. + + When PCRE is being built, the RunTest script that is called by "make + check" uses the pcretest -C option to discover which of the 8-bit and + 16-bit libraries has been built, and runs the tests appropriately. + + +NOT SUPPORTED IN 16-BIT MODE + + Not all the features of the 8-bit library are available with the 16-bit + library. The C++ and POSIX wrapper functions support only the 8-bit + library, and the pcregrep program is at present 8-bit only. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 14 April 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -307,46 +502,89 @@ PCRE BUILD-TIME OPTIONS is not described. +BUILDING 8-BIT and 16-BIT LIBRARIES + + By default, a library called libpcre is built, containing functions + that take string arguments contained in vectors of bytes, either as + single-byte characters, or interpreted as UTF-8 strings. You can also + build a separate library, called libpcre16, in which strings are con- + tained in vectors of 16-bit data units and interpreted either as sin- + gle-unit characters or UTF-16 strings, by adding + + --enable-pcre16 + + to the configure command. If you do not want the 8-bit library, add + + --disable-pcre8 + + as well. At least one of the two libraries must be built. Note that the + C++ and POSIX wrappers are for the 8-bit library only, and that pcre- + grep is an 8-bit program. None of these are built if you select only + the 16-bit library. + + +BUILDING SHARED AND STATIC LIBRARIES + + The PCRE building process uses libtool to build both shared and static + Unix libraries by default. You can suppress one of these by adding one + of + + --disable-shared + --disable-static + + to the configure command, as required. + + C++ SUPPORT - By default, the configure script will search for a C++ compiler and C++ - header files. If it finds them, it automatically builds the C++ wrapper - library for PCRE. You can disable this by adding + By default, if the 8-bit library is being built, the configure script + will search for a C++ compiler and C++ header files. If it finds them, + it automatically builds the C++ wrapper library (which supports only + 8-bit strings). You can disable this by adding --disable-cpp to the configure command. -UTF-8 SUPPORT +UTF-8 and UTF-16 SUPPORT - To build PCRE with support for UTF-8 Unicode character strings, add + To build PCRE with support for UTF Unicode character strings, add - --enable-utf8 + --enable-utf - to the configure command. Of itself, this does not make PCRE treat - strings as UTF-8. As well as compiling PCRE with this option, you also - have have to set the PCRE_UTF8 option when you call the pcre_compile() - or pcre_compile2() functions. + to the configure command. This setting applies to both libraries, + adding support for UTF-8 to the 8-bit library and support for UTF-16 to + the 16-bit library. There are no separate options for enabling UTF-8 + and UTF-16 independently because that would allow ridiculous settings + such as requesting UTF-16 support while building only the 8-bit + library. It is not possible to build one library with UTF support and + the other without in the same configuration. (For backwards compatibil- + ity, --enable-utf8 is a synonym of --enable-utf.) - If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE - expects its input to be either ASCII or UTF-8 (depending on the runtime - option). It is not possible to support both EBCDIC and UTF-8 codes in - the same version of the library. Consequently, --enable-utf8 and + Of itself, this setting does not make PCRE treat strings as UTF-8 or + UTF-16. As well as compiling PCRE with this option, you also have have + to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pat- + tern compiling functions. + + If you set --enable-utf when compiling in an EBCDIC environment, PCRE + expects its input to be either ASCII or UTF-8 (depending on the run- + time option). It is not possible to support both EBCDIC and UTF-8 codes + in the same version of the library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive. UNICODE CHARACTER PROPERTY SUPPORT - UTF-8 support allows PCRE to process character values greater than 255 - in the strings that it handles. On its own, however, it does not pro- - vide any facilities for accessing the properties of such characters. If - you want to be able to use the pattern escapes \P, \p, and \X, which - refer to Unicode character properties, you must add + UTF support allows the libraries to process character codepoints up to + 0x10ffff in the strings that they handle. On its own, however, it does + not provide any facilities for accessing the properties of such charac- + ters. If you want to be able to use the pattern escapes \P, \p, and \X, + which refer to Unicode character properties, you must add --enable-unicode-properties - to the configure command. This implies UTF-8 support, even if you have + to the configure command. This implies UTF support, even if you have not explicitly requested it. Including Unicode property support adds around 30K of tables to the @@ -354,6 +592,23 @@ UNICODE CHARACTER PROPERTY SUPPORT are supported. Details are given in the pcrepattern documentation. +JUST-IN-TIME COMPILER SUPPORT + + Just-in-time compiler support is included in the build by specifying + + --enable-jit + + This support is available only for certain hardware architectures. If + this option is set for an unsupported architecture, a compile time + error occurs. See the pcrejit documentation for a discussion of JIT + usage. When JIT support is enabled, pcregrep automatically makes use of + it, unless you add + + --disable-pcregrep-jit + + to the "configure" command. + + CODE VALUE OF NEWLINE By default, PCRE interprets the linefeed (LF) character as indicating @@ -400,28 +655,16 @@ WHAT \R MATCHES functions are called. -BUILDING SHARED AND STATIC LIBRARIES - - The PCRE building process uses libtool to build both shared and static - Unix libraries by default. You can suppress one of these by adding one - of - - --disable-shared - --disable-static - - to the configure command, as required. - - POSIX MALLOC USAGE - When PCRE is called through the POSIX interface (see the pcreposix doc- - umentation), additional working storage is required for holding the - pointers to capturing substrings, because PCRE requires three integers - per substring, whereas the POSIX interface provides only two. If the - number of expected substrings is small, the wrapper function uses space - on the stack, because this is faster than using malloc() for each call. - The default threshold above which the stack is no longer used is 10; it - can be changed by adding a setting such as + When the 8-bit library is called through the POSIX interface (see the + pcreposix documentation), additional working storage is required for + holding the pointers to capturing substrings, because PCRE requires + three integers per substring, whereas the POSIX interface provides only + two. If the number of expected substrings is small, the wrapper func- + tion uses space on the stack, because this is faster than using mal- + loc() for each call. The default threshold above which the stack is no + longer used is 10; it can be changed by adding a setting such as --with-posix-malloc-threshold=20 @@ -435,107 +678,108 @@ HANDLING VERY LARGE PATTERNS nation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. - Nevertheless, some people do want to process truyl enormous patterns, + Nevertheless, some people do want to process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte off- sets by adding a setting such as --with-link-size=3 - to the configure command. The value given must be 2, 3, or 4. Using - longer offsets slows down the operation of PCRE because it has to load - additional bytes when handling them. + to the configure command. The value given must be 2, 3, or 4. For the + 16-bit library, a value of 3 is rounded up to 4. Using longer offsets + slows down the operation of PCRE because it has to load additional data + when handling them. AVOIDING EXCESSIVE STACK USAGE When matching with the pcre_exec() function, PCRE implements backtrack- - ing by making recursive calls to an internal function called match(). - In environments where the size of the stack is limited, this can se- - verely limit PCRE's operation. (The Unix environment does not usually + ing by making recursive calls to an internal function called match(). + In environments where the size of the stack is limited, this can se- + verely limit PCRE's operation. (The Unix environment does not usually suffer from this problem, but it may sometimes be necessary to increase - the maximum stack size. There is a discussion in the pcrestack docu- - mentation.) An alternative approach to recursion that uses memory from - the heap to remember data, instead of using recursive function calls, - has been implemented to work round the problem of limited stack size. + the maximum stack size. There is a discussion in the pcrestack docu- + mentation.) An alternative approach to recursion that uses memory from + the heap to remember data, instead of using recursive function calls, + has been implemented to work round the problem of limited stack size. If you want to build a version of PCRE that works this way, add --disable-stack-for-recursion - to the configure command. With this configuration, PCRE will use the - pcre_stack_malloc and pcre_stack_free variables to call memory manage- - ment functions. By default these point to malloc() and free(), but you + to the configure command. With this configuration, PCRE will use the + pcre_stack_malloc and pcre_stack_free variables to call memory manage- + ment functions. By default these point to malloc() and free(), but you can replace the pointers so that your own functions are used instead. - Separate functions are provided rather than using pcre_malloc and - pcre_free because the usage is very predictable: the block sizes - requested are always the same, and the blocks are always freed in - reverse order. A calling program might be able to implement optimized - functions that perform better than malloc() and free(). PCRE runs + Separate functions are provided rather than using pcre_malloc and + pcre_free because the usage is very predictable: the block sizes + requested are always the same, and the blocks are always freed in + reverse order. A calling program might be able to implement optimized + functions that perform better than malloc() and free(). PCRE runs noticeably more slowly when built in this way. This option affects only the pcre_exec() function; it is not relevant for pcre_dfa_exec(). LIMITING PCRE RESOURCE USAGE - Internally, PCRE has a function called match(), which it calls repeat- - edly (sometimes recursively) when matching a pattern with the - pcre_exec() function. By controlling the maximum number of times this - function may be called during a single matching operation, a limit can - be placed on the resources used by a single call to pcre_exec(). The - limit can be changed at run time, as described in the pcreapi documen- - tation. The default is 10 million, but this can be changed by adding a + Internally, PCRE has a function called match(), which it calls repeat- + edly (sometimes recursively) when matching a pattern with the + pcre_exec() function. By controlling the maximum number of times this + function may be called during a single matching operation, a limit can + be placed on the resources used by a single call to pcre_exec(). The + limit can be changed at run time, as described in the pcreapi documen- + tation. The default is 10 million, but this can be changed by adding a setting such as --with-match-limit=500000 - to the configure command. This setting has no effect on the + to the configure command. This setting has no effect on the pcre_dfa_exec() matching function. - In some environments it is desirable to limit the depth of recursive + In some environments it is desirable to limit the depth of recursive calls of match() more strictly than the total number of calls, in order - to restrict the maximum amount of stack (or heap, if --disable-stack- + to restrict the maximum amount of stack (or heap, if --disable-stack- for-recursion is specified) that is used. A second limit controls this; - it defaults to the value that is set for --with-match-limit, which - imposes no additional constraints. However, you can set a lower limit + it defaults to the value that is set for --with-match-limit, which + imposes no additional constraints. However, you can set a lower limit by adding, for example, --with-match-limit-recursion=10000 - to the configure command. This value can also be overridden at run + to the configure command. This value can also be overridden at run time. CREATING CHARACTER TABLES AT BUILD TIME - PCRE uses fixed tables for processing characters whose code values are - less than 256. By default, PCRE is built with a set of tables that are - distributed in the file pcre_chartables.c.dist. These tables are for + PCRE uses fixed tables for processing characters whose code values are + less than 256. By default, PCRE is built with a set of tables that are + distributed in the file pcre_chartables.c.dist. These tables are for ASCII codes only. If you add --enable-rebuild-chartables - to the configure command, the distributed tables are no longer used. - Instead, a program called dftables is compiled and run. This outputs + to the configure command, the distributed tables are no longer used. + Instead, a program called dftables is compiled and run. This outputs the source for new set of tables, created in the default locale of your - C runtime system. (This method of replacing the tables does not work if - you are cross compiling, because dftables is run on the local host. If - you need to create alternative tables when cross compiling, you will + C run-time system. (This method of replacing the tables does not work + if you are cross compiling, because dftables is run on the local host. + If you need to create alternative tables when cross compiling, you will have to do so "by hand".) USING EBCDIC CODE - PCRE assumes by default that it will run in an environment where the - character code is ASCII (or Unicode, which is a superset of ASCII). - This is the case for most computer operating systems. PCRE can, how- + PCRE assumes by default that it will run in an environment where the + character code is ASCII (or Unicode, which is a superset of ASCII). + This is the case for most computer operating systems. PCRE can, how- ever, be compiled to run in an EBCDIC environment by adding --enable-ebcdic to the configure command. This setting implies --enable-rebuild-charta- - bles. You should only use it if you know that you are in an EBCDIC - environment (for example, an IBM mainframe operating system). The - --enable-ebcdic option is incompatible with --enable-utf8. + bles. You should only use it if you know that you are in an EBCDIC + environment (for example, an IBM mainframe operating system). The + --enable-ebcdic option is incompatible with --enable-utf. PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT @@ -548,10 +792,26 @@ PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT --enable-pcregrep-libbz2 to the configure command. These options naturally require that the rel- - evant libraries are installed on your system. Configuration will fail + evant libraries are installed on your system. Configuration will fail if they are not. +PCREGREP BUFFER SIZE + + pcregrep uses an internal buffer to hold a "window" on the file it is + scanning, in order to be able to output "before" and "after" lines when + it finds a match. The size of the buffer is controlled by a parameter + whose default value is 20K. The buffer itself is three times this size, + but because of the way it is used for holding "before" lines, the long- + est line that is guaranteed to be processable is the parameter size. + You can change the default parameter value by adding, for example, + + --with-pcregrep-bufsize=50K + + to the configure command. The caller of pcregrep can, however, override + this value by specifying a run-time option. + + PCRETEST OPTION FOR LIBREADLINE SUPPORT If you add @@ -585,7 +845,7 @@ PCRETEST OPTION FOR LIBREADLINE SUPPORT SEE ALSO - pcreapi(3), pcre_config(3). + pcreapi(3), pcre16, pcre_config(3). AUTHOR @@ -597,8 +857,8 @@ AUTHOR REVISION - Last updated: 29 September 2009 - Copyright (c) 1997-2009 University of Cambridge. + Last updated: 07 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -614,13 +874,15 @@ PCRE MATCHING ALGORITHMS This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given sub- ject string. The "standard" algorithm is the one provided by the - pcre_exec() function. This works in the same was as Perl's matching - function, and provides a Perl-compatible matching operation. + pcre_exec() and pcre16_exec() functions. These work in the same was as + Perl's matching function, and provide a Perl-compatible matching opera- + tion. The just-in-time (JIT) optimization that is described in the + pcrejit documentation is compatible with these functions. - An alternative algorithm is provided by the pcre_dfa_exec() function; - this operates in a different way, and is not Perl-compatible. It has - advantages and disadvantages compared with the standard algorithm, and - these are described below. + An alternative algorithm is provided by the pcre_dfa_exec() and + pcre16_dfa_exec() functions; they operate in a different way, and are + not Perl-compatible. This alternative has advantages and disadvantages + compared with the standard algorithm, and these are described below. When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference @@ -748,42 +1010,43 @@ THE ALTERNATIVE MATCHING ALGORITHM 6. Callouts are supported, but the value of the capture_top field is always 1, and the value of the capture_last field is always -1. - 7. The \C escape sequence, which (in the standard algorithm) matches a - single byte, even in UTF-8 mode, is not supported because the alterna- - tive algorithm moves through the subject string one character at a - time, for all active paths through the tree. + 7. The \C escape sequence, which (in the standard algorithm) always + matches a single data unit, even in UTF-8 or UTF-16 modes, is not sup- + ported in these modes, because the alternative algorithm moves through + the subject string one character (not data unit) at a time, for all + active paths through the tree. - 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) - are not supported. (*FAIL) is supported, and behaves like a failing + 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) + are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. ADVANTAGES OF THE ALTERNATIVE ALGORITHM - Using the alternative matching algorithm provides the following advan- + Using the alternative matching algorithm provides the following advan- tages: 1. All possible matches (at a single point in the subject) are automat- - ically found, and in particular, the longest match is found. To find + ically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts. - 2. Because the alternative algorithm scans the subject string just - once, and never needs to backtrack, it is possible to pass very long - subject strings to the matching function in several pieces, checking - for partial matching each time. Although it is possible to do multi- - segment matching using the standard algorithm (pcre_exec()), by retain- - ing partially matched substrings, it is more complicated. The pcrepar- - tial documentation gives details of partial matching and discusses - multi-segment matching. + 2. Because the alternative algorithm scans the subject string just + once, and never needs to backtrack (except for lookbehinds), it is pos- + sible to pass very long subject strings to the matching function in + several pieces, checking for partial matching each time. Although it is + possible to do multi-segment matching using the standard algorithm by + retaining partially matched substrings, it is more complicated. The + pcrepartial documentation gives details of partial matching and dis- + cusses multi-segment matching. DISADVANTAGES OF THE ALTERNATIVE ALGORITHM The alternative algorithm suffers from a number of disadvantages: - 1. It is substantially slower than the standard algorithm. This is - partly because it has to search for all possible matches, but is also + 1. It is substantially slower than the standard algorithm. This is + partly because it has to search for all possible matches, but is also because it is less susceptible to optimization. 2. Capturing parentheses and back references are not supported. @@ -801,8 +1064,8 @@ AUTHOR REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 08 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -812,11 +1075,11 @@ PCREAPI(3) PCREAPI(3) NAME PCRE - Perl-compatible regular expressions - -PCRE NATIVE API - #include + +PCRE NATIVE API BASIC FUNCTIONS + pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); @@ -829,6 +1092,8 @@ PCRE NATIVE API pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); + void pcre_free_study(pcre_extra *extra); + int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); @@ -838,6 +1103,9 @@ PCRE NATIVE API int options, int *ovector, int ovecsize, int *workspace, int wscount); + +PCRE NATIVE API STRING EXTRACTION FUNCTIONS + int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, @@ -869,18 +1137,32 @@ PCRE NATIVE API void pcre_free_substring_list(const char **stringptr); + +PCRE NATIVE API AUXILIARY FUNCTIONS + + pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize); + + void pcre_jit_stack_free(pcre_jit_stack *stack); + + void pcre_assign_jit_stack(pcre_extra *extra, + pcre_jit_callback callback, void *data); + const unsigned char *pcre_maketables(void); int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); - int pcre_info(const pcre *code, int *optptr, int *firstcharptr); - int pcre_refcount(pcre *code, int adjust); int pcre_config(int what, void *where); - char *pcre_version(void); + const char *pcre_version(void); + + int pcre_pattern_to_host_byte_order(pcre *code, + pcre_extra *extra, const unsigned char *tables); + + +PCRE NATIVE API INDIRECTED FUNCTIONS void *(*pcre_malloc)(size_t); @@ -893,46 +1175,80 @@ PCRE NATIVE API int (*pcre_callout)(pcre_callout_block *); +PCRE 8-BIT AND 16-BIT LIBRARIES + + From release 8.30, PCRE can be compiled as a library for handling + 16-bit character strings as well as, or instead of, the original + library that handles 8-bit character strings. To avoid too much compli- + cation, this document describes the 8-bit versions of the functions, + with only occasional references to the 16-bit library. + + The 16-bit functions operate in the same way as their 8-bit counter- + parts; they just use different data types for their arguments and + results, and their names start with pcre16_ instead of pcre_. For every + option that has UTF8 in its name (for example, PCRE_UTF8), there is a + corresponding 16-bit name with UTF8 replaced by UTF16. This facility is + in fact just cosmetic; the 16-bit option names define the same bit val- + ues. + + References to bytes and UTF-8 in this document should be read as refer- + ences to 16-bit data quantities and UTF-16 when using the 16-bit + library, unless specified otherwise. More details of the specific dif- + ferences for the 16-bit library are given in the pcre16 page. + + PCRE API OVERVIEW PCRE has its own native API, which is described in this document. There - are also some wrapper functions that correspond to the POSIX regular - expression API. These are described in the pcreposix documentation. - Both of these APIs define a set of C function calls. A C++ wrapper is - distributed with PCRE. It is documented in the pcrecpp page. + 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 systems the library itself is called libpcre. It - can normally be accessed by adding -lpcre to the command for linking an - application that uses PCRE. The header file defines the macros - PCRE_MAJOR and PCRE_MINOR to contain the major and minor release num- - bers for the library. Applications can use these to include support + The native API C function prototypes are defined in the header file + pcre.h, and on Unix-like systems the (8-bit) library itself is called + libpcre. It can normally be accessed by adding -lpcre to the command + for linking an application that uses PCRE. The header file defines the + macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release + numbers for the library. Applications can use these to include support for different releases of PCRE. In a Windows environment, if you want to statically link an application - program against a non-dll pcre.a file, you must define PCRE_STATIC - before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- + program against a non-dll pcre.a file, you must define PCRE_STATIC + before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. - The functions pcre_compile(), pcre_compile2(), pcre_study(), and - pcre_exec() are used for compiling and matching regular expressions in - a Perl-compatible manner. A sample program that demonstrates the sim- - plest way of using them is provided in the file called pcredemo.c in + The functions pcre_compile(), pcre_compile2(), pcre_study(), and + pcre_exec() are used for compiling and matching regular expressions in + a Perl-compatible manner. A sample program that demonstrates the sim- + plest way of using them is provided in the file called pcredemo.c in the PCRE source distribution. A listing of this program is given in the - pcredemo documentation, and the pcresample documentation describes how + pcredemo documentation, and the pcresample documentation describes how to compile and run it. + Just-in-time compiler support is an optional feature of PCRE that can + be built in appropriate hardware environments. It greatly speeds up the + matching performance of many patterns. Simple programs can easily + request that it be used if available, by setting an option that is + ignored when it is not relevant. More complicated programs might need + to make use of the functions pcre_jit_stack_alloc(), + pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control + the JIT code's memory usage. These functions are discussed in the + pcrejit documentation. + A second matching function, pcre_dfa_exec(), which is not Perl-compati- - ble, is also provided. This uses a different algorithm for the match- - ing. The alternative algorithm finds all possible matches (at a given - point in the subject), and scans the subject just once (unless there - are lookbehind assertions). However, this algorithm does not return - captured substrings. A description of the two matching algorithms and - their advantages and disadvantages is given in the pcrematching docu- + ble, is also provided. This uses a different algorithm for the match- + ing. The alternative algorithm finds all possible matches (at a given + point in the subject), and scans the subject just once (unless there + are lookbehind assertions). However, this algorithm does not return + captured substrings. A description of the two matching algorithms and + their advantages and disadvantages is given in the pcrematching docu- mentation. - In addition to the main compiling and matching functions, there are + In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by pcre_exec(). They are: @@ -947,103 +1263,106 @@ PCRE 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; pcre_info() is an obsolete version that returns only - some of the available information, but is retained for backwards com- - patibility. The function pcre_version() returns a pointer to a string - containing the version of PCRE and its date of release. + The function pcre_fullinfo() is used to find out information about a + compiled pattern. The function pcre_version() returns a pointer to a + string containing the version of PCRE and its date of release. - The function pcre_refcount() maintains a reference count in a data - block containing a compiled pattern. This is provided for the benefit + The function pcre_refcount() maintains a reference count in a data + block containing a compiled pattern. This is provided for the benefit of object-oriented applications. - The global variables pcre_malloc and pcre_free initially contain the - entry points of the standard malloc() and free() functions, respec- + The global variables pcre_malloc and pcre_free initially contain the + entry points of the standard malloc() and free() functions, respec- tively. PCRE calls the memory management functions via these variables, - so a calling program can replace them if it wishes to intercept the + so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions. - The global variables pcre_stack_malloc and pcre_stack_free are also - indirections to memory management functions. These special functions - are used only when PCRE is compiled to use the heap for remembering + The global variables pcre_stack_malloc and pcre_stack_free are also + indirections to memory management functions. These special functions + are used only when PCRE is compiled to use the heap for remembering data, instead of recursive function calls, when running the pcre_exec() - function. See the pcrebuild documentation for details of how to do - this. It is a non-standard way of building PCRE, for use in environ- - ments that have limited stacks. Because of the greater use of memory - management, it runs more slowly. Separate functions are provided so - that special-purpose external code can be used for this case. When - used, these functions are always called in a stack-like manner (last - obtained, first freed), and always for memory blocks of the same size. - There is a discussion about PCRE's stack usage in the pcrestack docu- + function. See the pcrebuild documentation for details of how to do + this. It is a non-standard way of building PCRE, for use in environ- + ments that have limited stacks. Because of the greater use of memory + management, it runs more slowly. Separate functions are provided so + that special-purpose external code can be used for this case. When + used, these functions are always called in a stack-like manner (last + obtained, first freed), and always for memory blocks of the same size. + There is a discussion about PCRE's stack usage in the pcrestack docu- mentation. The global variable pcre_callout initially contains NULL. It can be set - by the caller to a "callout" function, which PCRE will then call at - specified points during a matching operation. Details are given in the + by the caller to a "callout" function, which PCRE will then call at + specified points during a matching operation. Details are given in the pcrecallout documentation. NEWLINES - PCRE supports five different conventions for indicating line breaks in - strings: a single CR (carriage return) character, a single LF (line- + PCRE supports five different conventions for indicating line breaks in + strings: a single CR (carriage return) character, a single LF (line- feed) character, the two-character sequence CRLF, any of the three pre- - ceding, or any Unicode newline sequence. The Unicode newline sequences - are the three just mentioned, plus the single characters VT (vertical - tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line + ceding, or any Unicode newline sequence. The Unicode newline sequences + are the three just mentioned, plus the single characters VT (vertical + tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). - Each of the first three conventions is used by at least one operating - system as its standard newline sequence. When PCRE is built, a default - can be specified. The default default is LF, which is the Unix stan- - dard. When PCRE is run, the default can be overridden, either when a + Each of the first three conventions is used by at least one operating + system as its standard newline sequence. When PCRE is built, a default + can be specified. The default default is LF, which is the Unix stan- + dard. When PCRE is run, the default can be overridden, either when a pattern is compiled, or when it is matched. At compile time, the newline convention can be specified by the options - argument of pcre_compile(), or it can be specified by special text at + argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences. In the PCRE documentation the word "newline" is used to mean "the char- - acter or pair of characters that indicate a line break". The choice of - newline convention affects the handling of the dot, circumflex, and + acter or pair of characters that indicate a line break". The choice of + newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when - CRLF is a recognized line ending sequence, the match position advance- + CRLF is a recognized line ending sequence, the match position advance- ment for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below. - The choice of newline convention does not affect the interpretation of - the \n or \r escape sequences, nor does it affect what \R matches, + The choice of newline convention does not affect the interpretation of + the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options. MULTITHREADING - The PCRE functions can be used in multi-threading applications, with + The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the callout function pointed to by pcre_callout, are shared by all threads. - The compiled form of a regular expression is not altered during match- + The compiled form of a regular expression is not altered during match- ing, so the same compiled pattern can safely be used by several threads at once. + If the just-in-time optimization feature is being used, it needs sepa- + rate memory stack areas for each thread. See the pcrejit documentation + for more details. + SAVING PRECOMPILED PATTERNS FOR LATER USE The compiled form of a regular expression can be saved and re-used at a - later time, possibly by a different program, and even on a host other - than the one on which it was compiled. Details are given in the - pcreprecompile documentation. However, compiling a regular expression - with one version of PCRE for use with a different version is not guar- - anteed to work and may cause crashes. + later time, possibly by a different program, and even on a host other + than the one on which it was compiled. Details are given in the + pcreprecompile documentation, which includes a description of the + pcre_pattern_to_host_byte_order() function. However, compiling a regu- + lar expression with one version of PCRE for use with a different ver- + sion is not guaranteed to work and may cause crashes. CHECKING BUILD-TIME OPTIONS @@ -1057,72 +1376,99 @@ CHECKING BUILD-TIME OPTIONS The first argument for pcre_config() is an integer, specifying which information is required; the second argument is a pointer to a variable - into which the information is placed. The following information is + into which the information is placed. The returned value is zero on + success, or the negative error code PCRE_ERROR_BADOPTION if the value + in the first argument is not recognized. The following information is available: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is avail- - able; otherwise it is set to zero. + able; otherwise it is set to zero. If this option is given to the + 16-bit version of this function, pcre16_config(), the result is + PCRE_ERROR_BADOPTION. + + PCRE_CONFIG_UTF16 + + The output is an integer that is set to one if UTF-16 support is avail- + able; otherwise it is set to zero. This value should normally be given + to the 16-bit version of this function, pcre16_config(). If it is given + to the 8-bit version of this function, the result is PCRE_ERROR_BADOP- + TION. PCRE_CONFIG_UNICODE_PROPERTIES The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero. + PCRE_CONFIG_JIT + + The output is an integer that is set to one if support for just-in-time + compiling is available; otherwise it is set to zero. + + PCRE_CONFIG_JITTARGET + + The output is a pointer to a zero-terminated "const char *" string. If + JIT support is available, the string contains the name of the architec- + ture for which the JIT compiler is configured, for example "x86 32bit + (little endian + unaligned)". If JIT support is not available, the + result is NULL. + PCRE_CONFIG_NEWLINE - The output is an integer whose value specifies the default character - sequence that is recognized as meaning "newline". The four values that + The output is an integer whose value specifies the default character + sequence that is recognized as meaning "newline". The four values that are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF, - and -1 for ANY. Though they are derived from ASCII, the same values + and -1 for ANY. Though they are derived from ASCII, the same values are returned in EBCDIC environments. The default should normally corre- spond to the standard sequence for your operating system. PCRE_CONFIG_BSR The output is an integer whose value indicates what character sequences - the \R escape sequence matches by default. A value of 0 means that \R - matches any Unicode line ending sequence; a value of 1 means that \R + the \R escape sequence matches by default. A value of 0 means that \R + matches any Unicode line ending sequence; a value of 1 means that \R matches only CR, LF, or CRLF. The default can be overridden when a pat- tern is compiled or matched. PCRE_CONFIG_LINK_SIZE - The output is an integer that contains the number of bytes used for - internal linkage in compiled regular expressions. The value is 2, 3, or - 4. Larger values allow larger regular expressions to be compiled, at - the expense of slower matching. The default value of 2 is sufficient - for all but the most massive patterns, since it allows the compiled - pattern to be up to 64K in size. + The output is an integer that contains the number of bytes used for + internal linkage in compiled regular expressions. For the 8-bit + library, the value can be 2, 3, or 4. For the 16-bit library, the value + is either 2 or 4 and is still a number of bytes. The default value of 2 + is sufficient for all but the most massive patterns, since it allows + the compiled pattern to be up to 64K in size. Larger values allow + larger regular expressions to be compiled, at the expense of slower + matching. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD - The output is an integer that contains the threshold above which the - POSIX interface uses malloc() for output vectors. Further details are + The output is an integer that contains the threshold above which the + POSIX interface uses malloc() for output vectors. Further details are given in the pcreposix documentation. PCRE_CONFIG_MATCH_LIMIT - The output is a long integer that gives the default limit for the num- - ber of internal matching function calls in a pcre_exec() execution. + The output is a long integer that gives the default limit for the num- + ber of internal matching function calls in a pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_MATCH_LIMIT_RECURSION The output is a long integer that gives the default limit for the depth - of recursion when calling the internal matching function in a - pcre_exec() execution. Further details are given with pcre_exec() + of recursion when calling the internal matching function in a + pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_STACKRECURSE - The output is an integer that is set to one if internal recursion when + The output is an integer that is set to one if internal recursion when running pcre_exec() is implemented by recursive function calls that use - the stack to remember their state. This is the usual way that PCRE is + the stack to remember their state. This is the usual way that PCRE is compiled. The output is zero if PCRE was compiled to use blocks of data - on the heap instead of recursive function calls. In this case, - pcre_stack_malloc and pcre_stack_free are called to manage memory + on the heap instead of recursive function calls. In this case, + pcre_stack_malloc and pcre_stack_free are called to manage memory blocks on the heap, thus avoiding the use of the stack. @@ -1139,65 +1485,65 @@ COMPILING A PATTERN Either of the functions pcre_compile() or pcre_compile2() can be called to compile a pattern into an internal form. The only difference between - the two interfaces is that pcre_compile2() has an additional argument, - errorcodeptr, via which a numerical error code can be returned. To - avoid too much repetition, we refer just to pcre_compile() below, but + the two interfaces is that pcre_compile2() has an additional argument, + errorcodeptr, via which a numerical error code can be returned. To + avoid too much repetition, we refer just to pcre_compile() below, but the information applies equally to pcre_compile2(). The pattern is a C string terminated by a binary zero, and is passed in - the pattern argument. A pointer to a single block of memory that is - obtained via pcre_malloc is returned. This contains the compiled code + the pattern argument. A pointer to a single block of memory that is + obtained via pcre_malloc is returned. This contains the compiled code and related data. The pcre type is defined for the returned block; this is a typedef for a structure whose contents are not externally defined. It is up to the caller to free the memory (via pcre_free) when it is no longer required. - Although the compiled code of a PCRE regex is relocatable, that is, it + Although the compiled code of a PCRE regex is relocatable, that is, it does not depend on memory location, the complete pcre data block is not - fully relocatable, because it may contain a copy of the tableptr argu- + fully relocatable, because it may contain a copy of the tableptr argu- ment, which is an address (see below). The options argument contains various bit settings that affect the com- - pilation. It should be zero if no options are required. The available - options are described below. Some of them (in particular, those that - are compatible with Perl, but some others as well) can also be set and - unset from within the pattern (see the detailed description in the - pcrepattern documentation). For those options that can be different in - different parts of the pattern, the contents of the options argument + pilation. It should be zero if no options are required. The available + options are described below. Some of them (in particular, those that + are compatible with Perl, but some others as well) can also be set and + unset from within the pattern (see the detailed description in the + pcrepattern documentation). For those options that can be different in + different parts of the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The - PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and - PCRE_NO_START_OPT options can be set at the time of matching as well as - at compile time. + PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and + PCRE_NO_START_OPTIMIZE options can be set at the time of matching as + well as at compile time. If errptr is NULL, pcre_compile() returns NULL immediately. Otherwise, - if compilation of a pattern fails, pcre_compile() returns NULL, and + if compilation of a pattern fails, pcre_compile() returns NULL, and sets the variable pointed to by errptr to point to a textual error mes- sage. This is a static string that is part of the library. You must not - try to free it. The offset from the start of the pattern to the byte - that was being processed when the error was discovered is placed in the - variable pointed to by erroffset, which must not be NULL. If it is, an - immediate error is given. Some errors are not detected until checks are - carried out when the whole pattern has been scanned; in this case the - offset is set to the end of the pattern. + try to free it. Normally, the offset from the start of the pattern to + the byte that was being processed when the error was discovered is + placed in the variable pointed to by erroffset, which must not be NULL + (if it is, an immediate error is given). However, for an invalid UTF-8 + string, the offset is that of the first byte of the failing character. + Some errors are not detected until the whole pattern has been scanned; + in these cases, the offset passed back is the length of the pattern. Note that the offset is in bytes, not characters, even in UTF-8 mode. - It may point into the middle of a UTF-8 character (for example, when - PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string). + It may sometimes point into the middle of a UTF-8 character. - If pcre_compile2() is used instead of pcre_compile(), and the error- - codeptr argument is not NULL, a non-zero error code number is returned - via this argument in the event of an error. This is in addition to the + If pcre_compile2() is used instead of pcre_compile(), and the error- + codeptr argument is not NULL, a non-zero error code number is returned + via this argument in the event of an error. This is in addition to the textual error message. Error codes and messages are listed below. - If the final argument, tableptr, is NULL, PCRE uses a default set of - character tables that are built when PCRE is compiled, using the - default C locale. Otherwise, tableptr must be an address that is the - result of a call to pcre_maketables(). This value is stored with the - compiled pattern, and used again by pcre_exec(), unless another table + If the final argument, tableptr, is NULL, PCRE uses a default set of + character tables that are built when PCRE is compiled, using the + default C locale. Otherwise, tableptr must be an address that is the + result of a call to pcre_maketables(). This value is stored with the + compiled pattern, and used again by pcre_exec(), unless another table pointer is passed to it. For more discussion, see the section on locale support below. - This code fragment shows a typical straightforward call to pcre_com- + This code fragment shows a typical straightforward call to pcre_com- pile(): pcre *re; @@ -1210,147 +1556,161 @@ COMPILING A PATTERN &erroffset, /* for error offset */ NULL); /* use default character tables */ - The following names for option bits are defined in the pcre.h header + The following names for option bits are defined in the pcre.h header file: PCRE_ANCHORED If this bit is set, the pattern is forced to be "anchored", that is, it - is constrained to match only at the first matching point in the string - that is being searched (the "subject string"). This effect can also be - achieved by appropriate constructs in the pattern itself, which is the + is constrained to match only at the first matching point in the string + that is being searched (the "subject string"). This effect can also be + achieved by appropriate constructs in the pattern itself, which is the only way to do it in Perl. PCRE_AUTO_CALLOUT If this bit is set, pcre_compile() automatically inserts callout items, - all with number 255, before each pattern item. For discussion of the + all with number 255, before each pattern item. For discussion of the callout facility, see the pcrecallout documentation. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape - sequence matches. The choice is either to match only CR, LF, or CRLF, + sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by set- ting an option when a compiled pattern is matched. PCRE_CASELESS - If this bit is set, letters in the pattern match both upper and lower - case letters. It is equivalent to Perl's /i option, and it can be - changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE - always understands the concept of case for characters whose values are - less than 128, so caseless matching is always possible. For characters - with higher values, the concept of case is supported if PCRE is com- - piled with Unicode property support, but not otherwise. If you want to - use caseless matching for characters 128 and above, you must ensure - that PCRE is compiled with Unicode property support as well as with + If this bit is set, letters in the pattern match both upper and lower + case letters. It is equivalent to Perl's /i option, and it can be + changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE + always understands the concept of case for characters whose values are + less than 128, so caseless matching is always possible. For characters + with higher values, the concept of case is supported if PCRE is com- + piled with Unicode property support, but not otherwise. If you want to + use caseless matching for characters 128 and above, you must ensure + that PCRE is compiled with Unicode property support as well as with UTF-8 support. PCRE_DOLLAR_ENDONLY - If this bit is set, a dollar metacharacter in the pattern matches only - at the end of the subject string. Without this option, a dollar also - matches immediately before a newline at the end of the string (but not - before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored - if PCRE_MULTILINE is set. There is no equivalent to this option in + If this bit is set, a dollar metacharacter in the pattern matches only + at the end of the subject string. Without this option, a dollar also + matches immediately before a newline at the end of the string (but not + before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored + if PCRE_MULTILINE is set. There is no equivalent to this option in Perl, and no way to set it within a pattern. PCRE_DOTALL - If this bit is set, a dot metacharacter in the pattern matches a char- + If this bit is set, a dot metacharacter in the pattern matches a char- acter of any value, including one that indicates a newline. However, it - only ever matches one character, even if newlines are coded as CRLF. - Without this option, a dot does not match when the current position is + only ever matches one character, even if newlines are coded as CRLF. + Without this option, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can - be changed within a pattern by a (?s) option setting. A negative class + be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of the set- ting of this option. PCRE_DUPNAMES - If this bit is set, names used to identify capturing subpatterns need + If this bit is set, names used to identify capturing subpatterns need not be unique. This can be helpful for certain types of pattern when it - is known that only one instance of the named subpattern can ever be - matched. There are more details of named subpatterns below; see also + is known that only one instance of the named subpattern can ever be + matched. There are more details of named subpatterns below; see also the pcrepattern documentation. PCRE_EXTENDED - If this bit is set, whitespace data characters in the pattern are - totally ignored except when escaped or inside a character class. White- + If this bit is set, white space data characters in the pattern are + totally ignored except when escaped or inside a character class. White space does not include the VT character (code 11). In addition, charac- ters between an unescaped # outside a character class and the next new- - line, inclusive, are also ignored. This is equivalent to Perl's /x - option, and it can be changed within a pattern by a (?x) option set- + line, inclusive, are also ignored. This is equivalent to Perl's /x + option, and it can be changed within a pattern by a (?x) option set- ting. - Which characters are interpreted as newlines is controlled by the - options passed to pcre_compile() or by a special sequence at the start - of the pattern, as described in the section entitled "Newline conven- + Which characters are interpreted as newlines is controlled by the + options passed to pcre_compile() or by a special sequence at the start + of the pattern, as described in the section entitled "Newline conven- tions" in the pcrepattern documentation. Note that the end of this type - of comment is a literal newline sequence in the pattern; escape + of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. - This option makes it possible to include comments inside complicated - patterns. Note, however, that this applies only to data characters. - Whitespace characters may never appear within special character + This option makes it possible to include comments inside complicated + patterns. Note, however, that this applies only to data characters. + White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that intro- duces a conditional subpattern. PCRE_EXTRA - This option was invented in order to turn on additional functionality - of PCRE that is incompatible with Perl, but it is currently of very - little use. When set, any backslash in a pattern that is followed by a - letter that has no special meaning causes an error, thus reserving - these combinations for future expansion. By default, as in Perl, a - backslash followed by a letter with no special meaning is treated as a + This option was invented in order to turn on additional functionality + of PCRE that is incompatible with Perl, but it is currently of very + little use. When set, any backslash in a pattern that is followed by a + letter that has no special meaning causes an error, thus reserving + these combinations for future expansion. By default, as in Perl, a + backslash followed by a letter with no special meaning is treated as a literal. (Perl can, however, be persuaded to give an error for this, by - running it with the -w option.) There are at present no other features - controlled by this option. It can also be set by a (?X) option setting + running it with the -w option.) There are at present no other features + controlled by this option. It can also be set by a (?X) option setting within a pattern. PCRE_FIRSTLINE - If this option is set, an unanchored pattern is required to match - before or at the first newline in the subject string, though the + If this option is set, an unanchored pattern is required to match + before or at the first newline in the subject string, though the matched text may continue over the newline. PCRE_JAVASCRIPT_COMPAT If this option is set, PCRE's behaviour is changed in some ways so that - it is compatible with JavaScript rather than Perl. The changes are as + it is compatible with JavaScript rather than Perl. The changes are as follows: - (1) A lone closing square bracket in a pattern causes a compile-time - error, because this is illegal in JavaScript (by default it is treated + (1) A lone closing square bracket in a pattern causes a compile-time + error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set. - (2) At run time, a back reference to an unset subpattern group matches - an empty string (by default this causes the current matching alterna- - tive to fail). A pattern such as (\1)(a) succeeds when this option is - set (assuming it can find an "a" in the subject), whereas it fails by + (2) At run time, a back reference to an unset subpattern group matches + an empty string (by default this causes the current matching alterna- + tive to fail). A pattern such as (\1)(a) succeeds when this option is + set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. + (3) \U matches an upper case "U" character; by default \U causes a com- + pile time error (Perl uses \U to upper case subsequent characters). + + (4) \u matches a lower case "u" character unless it is followed by four + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, \u causes a compile time error (Perl + uses it to upper case the following character). + + (5) \x matches a lower case "x" character unless it is followed by two + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, as in Perl, a hexadecimal number is + always expected after \x, but it may have zero, one, or two digits (so, + for example, \xz matches a binary zero character followed by z). + PCRE_MULTILINE - By default, PCRE treats the subject string as consisting of a single - line of characters (even if it actually contains newlines). The "start - of line" metacharacter (^) matches only at the start of the string, - while the "end of line" metacharacter ($) matches only at the end of + By default, PCRE treats the subject string as consisting of a single + line of characters (even if it actually contains newlines). The "start + of line" metacharacter (^) matches only at the start of the string, + while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as Perl. - When PCRE_MULTILINE it is set, the "start of line" and "end of line" - constructs match immediately following or immediately before internal - newlines in the subject string, respectively, as well as at the very - start and end. This is equivalent to Perl's /m option, and it can be + When PCRE_MULTILINE it is set, the "start of line" and "end of line" + constructs match immediately following or immediately before internal + newlines in the subject string, respectively, as well as at the very + start and end. This is equivalent to Perl's /m option, and it can be changed within a pattern by a (?m) option setting. If there are no new- - lines in a subject string, or no occurrences of ^ or $ in a pattern, + lines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. PCRE_NEWLINE_CR @@ -1359,32 +1719,32 @@ COMPILING A PATTERN PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY - These options override the default newline definition that was chosen - when PCRE was built. Setting the first or the second specifies that a - newline is indicated by a single character (CR or LF, respectively). - Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the - two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies + These options override the default newline definition that was chosen + when PCRE was built. Setting the first or the second specifies that a + newline is indicated by a single character (CR or LF, respectively). + Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the + two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting - PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be + PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, - plus the single characters VT (vertical tab, U+000B), FF (formfeed, - U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS - (paragraph separator, U+2029). The last two are recognized only in - UTF-8 mode. + plus the single characters VT (vertical tab, U+000B), FF (form feed, + U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS + (paragraph separator, U+2029). For the 8-bit library, the last two are + recognized only in UTF-8 mode. - The newline setting in the options word uses three bits that are + The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are - used (default plus the five values above). This means that if you set - more than one newline option, the combination may or may not be sensi- + used (default plus the five values above). This means that if you set + more than one newline option, the combination may or may not be sensi- ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to - PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and + PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error. - The only time that a line break in a pattern is specially recognized - when compiling is when PCRE_EXTENDED is set. CR and LF are whitespace - characters, and so are ignored in this mode. Also, an unescaped # out- - side a character class indicates a comment that lasts until after the - next line break sequence. In other circumstances, line break sequences + The only time that a line break in a pattern is specially recognized + when compiling is when PCRE_EXTENDED is set. CR and LF are white space + characters, and so are ignored in this mode. Also, an unescaped # out- + side a character class indicates a comment that lasts until after the + next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data. The newline option that is set at compile time becomes the default that @@ -1393,66 +1753,67 @@ COMPILING A PATTERN PCRE_NO_AUTO_CAPTURE If this option is set, it disables the use of numbered capturing paren- - theses in the pattern. Any opening parenthesis that is not followed by - ? behaves as if it were followed by ?: but named parentheses can still - be used for capturing (and they acquire numbers in the usual way). + theses in the pattern. Any opening parenthesis that is not followed by + ? behaves as if it were followed by ?: but named parentheses can still + be used for capturing (and they acquire numbers in the usual way). There is no equivalent of this option in Perl. NO_START_OPTIMIZE - This is an option that acts at matching time; that is, it is really an - option for pcre_exec() or pcre_dfa_exec(). If it is set at compile - time, it is remembered with the compiled pattern and assumed at match- - ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE + This is an option that acts at matching time; that is, it is really an + option for pcre_exec() or pcre_dfa_exec(). If it is set at compile + time, it is remembered with the compiled pattern and assumed at match- + ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE below. PCRE_UCP - This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, - \w, and some of the POSIX character classes. By default, only ASCII - characters are recognized, but if PCRE_UCP is set, Unicode properties - are used instead to classify characters. More details are given in the - section on generic character types in the pcrepattern page. If you set - PCRE_UCP, matching one of the items it affects takes much longer. The - option is available only if PCRE has been compiled with Unicode prop- + This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, + \w, and some of the POSIX character classes. By default, only ASCII + characters are recognized, but if PCRE_UCP is set, Unicode properties + are used instead to classify characters. More details are given in the + section on generic character types in the pcrepattern page. If you set + PCRE_UCP, matching one of the items it affects takes much longer. The + option is available only if PCRE has been compiled with Unicode prop- erty support. PCRE_UNGREEDY - This option inverts the "greediness" of the quantifiers so that they - are not greedy by default, but become greedy if followed by "?". It is - not compatible with Perl. It can also be set by a (?U) option setting + This option inverts the "greediness" of the quantifiers so that they + are not greedy by default, but become greedy if followed by "?". It is + not compatible with Perl. It can also be set by a (?U) option setting within the pattern. PCRE_UTF8 - This option causes PCRE to regard both the pattern and the subject as - strings of UTF-8 characters instead of single-byte character strings. - However, it is available only when PCRE is built to include UTF-8 sup- - port. If not, the use of this option provokes an error. Details of how - this option changes the behaviour of PCRE are given in the section on - UTF-8 support in the main pcre page. + This option causes PCRE to regard both the pattern and the subject as + strings of UTF-8 characters instead of single-byte strings. However, it + is available only when PCRE is built to include UTF support. If not, + the use of this option provokes an error. Details of how this option + changes the behaviour of PCRE are given in the pcreunicode page. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is automatically checked. There is a discussion about the validity of - UTF-8 strings in the main pcre page. If an invalid UTF-8 sequence of - bytes is found, pcre_compile() returns an error. If you already know - that your pattern is valid, and you want to skip this check for perfor- - mance reasons, you can set the PCRE_NO_UTF8_CHECK option. When it is - set, the effect of passing an invalid UTF-8 string as a pattern is - undefined. It may cause your program to crash. Note that this option - can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress the - UTF-8 validity checking of subject strings. + UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is + found, pcre_compile() returns an error. If you already know that your + pattern is valid, and you want to skip this check for performance rea- + sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the + effect of passing an invalid UTF-8 string as a pattern is undefined. It + may cause your program to crash. Note that this option can also be + passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity + checking of subject strings. COMPILATION ERROR CODES The following table lists the error codes than may be returned by pcre_compile2(), along with the error messages that may be returned by - both compiling functions. As PCRE has developed, some error codes have - fallen out of use. To avoid confusion, they have not been re-used. + both compiling functions. Note that error messages are always 8-bit + ASCII strings, even in 16-bit mode. As PCRE has developed, some error + codes have fallen out of use. To avoid confusion, they have not been + re-used. 0 no error 1 \ at end of pattern @@ -1486,26 +1847,26 @@ COMPILATION ERROR CODES 29 (?R or (?[+-]digits must be followed by ) 30 unknown POSIX class name 31 POSIX collating elements are not supported - 32 this version of PCRE is not compiled with PCRE_UTF8 support + 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] 34 character value in \x{...} sequence is too large 35 invalid condition (?(0) 36 \C not allowed in lookbehind assertion - 37 PCRE does not support \L, \l, \N, \U, or \u + 37 PCRE does not support \L, \l, \N{name}, \U, or \u 38 number after (?C is > 255 39 closing ) for (?C expected 40 recursive call could loop indefinitely 41 unrecognized character after (?P 42 syntax error in subpattern name (missing terminator) 43 two named subpatterns have the same name - 44 invalid UTF-8 string + 44 invalid UTF-8 string (specifically UTF-8) 45 support for \P, \p, and \X has not been compiled 46 malformed \P or \p sequence 47 unknown property name after \P or \p 48 subpattern name is too long (maximum 32 characters) 49 too many named subpatterns (maximum 10000) 50 [this code is not in use] - 51 octal value is greater than \377 (not in UTF-8 mode) + 51 octal value is greater than \377 in 8-bit non-UTF-8 mode 52 internal error: overran compiling workspace 53 internal error: previously-checked referenced subpattern not found @@ -1524,7 +1885,17 @@ COMPILATION ERROR CODES 65 different names for subpatterns of the same number are not allowed 66 (*MARK) must have an argument - 67 this version of PCRE is not compiled with PCRE_UCP support + 67 this version of PCRE is not compiled with Unicode property + support + 68 \c must be followed by an ASCII character + 69 \k is not followed by a braced, angle-bracketed, or quoted name + 70 internal error: unknown opcode in find_fixedlength() + 71 \N is not supported in a class + 72 too many forward references + 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff) + 74 invalid UTF-16 string (specifically UTF-16) + 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) + 76 character value in \u.... sequence is too large The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. @@ -1553,8 +1924,26 @@ STUDYING A PATTERN wants to pass any of the other fields to pcre_exec() or pcre_dfa_exec(), it must set up its own pcre_extra block. - The second argument of pcre_study() contains option bits. At present, - no options are defined, and this argument should always be zero. + The second argument of pcre_study() contains option bits. There are + three options: + + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + If any of these are set, and the just-in-time compiler is available, + the pattern is further compiled into machine code that executes much + faster than the pcre_exec() interpretive matching function. If the + just-in-time compiler is not available, these options are ignored. All + other bits in the options argument must be zero. + + JIT compilation is a heavyweight optimization. It can take some time + for patterns to be analyzed, and for one-off matches and simple pat- + terns the benefit of faster execution might be offset by a much slower + study time. Not all patterns can be optimized by the JIT compiler. For + those that cannot be handled, matching automatically falls back to the + pcre_exec() interpreter. For more details, see the pcrejit documenta- + tion. The third argument for pcre_study() is a pointer for an error message. If studying succeeds (even if no data is returned), the variable it @@ -1563,13 +1952,29 @@ STUDYING A PATTERN must not try to free it. You should test the error pointer for NULL after calling pcre_study(), to be sure that it has run successfully. - This is a typical call to pcre_study(): + When you are finished with a pattern, you can free the memory used for + the study data by calling pcre_free_study(). This function was added to + the API for release 8.20. For earlier versions, the memory could be + freed with pcre_free(), just like the pattern itself. This will still + work in cases where JIT optimization is not used, but it is advisable + to change to the new function when convenient. - pcre_extra *pe; - pe = pcre_study( + This is a typical way in which pcre_study() is used (except that in a + real application there should be tests for errors): + + int rc; + pcre *re; + pcre_extra *sd; + re = pcre_compile("pattern", 0, &error, &erroroffset, NULL); + sd = pcre_study( re, /* result of pcre_compile() */ - 0, /* no options exist */ + 0, /* no options */ &error); /* set to NULL or points to a message */ + rc = pcre_exec( /* see below for details of pcre_exec() options */ + re, sd, "subject", 7, 0, 0, ovector, 30); + ... + pcre_free_study(sd); + pcre_free(re); Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This @@ -1582,70 +1987,73 @@ STUDYING A PATTERN Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at - which to start matching. + which to start matching. (In 16-bit mode, the bitmap is used for 16-bit + values less than 256.) - The two optimizations just described can be disabled by setting the - PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or - pcre_dfa_exec(). You might want to do this if your pattern contains - callouts or (*MARK), and you want to make use of these facilities in - cases where matching fails. See the discussion of PCRE_NO_START_OPTI- - MIZE below. + These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), + and the information is also used by the JIT compiler. The optimiza- + tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option when + calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execu- + tion is also disabled. You might want to do this if your pattern con- + tains callouts or (*MARK) and you want to make use of these facilities + in cases where matching fails. See the discussion of + PCRE_NO_START_OPTIMIZE below. LOCALE SUPPORT - PCRE handles caseless matching, and determines whether characters are - letters, digits, or whatever, by reference to a set of tables, indexed - by character value. When running in UTF-8 mode, this applies only to - characters with codes less than 128. By default, higher-valued codes + PCRE handles caseless matching, and determines whether characters are + letters, digits, or whatever, by reference to a set of tables, indexed + by character value. When running in UTF-8 mode, this applies only to + characters with codes less than 128. By default, higher-valued codes never match escapes such as \w or \d, but they can be tested with \p if - PCRE is built with Unicode character property support. Alternatively, - the PCRE_UCP option can be set at compile time; this causes \w and + PCRE is built with Unicode character property support. Alternatively, + the PCRE_UCP option can be set at compile time; this causes \w and friends to use Unicode property support instead of built-in tables. The use of locales with Unicode is discouraged. If you are handling charac- - ters with codes greater than 128, you should either use UTF-8 and Uni- + ters with codes greater than 128, you should either use UTF-8 and Uni- code, or use locales, but not try to mix the two. - PCRE contains an internal set of tables that are used when the final - argument of pcre_compile() is NULL. These are sufficient for many + PCRE contains an internal set of tables that are used when the final + argument of pcre_compile() is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII char- acters. However, when PCRE is built, it is possible to cause the inter- nal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different. - The internal tables can always be overridden by tables supplied by the + The internal tables can always be overridden by tables supplied by the application that calls PCRE. These may be created in a different locale - from the default. As more and more applications change to using Uni- + from the default. As more and more applications change to using Uni- code, the need for this locale support is expected to die away. - External tables are built by calling the pcre_maketables() function, - which has no arguments, in the relevant locale. The result can then be - passed to pcre_compile() or pcre_exec() as often as necessary. For - example, to build and use tables that are appropriate for the French - locale (where accented characters with values greater than 128 are + External tables are built by calling the pcre_maketables() function, + which has no arguments, in the relevant locale. The result can then be + passed to pcre_compile() or pcre_exec() as often as necessary. For + example, to build and use tables that are appropriate for the French + locale (where accented characters with values greater than 128 are treated as letters), the following code could be used: setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); re = pcre_compile(..., tables); - The locale name "fr_FR" is used on Linux and other Unix-like systems; + The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french". - When pcre_maketables() runs, the tables are built in memory that is - obtained via pcre_malloc. It is the caller's responsibility to ensure - that the memory containing the tables remains available for as long as + When pcre_maketables() runs, the tables are built in memory that is + obtained via pcre_malloc. It is the caller's responsibility to ensure + that the memory containing the tables remains available for as long as it is needed. The pointer that is passed to pcre_compile() is saved with the compiled - pattern, and the same tables are used via this pointer by pcre_study() + pattern, and the same tables are used via this pointer by pcre_study() and normally also by pcre_exec(). Thus, by default, for any single pat- tern, compilation, studying and matching all happen in the same locale, but different patterns can be compiled in different locales. - It is possible to pass a table pointer or NULL (indicating the use of - the internal tables) to pcre_exec(). Although not intended for this - purpose, this facility could be used to match a pattern in a different + It is possible to pass a table pointer or NULL (indicating the use of + the internal tables) to pcre_exec(). Although not intended for this + purpose, this facility could be used to match a pattern in a different locale from the one in which it was compiled. Passing table pointers at run time is discussed below in the section on matching a pattern. @@ -1655,32 +2063,35 @@ INFORMATION ABOUT A PATTERN int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); - The pcre_fullinfo() function returns information about a compiled pat- - tern. It replaces the obsolete pcre_info() function, which is neverthe- - less retained for backwards compability (and is documented below). + The pcre_fullinfo() function returns information about a compiled pat- + tern. It replaces the pcre_info() function, which was removed from the + library at version 8.30, after more than 10 years of obsolescence. - The first argument for pcre_fullinfo() is a pointer to the compiled - pattern. The second argument is the result of pcre_study(), or NULL if - the pattern was not studied. The third argument specifies which piece - of information is required, and the fourth argument is a pointer to a - variable to receive the data. The yield of the function is zero for + The first argument for pcre_fullinfo() is a pointer to the compiled + pattern. The second argument is the result of pcre_study(), or NULL if + the pattern was not studied. The third argument specifies which piece + of information is required, and the fourth argument is a pointer to a + variable to receive the data. The yield of the function is zero for success, or one of the following negative numbers: - PCRE_ERROR_NULL the argument code was NULL - the argument where was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found - PCRE_ERROR_BADOPTION the value of what was invalid + PCRE_ERROR_NULL the argument code was NULL + the argument where was NULL + PCRE_ERROR_BADMAGIC the "magic number" was not found + PCRE_ERROR_BADENDIANNESS the pattern was compiled with different + endianness + PCRE_ERROR_BADOPTION the value of what was invalid - The "magic number" is placed at the start of each compiled pattern as - an simple check against passing an arbitrary memory pointer. Here is a - typical call of pcre_fullinfo(), to obtain the length of the compiled - pattern: + The "magic number" is placed at the start of each compiled pattern as + an simple check against passing an arbitrary memory pointer. The endi- + anness error can occur if a compiled pattern is saved and reloaded on a + different host. Here is a typical call of pcre_fullinfo(), to obtain + the length of the compiled pattern: int rc; size_t length; rc = pcre_fullinfo( re, /* result of pcre_compile() */ - pe, /* result of pcre_study(), or NULL */ + sd, /* result of pcre_study(), or NULL */ PCRE_INFO_SIZE, /* what is required */ &length); /* where to put the data */ @@ -1708,13 +2119,17 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_FIRSTBYTE - Return information about the first byte of any matched string, for a - non-anchored pattern. The fourth argument should point to an int vari- - able. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name - is still recognized for backwards compatibility.) + Return information about the first data unit of any matched string, for + a non-anchored pattern. (The name of this option refers to the 8-bit + library, where data units are bytes.) The fourth argument should point + to an int variable. - If there is a fixed first byte, for example, from a pattern such as - (cat|cow|coyote), its value is returned. Otherwise, if either + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), its value is returned. In the 8-bit + library, the value is always less than 256; in the 16-bit library the + value can be up to 0xffff. + + If there is no fixed first value, and if either (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or @@ -1729,10 +2144,10 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_FIRSTTABLE If the pattern was studied, and this resulted in the construction of a - 256-bit table indicating a fixed set of bytes for the first byte in any - matching string, a pointer to the table is returned. Otherwise NULL is - returned. The fourth argument should point to an unsigned char * vari- - able. + 256-bit table indicating a fixed set of values for the first data unit + in any matching string, a pointer to the table is returned. Otherwise + NULL is returned. The fourth argument should point to an unsigned char + * variable. PCRE_INFO_HASCRORLF @@ -1747,25 +2162,49 @@ INFORMATION ABOUT A PATTERN otherwise 0. The fourth argument should point to an int variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. + PCRE_INFO_JIT + + Return 1 if the pattern was studied with one of the JIT options, and + just-in-time compiling was successful. The fourth argument should point + to an int variable. A return value of 0 means that JIT support is not + available in this version of PCRE, or that the pattern was not studied + with a JIT option, or that the JIT compiler could not handle this par- + ticular pattern. See the pcrejit documentation for details of what can + and cannot be handled. + + PCRE_INFO_JITSIZE + + If the pattern was successfully studied with a JIT option, return the + size of the JIT compiled code, otherwise return zero. The fourth argu- + ment should point to a size_t variable. + PCRE_INFO_LASTLITERAL - Return the value of the rightmost literal byte that must exist in any - matched string, other than at its start, if such a byte has been + Return the value of the rightmost literal data unit that must exist in + any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an int variable. If there - is no such byte, -1 is returned. For anchored patterns, a last literal - byte is recorded only if it follows something of variable length. For + is no such value, -1 is returned. For anchored patterns, a last literal + value is recorded only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1. + PCRE_INFO_MAXLOOKBEHIND + + Return the number of characters (NB not bytes) in the longest lookbe- + hind assertion in the pattern. Note that the simple assertions \b and + \B require a one-character lookbehind. This information is useful when + doing multi-segment matching using the partial matching facilities. + PCRE_INFO_MINLENGTH - If the pattern was studied and a minimum length for matching subject - strings was computed, its value is returned. Otherwise the returned - value is -1. The value is a number of characters, not bytes (this may - be relevant in UTF-8 mode). The fourth argument should point to an int - variable. A non-negative value is a lower bound to the length of any - matching string. There may not be any strings of that length that do - actually match, but every string that does match is at least that long. + If the pattern was studied and a minimum length for matching subject + strings was computed, its value is returned. Otherwise the returned + value is -1. The value is a number of characters, which in UTF-8 mode + may be different from the number of bytes. The fourth argument should + point to an int variable. A non-negative value is a lower bound to the + length of any matching string. There may not be any strings of that + length that do actually match, but every string that does match is at + least that long. PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE @@ -1785,10 +2224,12 @@ INFORMATION ABOUT A PATTERN gives the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each entry; both of these return an int value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns - a pointer to the first entry of the table (a pointer to char). The - first two bytes of each entry are the number of the capturing parenthe- - sis, most significant byte first. The rest of the entry is the corre- - sponding name, zero terminated. + a pointer to the first entry of the table. This is a pointer to char in + the 8-bit library, where the first two bytes of each entry are the num- + ber of the capturing parenthesis, most significant byte first. In the + 16-bit library, the pointer points to 16-bit data units, the first of + which contains the parenthesis number. The rest of the entry is the + corresponding name, zero terminated. The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in @@ -1801,8 +2242,8 @@ INFORMATION ABOUT A PATTERN terns may have lower numbers. As a simple example of the name/number table, consider the following - pattern (assume PCRE_EXTENDED is set, so white space - including new- - lines - is ignored): + pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is + set, so white space - including newlines - is ignored): (? (?(\d\d)?\d\d) - (?\d\d) - (?\d\d) ) @@ -1855,62 +2296,47 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_SIZE - Return the size of the compiled pattern, that is, the value that was - passed as the argument to pcre_malloc() when PCRE was getting memory in - which to place the compiled data. The fourth argument should point to a - size_t variable. + Return the size of the compiled pattern in bytes (for both libraries). + The fourth argument should point to a size_t variable. This value does + not include the size of the pcre structure that is returned by + pcre_compile(). The value that is passed as the argument to pcre_mal- + loc() when pcre_compile() is getting memory in which to place the com- + piled data is the value returned by this option plus the size of the + pcre structure. Studying a compiled pattern, with or without JIT, does + not alter the value returned by this option. PCRE_INFO_STUDYSIZE - Return the size of the data block pointed to by the study_data field in - a pcre_extra block. That is, it is the value that was passed to - pcre_malloc() when PCRE was getting memory into which to place the data - created by pcre_study(). If pcre_extra is NULL, or there is no study - data, zero is returned. The fourth argument should point to a size_t - variable. - - -OBSOLETE INFO FUNCTION - - int pcre_info(const pcre *code, int *optptr, int *firstcharptr); - - The pcre_info() function is now obsolete because its interface is too - restrictive to return all the available data about a compiled pattern. - New programs should use pcre_fullinfo() instead. The yield of - pcre_info() is the number of capturing subpatterns, or one of the fol- - lowing negative numbers: - - PCRE_ERROR_NULL the argument code was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found - - If the optptr argument is not NULL, a copy of the options with which - the pattern was compiled is placed in the integer it points to (see - PCRE_INFO_OPTIONS above). - - If the pattern is not anchored and the firstcharptr argument is not - NULL, it is used to pass back information about the first character of - any matched string (see PCRE_INFO_FIRSTBYTE above). + Return the size in bytes of the data block pointed to by the study_data + field in a pcre_extra block. If pcre_extra is NULL, or there is no + study data, zero is returned. The fourth argument should point to a + size_t variable. The study_data field is set by pcre_study() to record + information that will speed up matching (see the section entitled + "Studying a pattern" above). The format of the study_data block is pri- + vate, but its length is made available via this option so that it can + be saved and restored (see the pcreprecompile documentation for + details). REFERENCE COUNTS int pcre_refcount(pcre *code, int adjust); - The pcre_refcount() function is used to maintain a reference count in + The pcre_refcount() function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the - benefit of applications that operate in an object-oriented manner, + benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done. When a pattern is compiled, the reference count field is initialized to - zero. It is changed only by calling this function, whose action is to - add the adjust value (which may be positive or negative) to it. The + zero. It is changed only by calling this function, whose action is to + add the adjust value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count - is constrained to lie between 0 and 65535, inclusive. If the new value + is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value. - Except when it is zero, the reference count is not correctly preserved - if a pattern is compiled on one host and then transferred to a host + Except when it is zero, the reference count is not correctly preserved + if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.) @@ -1920,18 +2346,22 @@ 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. This function is the main matching facility of the library, - and it operates in a Perl-like manner. For specialist use there is also - an alternative matching function, which is described below in the sec- - tion about the pcre_dfa_exec() function. + The function pcre_exec() is called to match a subject string against a + compiled pattern, which is passed in the code argument. If the pattern + was studied, the result of the study should be passed in the extra + argument. You can call pcre_exec() with the same code and extra argu- + ments as many times as you like, in order to match different subject + strings with the same pattern. - In most applications, the pattern will have been compiled (and option- - ally studied) in the same process that calls pcre_exec(). However, it + 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 is possible to save compiled patterns and study data, and then use them - later in different processes, possibly even on different hosts. For a + later in different processes, possibly even on different hosts. For a discussion about this, see the pcreprecompile documentation. Here is an example of a simple call to pcre_exec(): @@ -1950,35 +2380,40 @@ 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; void *study_data; + void *executable_jit; unsigned long int match_limit; unsigned long int match_limit_recursion; void *callout_data; const unsigned char *tables; unsigned char **mark; - The flags field is a bitmap that specifies which of the other fields - are set. The flag bits are: + In the 16-bit version of this structure, the mark field has type + "PCRE_UCHAR16 **". - PCRE_EXTRA_STUDY_DATA + The flags field is used to specify which of the other fields are set. + The flag bits are: + + PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_EXECUTABLE_JIT + PCRE_EXTRA_MARK PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_MATCH_LIMIT_RECURSION - PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES - PCRE_EXTRA_MARK - Other flag bits should be set to zero. The study_data field is set in - the pcre_extra block that is returned by pcre_study(), together with - the appropriate flag bit. You should not set this yourself, but you may - add to the block by setting the other fields and their corresponding - flag bits. + Other flag bits should be set to zero. The study_data field and some- + times the executable_jit field are set in the pcre_extra block that is + returned by pcre_study(), together with the appropriate flag bits. You + should not set these yourself, but you may add to the block by setting + other fields and their corresponding flag bits. The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to @@ -1986,70 +2421,86 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION search trees. The classic example is a pattern that uses nested unlim- ited repeats. - Internally, PCRE uses a function called match() which it calls repeat- - edly (sometimes recursively). The limit set by match_limit is imposed - on the number of times this function is called during a match, which - has the effect of limiting the amount of backtracking that can take - place. For patterns that are not anchored, the count restarts from zero - for each position in the subject string. + 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. - 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 + When pcre_exec() is called with a pattern that was successfully studied + with a JIT option, the way that the matching is executed is entirely + different. However, there is still the possibility of runaway matching + that goes on for a very long time, and so the match_limit value is also + used in this case (but in a different way) to limit how long the match- + ing can continue. + + The default value for the limit can be set when PCRE is built; the + default default is 10 million, which handles all but the most extreme + cases. You can override the default by suppling pcre_exec() with a + pcre_extra block in which match_limit is set, and + PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. - The match_limit_recursion field is similar to match_limit, but instead + The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits - the depth of recursion. The recursion depth is a smaller number than - the total number of calls, because not all calls to match() are recur- + the depth of recursion. The recursion depth is a smaller number than + the total number of calls, because not all calls to match() are recur- sive. This limit is of use only if it is set smaller than match_limit. - Limiting the recursion depth limits the amount of stack that can be - used, or, when PCRE has been compiled to use memory on the heap instead - of the stack, the amount of heap memory that can be used. + Limiting the recursion depth limits the amount of machine stack that + can be used, or, when PCRE has been compiled to use memory on the heap + instead of the stack, the amount of heap memory that can be used. This + limit is not relevant, and is ignored, when matching is done using JIT + compiled code. - The default value for match_limit_recursion can be set when PCRE is - built; the default default is the same value as the default for - match_limit. You can override the default by suppling pcre_exec() with - a pcre_extra block in which match_limit_recursion is set, and - PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the + The default value for match_limit_recursion can be set when PCRE is + built; the default default is the same value as the default for + match_limit. You can override the default by suppling pcre_exec() with + a pcre_extra block in which match_limit_recursion is set, and + PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT. - The callout_data field is used in conjunction with the "callout" fea- + The callout_data field is used in conjunction with the "callout" fea- ture, and is described in the pcrecallout documentation. - The tables field is used to pass a character tables pointer to - pcre_exec(); this overrides the value that is stored with the compiled - pattern. A non-NULL value is stored with the compiled pattern only if - custom tables were supplied to pcre_compile() via its tableptr argu- + The tables field is used to pass a character tables pointer to + pcre_exec(); this overrides the value that is stored with the compiled + pattern. A non-NULL value is stored with the compiled pattern only if + custom tables were supplied to pcre_compile() via its tableptr argu- ment. If NULL is passed to pcre_exec() using this mechanism, it forces - PCRE's internal tables to be used. This facility is helpful when re- - using patterns that have been saved after compiling with an external - set of tables, because the external tables might be at a different - address when pcre_exec() is called. See the pcreprecompile documenta- + PCRE's internal tables to be used. This facility is helpful when re- + using patterns that have been saved after compiling with an external + set of tables, because the external tables might be at a different + address when pcre_exec() is called. See the pcreprecompile documenta- tion for a discussion of saving compiled patterns for later use. - If PCRE_EXTRA_MARK is set in the flags field, the mark field must be - set to point to a char * variable. If the pattern contains any back- - tracking control verbs such as (*MARK:NAME), and the execution ends up - with a name to pass back, a pointer to the name string (zero termi- - nated) is placed in the variable pointed to by the mark field. The - names are within the compiled pattern; if you wish to retain such a - name you must copy it before freeing the memory of a compiled pattern. - If there is no name to pass back, the variable pointed to by the mark - field set to NULL. For details of the backtracking control verbs, see - the section entitled "Backtracking control" in the pcrepattern documen- - tation. + If PCRE_EXTRA_MARK is set in the flags field, the mark field must be + set to point to a suitable variable. If the pattern contains any back- + tracking control verbs such as (*MARK:NAME), and the execution ends up + with a name to pass back, a pointer to the name string (zero termi- + nated) is placed in the variable pointed to by the mark field. The + names are within the compiled pattern; if you wish to retain such a + name you must copy it before freeing the memory of a compiled pattern. + If there is no name to pass back, the variable pointed to by the mark + field is set to NULL. For details of the backtracking control verbs, + see the section entitled "Backtracking control" in the pcrepattern doc- + umentation. Option bits for pcre_exec() - The unused bits of the options argument for pcre_exec() must be zero. - The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, - PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, - PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and - PCRE_PARTIAL_HARD. + The unused bits of the options argument for pcre_exec() must be zero. + The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, + PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, + PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and + PCRE_PARTIAL_SOFT. + + If the pattern was successfully studied with one of the just-in-time + (JIT) compile options, the only supported options for JIT execution are + PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, + PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an + unsupported option is used, JIT execution is disabled and the normal + interpretive code in pcre_exec() is run. PCRE_ANCHORED @@ -2172,7 +2623,9 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at - compile time, it cannot be unset at matching time. + compile time, it cannot be unset at matching time. The use of + PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching + is always done using interpretively. Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern @@ -2206,182 +2659,201 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when pcre_exec() is subsequently - called. The value of startoffset is also checked to ensure that it - points to the start of a UTF-8 character. There is a discussion about - the validity of UTF-8 strings in the section on UTF-8 support in the - main pcre page. If an invalid UTF-8 sequence of bytes is found, - pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PAR- - TIAL_HARD is set and the problem is a truncated UTF-8 character at the - end of the subject, PCRE_ERROR_SHORTUTF8. If startoffset contains a - value that does not point to the start of a UTF-8 character (or to the - end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. + called. The entire string is checked before any other processing takes + place. The value of startoffset is also checked to ensure that it + points to the start of a UTF-8 character. There is a discussion about + the validity of UTF-8 strings in the pcreunicode page. If an invalid + sequence of bytes is found, pcre_exec() returns the error + PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a + truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In + both cases, information about the precise nature of the error may also + be returned (see the descriptions of these errors in the section enti- + tled Error return values from pcre_exec() below). If startoffset con- + tains a value that does not point to the start of a UTF-8 character (or + to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. - If you already know that your subject is valid, and you want to skip - these checks for performance reasons, you can set the - PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to - do this for the second and subsequent calls to pcre_exec() if you are - making repeated calls to find all the matches in a single subject - string. However, you should be sure that the value of startoffset - points to the start of a UTF-8 character (or the end of the subject). - When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid UTF-8 - string as a subject or an invalid value of startoffset is undefined. - Your program may crash. + If you already know that your subject is valid, and you want to skip + these checks for performance reasons, you can set the + PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to + do this for the second and subsequent calls to pcre_exec() if you are + making repeated calls to find all the matches in a single subject + string. However, you should be sure that the value of startoffset + points to the start of a character (or the end of the subject). When + PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a + subject or an invalid value of startoffset is undefined. Your program + may crash. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These options turn on the partial matching feature. For backwards com- - patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial - match occurs if the end of the subject string is reached successfully, - but there are not enough subject characters to complete the match. If + These options turn on the partial matching feature. For backwards com- + patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial + match occurs if the end of the subject string is reached successfully, + but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, - matching continues by testing any remaining alternatives. Only if no - complete match can be found is PCRE_ERROR_PARTIAL returned instead of - PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the - caller is prepared to handle a partial match, but only if no complete + matching continues by testing any remaining alternatives. Only if no + complete match can be found is PCRE_ERROR_PARTIAL returned instead of + PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the + caller is prepared to handle a partial match, but only if no complete match can be found. - If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this - case, if a partial match is found, pcre_exec() immediately returns - PCRE_ERROR_PARTIAL, without considering any other alternatives. In - other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- + If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this + case, if a partial match is found, pcre_exec() immediately returns + PCRE_ERROR_PARTIAL, without considering any other alternatives. In + other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- ered to be more important that an alternative complete match. - In both cases, the portion of the string that was inspected when the + In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a - more detailed discussion of partial and multi-segment matching, with + more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation. The string to be matched by pcre_exec() - The subject string is passed to pcre_exec() as a pointer in subject, a - length (in bytes) in length, and a starting byte offset in startoffset. - If this is negative or greater than the length of the subject, - pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is - zero, the search for a match starts at the beginning of the subject, + The subject string is passed to pcre_exec() as a pointer in subject, a + length in bytes in length, and a starting byte offset in startoffset. + If this is negative or greater than the length of the subject, + pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is + zero, the search for a match starts at the beginning of the subject, and this is by far the most common case. In UTF-8 mode, the byte offset - must point to the start of a UTF-8 character (or the end of the sub- - ject). Unlike the pattern string, the subject may contain binary zero + must point to the start of a UTF-8 character (or the end of the sub- + ject). Unlike the pattern string, the subject may contain binary zero bytes. - A non-zero starting offset is useful when searching for another match - in the same subject by calling pcre_exec() again after a previous suc- - cess. Setting startoffset differs from just passing over a shortened - string and setting PCRE_NOTBOL in the case of a pattern that begins + A non-zero starting offset is useful when searching for another match + in the same subject by calling pcre_exec() again after a previous suc- + cess. Setting startoffset differs from just passing over a shortened + string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern \Biss\B - which finds occurrences of "iss" in the middle of words. (\B matches - only if the current position in the subject is not a word boundary.) - When applied to the string "Mississipi" the first call to pcre_exec() - finds the first occurrence. If pcre_exec() is called again with just - the remainder of the subject, namely "issipi", it does not match, + which finds occurrences of "iss" in the middle of words. (\B matches + only if the current position in the subject is not a word boundary.) + When applied to the string "Mississipi" the first call to pcre_exec() + finds the first occurrence. If pcre_exec() is called again with just + the remainder of the subject, namely "issipi", it does not match, because \B is always false at the start of the subject, which is deemed - to be a word boundary. However, if pcre_exec() is passed the entire + to be a word boundary. However, if pcre_exec() is passed the entire string again, but with startoffset set to 4, it finds the second occur- - rence of "iss" because it is able to look behind the starting point to + rence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter. - Finding all the matches in a subject is tricky when the pattern can + Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by - first trying the match again at the same offset, with the - PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that - fails, advancing the starting offset and trying an ordinary match + first trying the match again at the same offset, with the + PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that + fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the pcre- demo sample program. In the most general case, you have to check to see - if the newline convention recognizes CRLF as a newline, and if so, and + if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. - If a non-zero starting offset is passed when the pattern is anchored, + If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed - if the pattern does not require the match to be at the start of the + if the pattern does not require the match to be at the start of the subject. How pcre_exec() returns captured substrings - In general, a pattern matches a certain portion of the subject, and in - addition, further substrings from the subject may be picked out by - parts of the pattern. Following the usage in Jeffrey Friedl's book, - this is called "capturing" in what follows, and the phrase "capturing - subpattern" is used for a fragment of a pattern that picks out a sub- - string. PCRE supports several other kinds of parenthesized subpattern + In general, a pattern matches a certain portion of the subject, and in + addition, further substrings from the subject may be picked out by + parts of the pattern. Following the usage in Jeffrey Friedl's book, + this is called "capturing" in what follows, and the phrase "capturing + subpattern" is used for a fragment of a pattern that picks out a sub- + string. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured. Captured substrings are returned to the caller via a vector of integers - whose address is passed in ovector. The number of elements in the vec- - tor is passed in ovecsize, which must be a non-negative number. Note: + whose address is passed in ovector. The number of elements in the vec- + tor is passed in ovecsize, which must be a non-negative number. Note: this argument is NOT the size of ovector in bytes. - The first two-thirds of the vector is used to pass back captured sub- - strings, each substring using a pair of integers. The remaining third - of the vector is used as workspace by pcre_exec() while matching cap- - turing subpatterns, and is not available for passing back information. - The number passed in ovecsize should always be a multiple of three. If + The first two-thirds of the vector is used to pass back captured sub- + strings, each substring using a pair of integers. The remaining third + of the vector is used as workspace by pcre_exec() while matching cap- + turing subpatterns, and is not available for passing back information. + The number passed in ovecsize should always be a multiple of three. If it is not, it is rounded down. - When a match is successful, information about captured substrings is - returned in pairs of integers, starting at the beginning of ovector, - and continuing up to two-thirds of its length at the most. The first - element of each pair is set to the byte offset of the first character - in a substring, and the second is set to the byte offset of the first - character after the end of a substring. Note: these values are always + When a match is successful, information about captured substrings is + returned in pairs of integers, starting at the beginning of ovector, + and continuing up to two-thirds of its length at the most. The first + element of each pair is set to the byte offset of the first character + in a substring, and the second is set to the byte offset of the first + character after the end of a substring. Note: these values are always byte offsets, even in UTF-8 mode. They are not character counts. - The first pair of integers, ovector[0] and ovector[1], identify the - portion of the subject string matched by the entire pattern. The next - pair is used for the first capturing subpattern, and so on. The value + The first pair of integers, ovector[0] and ovector[1], identify the + portion of the subject string matched by the entire pattern. The next + pair is used for the first capturing subpattern, and so on. The value returned by pcre_exec() is one more than the highest numbered pair that - has been set. For example, if two substrings have been captured, the - returned value is 3. If there are no capturing subpatterns, the return + has been set. For example, if two substrings have been captured, the + returned value is 3. If there are no capturing subpatterns, the return value from a successful match is 1, indicating that just the first pair of offsets has been set. If a capturing subpattern is matched repeatedly, it is the last portion of the string that it matched that is returned. - If the vector is too small to hold all the captured substring offsets, + If the vector is too small to hold all the captured substring offsets, it is used as far as possible (up to two-thirds of its length), and the - function returns a value of zero. If the substring offsets are not of - interest, pcre_exec() may be called with ovector passed as NULL and - ovecsize as zero. However, if the pattern contains back references and - the ovector is not big enough to remember the related substrings, PCRE - has to get additional memory for use during matching. Thus it is usu- - ally advisable to supply an ovector. + function returns a value of zero. If neither the actual string matched + nor any captured substrings are of interest, pcre_exec() may be called + with ovector passed as NULL and ovecsize as zero. However, if the pat- + tern contains back references and the ovector is not big enough to + remember the related substrings, PCRE has to get additional memory for + use during matching. Thus it is usually advisable to supply an ovector + of reasonable size. + + There are some cases where zero is returned (indicating vector over- + flow) when in fact the vector is exactly the right size for the final + match. For example, consider the pattern + + (a)(?:(b)c|bd) + + If a vector of 6 elements (allowing for only 1 captured substring) is + given with subject string "abd", pcre_exec() will try to set the second + captured string, thereby recording a vector overflow, before failing to + match "c" and backing up to try the second alternative. The zero + return, however, does correctly indicate that the maximum number of + slots (namely 2) have been filled. In similar cases where there is tem- + porary overflow, but the final number of used slots is actually less + than the maximum, a non-zero value is returned. The pcre_fullinfo() function can be used to find out how many capturing - subpatterns there are in a compiled pattern. The smallest size for - ovector that will allow for n captured substrings, in addition to the + subpatterns there are in a compiled pattern. The smallest size for + ovector that will allow for n captured substrings, in addition to the offsets of the substring matched by the whole pattern, is (n+1)*3. - It is possible for capturing subpattern number n+1 to match some part + It is possible for capturing subpattern number n+1 to match some part of the subject when subpattern n has not been used at all. For example, - if the string "abc" is matched against the pattern (a|(z))(bc) the + if the string "abc" is matched against the pattern (a|(z))(bc) the return from the function is 4, and subpatterns 1 and 3 are matched, but - 2 is not. When this happens, both values in the offset pairs corre- + 2 is not. When this happens, both values in the offset pairs corre- sponding to unused subpatterns are set to -1. - Offset values that correspond to unused subpatterns at the end of the - expression are also set to -1. For example, if the string "abc" is - matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not - matched. The return from the function is 2, because the highest used - capturing subpattern number is 1, and the offsets for for the second - and third capturing subpatterns (assuming the vector is large enough, + Offset values that correspond to unused subpatterns at the end of the + expression are also set to -1. For example, if the string "abc" is + matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not + matched. The return from the function is 2, because the highest used + capturing subpattern number is 1, and the offsets for for the second + and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. - Note: Elements of ovector that do not correspond to capturing parenthe- - ses in the pattern are never changed. That is, if a pattern contains n - capturing parentheses, no more than ovector[0] to ovector[2n+1] are set - by pcre_exec(). The other elements retain whatever values they previ- - ously had. + Note: Elements in the first two-thirds of ovector that do not corre- + spond to capturing parentheses in the pattern are never changed. That + is, if a pattern contains n capturing parentheses, no more than ovec- + tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in + the first two-thirds) retain whatever values they previously had. - Some convenience functions are provided for extracting the captured + Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. Error return values from pcre_exec() - If pcre_exec() fails, it returns a negative number. The following are + If pcre_exec() fails, it returns a negative number. The following are defined in the header file: PCRE_ERROR_NOMATCH (-1) @@ -2390,7 +2862,7 @@ 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) @@ -2399,76 +2871,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. However, if PCRE_PARTIAL_HARD is set and the problem is a - truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT- - UTF8 is used instead. + A string that contains an invalid UTF-8 byte sequence was passed as a + subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of + the output vector (ovecsize) is at least 2, the byte offset to the + start of the the invalid UTF-8 character is placed in the first ele- + ment, and a reason code is placed in the second element. The reason + codes are listed in the following section. For backward compatibility, + if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char- + acter at the end of the subject (reason codes 1 to 5), + PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. PCRE_ERROR_BADUTF8_OFFSET (-11) - The UTF-8 byte sequence that was passed as a subject was valid, but the - value of startoffset did not point to the beginning of a UTF-8 charac- + The UTF-8 byte sequence that was passed as a subject was checked and + found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the + value of startoffset did not point to the beginning of a UTF-8 charac- ter or the end of the subject. PCRE_ERROR_PARTIAL (-12) - The subject string did not match, but it did match partially. See the + The subject string did not match, but it did match partially. See the pcrepartial documentation for details of partial matching. PCRE_ERROR_BADPARTIAL (-13) - This code is no longer in use. It was formerly returned when the - PCRE_PARTIAL option was used with a compiled pattern containing items - that were not supported for partial matching. From release 8.00 + This code is no longer in use. It was formerly returned when the + PCRE_PARTIAL option was used with a compiled pattern containing items + that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching. PCRE_ERROR_INTERNAL (-14) - An unexpected internal error has occurred. This error could be caused + An unexpected internal error has occurred. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. PCRE_ERROR_BADCOUNT (-15) @@ -2478,7 +2956,7 @@ 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) @@ -2492,11 +2970,118 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_SHORTUTF8 (-25) - The subject string ended with an incomplete (truncated) UTF-8 charac- - ter, and the PCRE_PARTIAL_HARD option was set. Without this option, - PCRE_ERROR_BADUTF8 is returned in this situation. + This error is returned instead of PCRE_ERROR_BADUTF8 when the subject + string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD + option is set. Information about the failure is returned as for + PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but + this special error code for PCRE_PARTIAL_HARD precedes the implementa- + tion of returned information; it is retained for backwards compatibil- + ity. - Error numbers -16 to -20 and -22 are not used by pcre_exec(). + PCRE_ERROR_RECURSELOOP (-26) + + This error is returned when pcre_exec() detects a recursion loop within + the pattern. Specifically, it means that either the whole pattern or a + subpattern has been called recursively for the second time at the same + position in the subject string. Some simple patterns that might do this + are detected and faulted at compile time, but more complicated cases, + in particular mutual recursions between two different subpatterns, can- + not be detected until run time. + + PCRE_ERROR_JIT_STACKLIMIT (-27) + + This error is returned when a pattern that was successfully studied + using a JIT compile option is being matched, but the memory available + for the just-in-time processing stack is not large enough. See the + pcrejit documentation for more details. + + PCRE_ERROR_BADMODE (-28) + + This error is given if a pattern that was compiled by the 8-bit library + is passed to a 16-bit library function, or vice versa. + + PCRE_ERROR_BADENDIANNESS (-29) + + This error is given if a pattern that was compiled and saved is + reloaded on a host with different endianness. The utility function + pcre_pattern_to_host_byte_order() can be used to convert such a pattern + so that it runs on the new host. + + Error numbers -16 to -20, -22, and -30 are not used by pcre_exec(). + + Reason codes for invalid UTF-8 strings + + This section applies only to the 8-bit library. The corresponding + information for the 16-bit library is given in the pcre16 page. + + When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT- + UTF8, and the size of the output vector (ovecsize) is at least 2, the + offset of the start of the invalid UTF-8 character is placed in the + first output vector element (ovector[0]) and a reason code is placed in + the second element (ovector[1]). The reason codes are given names in + the pcre.h header file: + + PCRE_UTF8_ERR1 + PCRE_UTF8_ERR2 + PCRE_UTF8_ERR3 + PCRE_UTF8_ERR4 + PCRE_UTF8_ERR5 + + The string ends with a truncated UTF-8 character; the code specifies + how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 + characters to be no longer than 4 bytes, the encoding scheme (origi- + nally defined by RFC 2279) allows for up to 6 bytes, and this is + checked first; hence the possibility of 4 or 5 missing bytes. + + PCRE_UTF8_ERR6 + PCRE_UTF8_ERR7 + PCRE_UTF8_ERR8 + PCRE_UTF8_ERR9 + PCRE_UTF8_ERR10 + + The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of + the character do not have the binary value 0b10 (that is, either the + most significant bit is 0, or the next bit is 1). + + PCRE_UTF8_ERR11 + PCRE_UTF8_ERR12 + + A character that is valid by the RFC 2279 rules is either 5 or 6 bytes + long; these code points are excluded by RFC 3629. + + PCRE_UTF8_ERR13 + + A 4-byte character has a value greater than 0x10fff; these code points + are excluded by RFC 3629. + + PCRE_UTF8_ERR14 + + A 3-byte character has a value in the range 0xd800 to 0xdfff; this + range of code points are reserved by RFC 3629 for use with UTF-16, and + so are excluded from UTF-8. + + PCRE_UTF8_ERR15 + PCRE_UTF8_ERR16 + PCRE_UTF8_ERR17 + PCRE_UTF8_ERR18 + PCRE_UTF8_ERR19 + + A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes + for a value that can be represented by fewer bytes, which is invalid. + For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- + rect coding uses just one byte. + + PCRE_UTF8_ERR20 + + The two most significant bits of the first byte of a character have the + binary value 0b10 (that is, the most significant bit is 1 and the sec- + ond is 0). Such a byte can only validly occur as the second or subse- + quent byte of a multi-byte character. + + PCRE_UTF8_ERR21 + + The first byte of a character has the value 0xfe or 0xff. These values + can never occur in a valid UTF-8 string. EXTRACTING CAPTURED SUBSTRINGS BY NUMBER @@ -2512,78 +3097,78 @@ EXTRACTING CAPTURED SUBSTRINGS BY NUMBER int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr); - Captured substrings can be accessed directly by using the offsets - returned by pcre_exec() in ovector. For convenience, the functions + Captured substrings can be accessed directly by using the offsets + returned by pcre_exec() in ovector. For convenience, the functions pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub- - string_list() are provided for extracting captured substrings as new, - separate, zero-terminated strings. These functions identify substrings - by number. The next section describes functions for extracting named + string_list() are provided for extracting captured substrings as new, + separate, zero-terminated strings. These functions identify substrings + by number. The next section describes functions for extracting named substrings. - A substring that contains a binary zero is correctly extracted and has - a further zero added on the end, but the result is not, of course, a C - string. However, you can process such a string by referring to the - length that is returned by pcre_copy_substring() and pcre_get_sub- + A substring that contains a binary zero is correctly extracted and has + a further zero added on the end, but the result is not, of course, a C + string. However, you can process such a string by referring to the + length that is returned by pcre_copy_substring() and pcre_get_sub- string(). Unfortunately, the interface to pcre_get_substring_list() is - not adequate for handling strings containing binary zeros, because the + not adequate for handling strings containing binary zeros, because the end of the final string is not independently indicated. - The first three arguments are the same for all three of these func- - tions: subject is the subject string that has just been successfully + The first three arguments are the same for all three of these func- + tions: subject is the subject string that has just been successfully matched, ovector is a pointer to the vector of integer offsets that was passed to pcre_exec(), and stringcount is the number of substrings that - were captured by the match, including the substring that matched the + were captured by the match, including the substring that matched the entire regular expression. This is the value returned by pcre_exec() if - it is greater than zero. If pcre_exec() returned zero, indicating that - it ran out of space in ovector, the value passed as stringcount should + it is greater than zero. If pcre_exec() returned zero, indicating that + it ran out of space in ovector, the value passed as stringcount should be the number of elements in the vector divided by three. - The functions pcre_copy_substring() and pcre_get_substring() extract a - single substring, whose number is given as stringnumber. A value of - zero extracts the substring that matched the entire pattern, whereas - higher values extract the captured substrings. For pcre_copy_sub- - string(), the string is placed in buffer, whose length is given by - buffersize, while for pcre_get_substring() a new block of memory is - obtained via pcre_malloc, and its address is returned via stringptr. - The yield of the function is the length of the string, not including + The functions pcre_copy_substring() and pcre_get_substring() extract a + single substring, whose number is given as stringnumber. A value of + zero extracts the substring that matched the entire pattern, whereas + higher values extract the captured substrings. For pcre_copy_sub- + string(), the string is placed in buffer, whose length is given by + buffersize, while for pcre_get_substring() a new block of memory is + obtained via pcre_malloc, and its address is returned via stringptr. + The yield of the function is the length of the string, not including the terminating zero, or one of these error codes: PCRE_ERROR_NOMEMORY (-6) - The buffer was too small for pcre_copy_substring(), or the attempt to + The buffer was too small for pcre_copy_substring(), or the attempt to get memory failed for pcre_get_substring(). PCRE_ERROR_NOSUBSTRING (-7) There is no substring whose number is stringnumber. - The pcre_get_substring_list() function extracts all available sub- - strings and builds a list of pointers to them. All this is done in a + The pcre_get_substring_list() function extracts all available sub- + strings and builds a list of pointers to them. All this is done in a single block of memory that is obtained via pcre_malloc. The address of - the memory block is returned via listptr, which is also the start of - the list of string pointers. The end of the list is marked by a NULL - pointer. The yield of the function is zero if all went well, or the + the memory block is returned via listptr, which is also the start of + the list of string pointers. The end of the list is marked by a NULL + pointer. The yield of the function is zero if all went well, or the error code PCRE_ERROR_NOMEMORY (-6) if the attempt to get the memory block failed. - When any of these functions encounter a substring that is unset, which - can happen when capturing subpattern number n+1 matches some part of - the subject, but subpattern n has not been used at all, they return an + When any of these functions encounter a substring that is unset, which + can happen when capturing subpattern number n+1 matches some part of + the subject, but subpattern n has not been used at all, they return an empty string. This can be distinguished from a genuine zero-length sub- - string by inspecting the appropriate offset in ovector, which is nega- + string by inspecting the appropriate offset in ovector, which is nega- tive for unset substrings. - The two convenience functions pcre_free_substring() and pcre_free_sub- - string_list() can be used to free the memory returned by a previous + The two convenience functions pcre_free_substring() and pcre_free_sub- + string_list() can be used to free the memory returned by a previous call of pcre_get_substring() or pcre_get_substring_list(), respec- - tively. They do nothing more than call the function pointed to by - pcre_free, which of course could be called directly from a C program. - However, PCRE is used in some situations where it is linked via a spe- - cial interface to another programming language that cannot use - pcre_free directly; it is for these cases that the functions are pro- + tively. They do nothing more than call the function pointed to by + pcre_free, which of course could be called directly from a C program. + However, PCRE is used in some situations where it is linked via a spe- + cial interface to another programming language that cannot use + pcre_free directly; it is for these cases that the functions are pro- vided. @@ -2602,7 +3187,7 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME int stringcount, const char *stringname, const char **stringptr); - To extract a substring by name, you first have to find associated num- + To extract a substring by name, you first have to find associated num- ber. For example, for this pattern (a+)b(?\d+)... @@ -2611,35 +3196,35 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME be unique (PCRE_DUPNAMES was not set), you can find the number from the name by calling pcre_get_stringnumber(). The first argument is the com- piled pattern, and the second is the name. The yield of the function is - the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no + the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no subpattern of that name. Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job. - Most of the arguments of pcre_copy_named_substring() and - pcre_get_named_substring() are the same as those for the similarly - named functions that extract by number. As these are described in the - previous section, they are not re-described here. There are just two + Most of the arguments of pcre_copy_named_substring() and + pcre_get_named_substring() are the same as those for the similarly + named functions that extract by number. As these are described in the + previous section, they are not re-described here. There are just two differences: - First, instead of a substring number, a substring name is given. Sec- + First, instead of a substring number, a substring name is given. Sec- ond, there is an extra argument, given at the start, which is a pointer - to the compiled pattern. This is needed in order to gain access to the + to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. - These functions call pcre_get_stringnumber(), and if it succeeds, they - then call pcre_copy_substring() or pcre_get_substring(), as appropri- - ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the + These functions call pcre_get_stringnumber(), and if it succeeds, they + then call pcre_copy_substring() or pcre_get_substring(), as appropri- + ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). Warning: If the pattern uses the (?| feature to set up multiple subpat- - terns with the same number, as described in the section on duplicate - subpattern numbers in the pcrepattern page, you cannot use names to - distinguish the different subpatterns, because names are not included - in the compiled code. The matching process uses only numbers. For this - reason, the use of different names for subpatterns of the same number + terns with the same number, as described in the section on duplicate + subpattern numbers in the pcrepattern page, you cannot use names to + distinguish the different subpatterns, because names are not included + in the compiled code. The matching process uses only numbers. For this + reason, the use of different names for subpatterns of the same number causes an error at compile time. @@ -2648,54 +3233,79 @@ DUPLICATE SUBPATTERN NAMES int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last); - When a pattern is compiled with the PCRE_DUPNAMES option, names for - subpatterns are not required to be unique. (Duplicate names are always - allowed for subpatterns with the same number, created by using the (?| - feature. Indeed, if such subpatterns are named, they are required to + When a pattern is compiled with the PCRE_DUPNAMES option, names for + subpatterns are not required to be unique. (Duplicate names are always + allowed for subpatterns with the same number, created by using the (?| + feature. Indeed, if such subpatterns are named, they are required to use the same names.) Normally, patterns with duplicate names are such that in any one match, - only one of the named subpatterns participates. An example is shown in + only one of the named subpatterns participates. An example is shown in the pcrepattern documentation. - When duplicates are present, pcre_copy_named_substring() and - pcre_get_named_substring() return the first substring corresponding to - the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING - (-7) is returned; no data is returned. The pcre_get_stringnumber() - function returns one of the numbers that are associated with the name, + When duplicates are present, pcre_copy_named_substring() and + pcre_get_named_substring() return the first substring corresponding to + the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING + (-7) is returned; no data is returned. The pcre_get_stringnumber() + function returns one of the numbers that are associated with the name, but it is not defined which it is. - If you want to get full details of all captured substrings for a given - name, you must use the pcre_get_stringtable_entries() function. The + If you want to get full details of all captured substrings for a given + name, you must use the pcre_get_stringtable_entries() function. The first argument is the compiled pattern, and the second is the name. The - third and fourth are pointers to variables which are updated by the + third and fourth are pointers to variables which are updated by the function. After it has run, they point to the first and last entries in - the name-to-number table for the given name. The function itself - returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if - there are none. The format of the table is described above in the sec- - tion entitled Information about a pattern. Given all the relevant - entries for the name, you can extract each of their numbers, and hence - the captured data, if any. + the name-to-number table for the given name. The function itself + returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if + there are none. The format of the table is described above in the sec- + tion entitled Information about a pattern above. Given all the rele- + vant entries for the name, you can extract each of their numbers, and + hence the captured data, if any. FINDING ALL POSSIBLE MATCHES - The traditional matching function uses a similar algorithm to Perl, + The traditional matching function uses a similar algorithm to Perl, which stops when it finds the first match, starting at a given point in - the subject. If you want to find all possible matches, or the longest - possible match, consider using the alternative matching function (see - below) instead. If you cannot use the alternative function, but still - need to find all possible matches, you can kludge it up by making use + the subject. If you want to find all possible matches, or the longest + possible match, consider using the alternative matching function (see + below) instead. If you cannot use the alternative function, but still + need to find all possible matches, you can kludge it up by making use of the callout facility, which is described in the pcrecallout documen- tation. What you have to do is to insert a callout right at the end of the pat- - tern. When your callout function is called, extract and save the cur- - rent matched substring. Then return 1, which forces pcre_exec() to - backtrack and try other alternatives. Ultimately, when it runs out of + tern. When your callout function is called, extract and save the cur- + rent matched substring. Then return 1, which forces pcre_exec() to + backtrack and try other alternatives. Ultimately, when it runs out of matches, pcre_exec() will yield PCRE_ERROR_NOMATCH. +OBTAINING AN ESTIMATE OF STACK USAGE + + Matching certain patterns using pcre_exec() can use a lot of process + stack, which in certain environments can be rather limited in size. + Some users find it helpful to have an estimate of the amount of stack + that is used by pcre_exec(), to help them set recursion limits, as + described in the pcrestack documentation. The estimate that is output + by pcretest when called with the -m and -C options is obtained by call- + ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its + first five arguments. + + Normally, if its first argument is NULL, pcre_exec() immediately + returns the negative error code PCRE_ERROR_NULL, but with this special + combination of arguments, it returns instead a negative number whose + absolute value is the approximate stack frame size in bytes. (A nega- + tive number is used so that it is clear that no match has happened.) + The value is approximate because in some cases, recursive calls to + pcre_exec() occur when there are one or two additional variables on the + stack. + + If PCRE has been compiled to use the heap instead of the stack for + recursion, the value returned is the size of each block that is + obtained from the heap. + + MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, @@ -2703,26 +3313,26 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int options, int *ovector, int ovecsize, int *workspace, int wscount); - The function pcre_dfa_exec() is called to match a subject string - against a compiled pattern, using a matching algorithm that scans the - subject string just once, and does not backtrack. This has different - characteristics to the normal algorithm, and is not compatible with - Perl. Some of the features of PCRE patterns are not supported. Never- - theless, there are times when this kind of matching can be useful. For - a discussion of the two matching algorithms, and a list of features - that pcre_dfa_exec() does not support, see the pcrematching documenta- + The function pcre_dfa_exec() is called to match a subject string + against a compiled pattern, using a matching algorithm that scans the + subject string just once, and does not backtrack. This has different + characteristics to the normal algorithm, and is not compatible with + Perl. Some of the features of PCRE patterns are not supported. Never- + theless, there are times when this kind of matching can be useful. For + a discussion of the two matching algorithms, and a list of features + that pcre_dfa_exec() does not support, see the pcrematching documenta- tion. - The arguments for the pcre_dfa_exec() function are the same as for + The arguments for the pcre_dfa_exec() function are the same as for pcre_exec(), plus two extras. The ovector argument is used in a differ- - ent way, and this is described below. The other common arguments are - used in the same way as for pcre_exec(), so their description is not + ent way, and this is described below. The other common arguments are + used in the same way as for pcre_exec(), so their description is not repeated here. - The two additional arguments provide workspace for the function. The - workspace vector should contain at least 20 elements. It is used for + The two additional arguments provide workspace for the function. The + workspace vector should contain at least 20 elements. It is used for keeping track of multiple paths through the pattern tree. More - workspace will be needed for patterns and subjects where there are a + workspace will be needed for patterns and subjects where there are a lot of potential matches. Here is an example of a simple call to pcre_dfa_exec(): @@ -2744,55 +3354,55 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION Option bits for pcre_dfa_exec() - The unused bits of the options argument for pcre_dfa_exec() must be - zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- + The unused bits of the options argument for pcre_dfa_exec() must be + zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, - PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, - PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- - TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last - four of these are exactly the same as for pcre_exec(), so their + PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, + PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- + TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last + four of these are exactly the same as for pcre_exec(), so their description is not repeated here. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These have the same general effect as they do for pcre_exec(), but the - details are slightly different. When PCRE_PARTIAL_HARD is set for - pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- - ject is reached and there is still at least one matching possibility + These have the same general effect as they do for pcre_exec(), but the + details are slightly different. When PCRE_PARTIAL_HARD is set for + pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- + ject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, the return code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end - of the subject is reached, there have been no complete matches, but - there is still at least one matching possibility. The portion of the - string that was inspected when the longest partial match was found is - set as the first matching string in both cases. There is a more - detailed discussion of partial and multi-segment matching, with exam- + of the subject is reached, there have been no complete matches, but + there is still at least one matching possibility. The portion of the + string that was inspected when the longest partial match was found is + set as the first matching string in both cases. There is a more + detailed discussion of partial and multi-segment matching, with exam- ples, in the pcrepartial documentation. PCRE_DFA_SHORTEST - Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to + Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to stop as soon as it has found one match. Because of the way the alterna- - tive algorithm works, this is necessarily the shortest possible match + tive algorithm works, this is necessarily the shortest possible match at the first possible matching point in the subject string. PCRE_DFA_RESTART When pcre_dfa_exec() returns a partial match, it is possible to call it - again, with additional subject characters, and have it continue with - the same match. The PCRE_DFA_RESTART option requests this action; when - it is set, the workspace and wscount options must reference the same - vector as before because data about the match so far is left in them + again, with additional subject characters, and have it continue with + the same match. The PCRE_DFA_RESTART option requests this action; when + it is set, the workspace and wscount options must reference the same + vector as before because data about the match so far is left in them after a partial match. There is more discussion of this facility in the pcrepartial documentation. Successful returns from pcre_dfa_exec() - When pcre_dfa_exec() succeeds, it may have matched more than one sub- + When pcre_dfa_exec() succeeds, it may have matched more than one sub- string in the subject. Note, however, that all the matches from one run - of the function start at the same point in the subject. The shorter - matches are all initial substrings of the longer matches. For example, + of the function start at the same point in the subject. The shorter + matches are all initial substrings of the longer matches. For example, if the pattern <.*> @@ -2807,19 +3417,20 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION - On success, the yield of the function is a number greater than zero, - which is the number of matched substrings. The substrings themselves - are returned in ovector. Each string uses two elements; the first is - the offset to the start, and the second is the offset to the end. In - fact, all the strings have the same start offset. (Space could have - been saved by giving this only once, but it was decided to retain some - compatibility with the way pcre_exec() returns data, even though the + On success, the yield of the function is a number greater than zero, + which is the number of matched substrings. The substrings themselves + are returned in ovector. Each string uses two elements; the first is + the offset to the start, and the second is the offset to the end. In + fact, all the strings have the same start offset. (Space could have + been saved by giving this only once, but it was decided to retain some + compatibility with the way pcre_exec() returns data, even though the meaning of the strings is different.) The strings are returned in reverse order of length; that is, the long- - est matching string is given first. If there were too many matches to - fit into ovector, the yield of the function is zero, and the vector is - filled with the longest matches. + est matching string is given first. If there were too many matches to + fit into ovector, the yield of the function is zero, and the vector is + filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() + can use the entire ovector for returning matched strings. Error returns from pcre_dfa_exec() @@ -2843,26 +3454,35 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION PCRE_ERROR_DFA_UMLIMIT (-18) This return is given if pcre_dfa_exec() is called with an extra block - that contains a setting of the match_limit field. This is not supported - (it is meaningless). + that contains a setting of the match_limit or match_limit_recursion + fields. This is not supported (these fields are meaningless for DFA + matching). PCRE_ERROR_DFA_WSSIZE (-19) - This return is given if pcre_dfa_exec() runs out of space in the + This return is given if pcre_dfa_exec() runs out of space in the workspace vector. PCRE_ERROR_DFA_RECURSE (-20) - When a recursive subpattern is processed, the matching function calls - itself recursively, using private vectors for ovector and workspace. - This error is given if the output vector is not large enough. This + When a recursive subpattern is processed, the matching function calls + itself recursively, using private vectors for ovector and workspace. + This error is given if the output vector is not large enough. This should be extremely rare, as a vector of size 1000 is used. + PCRE_ERROR_DFA_BADRESTART (-30) + + When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some + plausibility checks are made on the contents of the workspace, which + should contain data about the previous partial match. If any of these + checks fail, this error is given. + SEE ALSO - pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepar- - tial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3). + pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematch- + ing(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3), + pcrestack(3). AUTHOR @@ -2874,8 +3494,8 @@ AUTHOR REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 17 June 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -2890,24 +3510,27 @@ PCRE CALLOUTS int (*pcre_callout)(pcre_callout_block *); + int (*pcre16_callout)(pcre16_callout_block *); + PCRE provides a feature called "callout", which is a means of temporar- ily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting - its entry point in the global variable pcre_callout. By default, this - variable contains NULL, which disables all calling out. + its entry point in the global variable pcre_callout (pcre16_callout for + the 16-bit library). By default, this variable contains NULL, which + disables all calling out. - Within a regular expression, (?C) indicates the points at which the - external function is to be called. Different callout points can be - identified by putting a number less than 256 after the letter C. The - default value is zero. For example, this pattern has two callout + Within a regular expression, (?C) indicates the points at which the + external function is to be called. Different callout points can be + identified by putting a number less than 256 after the letter C. The + default value is zero. For example, this pattern has two callout points: (?C1)abc(?C2)def - If the PCRE_AUTO_CALLOUT option bit is set when pcre_compile() or - pcre_compile2() is called, PCRE automatically inserts callouts, all - with number 255, before each item in the pattern. For example, if - PCRE_AUTO_CALLOUT is used with the pattern + If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, + PCRE automatically inserts callouts, all with number 255, before each + item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the + pattern A(\d{2}|--) @@ -2915,62 +3538,68 @@ PCRE CALLOUTS (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) - Notice that there is a callout before and after each parenthesis and - alternation bar. Automatic callouts can be used for tracking the - progress of pattern matching. The pcretest command has an option that - sets automatic callouts; when it is used, the output indicates how the - pattern is matched. This is useful information when you are trying to + Notice that there is a callout before and after each parenthesis and + alternation bar. Automatic callouts can be used for tracking the + progress of pattern matching. The pcretest command has an option that + sets automatic callouts; when it is used, the output indicates how the + pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern. + The use of callouts in a pattern makes it ineligible for optimization + by the just-in-time compiler. Studying such a pattern with the + PCRE_STUDY_JIT_COMPILE option always fails. + MISSING CALLOUTS - You should be aware that, because of optimizations in the way PCRE - matches patterns by default, callouts sometimes do not happen. For + You should be aware that, because of optimizations in the way PCRE + matches patterns by default, callouts sometimes do not happen. For example, if the pattern is ab(?C4)cd PCRE knows that any matching string must contain the letter "d". If the - subject string is "abyz", the lack of "d" means that matching doesn't - ever start, and the callout is never reached. However, with "abyd", + subject string is "abyz", the lack of "d" means that matching doesn't + ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed. - If the pattern is studied, PCRE knows the minimum length of a matching - string, and will immediately give a "no match" return without actually - running a match if the subject is not long enough, or, for unanchored + If the pattern is studied, PCRE knows the minimum length of a matching + string, and will immediately give a "no match" return without actually + running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough. - You can disable these optimizations by passing the PCRE_NO_START_OPTI- - MIZE option to pcre_compile(), pcre_exec(), or pcre_dfa_exec(), or by - starting the pattern with (*NO_START_OPT). This slows down the matching - process, but does ensure that callouts such as the example above are - obeyed. + You can disable these optimizations by passing the PCRE_NO_START_OPTI- + MIZE option to the matching function, or by starting the pattern with + (*NO_START_OPT). This slows down the matching process, but does ensure + that callouts such as the example above are obeyed. THE CALLOUT INTERFACE During matching, when PCRE reaches a callout point, the external func- - tion defined by pcre_callout is called (if it is set). This applies to - both the pcre_exec() and the pcre_dfa_exec() matching functions. The - only argument to the callout function is a pointer to a pcre_callout - block. This structure contains the following fields: + tion defined by pcre_callout or pcre16_callout is called (if it is + set). This applies to both normal and DFA matching. The only argument + to the callout function is a pointer to a pcre_callout or pcre16_call- + out block. These structures contains the following fields: - int version; - int callout_number; - int *offset_vector; - const char *subject; - int subject_length; - int start_match; - int current_position; - int capture_top; - int capture_last; - void *callout_data; - int pattern_position; - int next_item_length; + int version; + int callout_number; + int *offset_vector; + const char *subject; (8-bit version) + PCRE_SPTR16 subject; (16-bit version) + int subject_length; + int start_match; + int current_position; + int capture_top; + int capture_last; + void *callout_data; + int pattern_position; + int next_item_length; + const unsigned char *mark; (8-bit version) + const PCRE_UCHAR16 *mark; (16-bit version) The version field is an integer containing the version number of the - block format. The initial version was 0; the current version is 1. The + block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. @@ -2979,14 +3608,14 @@ THE CALLOUT INTERFACE outs, and 255 for automatically generated callouts). The offset_vector field is a pointer to the vector of offsets that was - passed by the caller to pcre_exec() or pcre_dfa_exec(). When - pcre_exec() is used, the contents can be inspected in order to extract - substrings that have been matched so far, in the same way as for - extracting substrings after a match has completed. For pcre_dfa_exec() - this field is not useful. + passed by the caller to the matching function. When pcre_exec() or + pcre16_exec() is used, the contents can be inspected, in order to + extract substrings that have been matched so far, in the same way as + for extracting substrings after a match has completed. For the DFA + matching functions, this field is not useful. The subject and subject_length fields contain copies of the values that - were passed to pcre_exec(). + were passed to the matching function. The start_match field normally contains the offset within the subject at which the current match attempt started. However, if the escape @@ -2998,38 +3627,46 @@ THE CALLOUT INTERFACE The current_position field contains the offset within the subject of the current match pointer. - When the pcre_exec() function is used, the capture_top field contains - one more than the number of the highest numbered captured substring so - far. If no substrings have been captured, the value of capture_top is - one. This is always the case when pcre_dfa_exec() is used, because it - does not support captured substrings. + When the pcre_exec() or pcre16_exec() is used, the capture_top field + contains one more than the number of the highest numbered captured sub- + string so far. If no substrings have been captured, the value of cap- + ture_top is one. This is always the case when the DFA functions are + used, because they do not support captured substrings. The capture_last field contains the number of the most recently cap- tured substring. If no substrings have been captured, its value is -1. - This is always the case when pcre_dfa_exec() is used. + This is always the case for the DFA matching functions. - The callout_data field contains a value that is passed to pcre_exec() - or pcre_dfa_exec() specifically so that it can be passed back in call- - outs. It is passed in the pcre_callout field of the pcre_extra data + The callout_data field contains a value that is passed to a matching + function specifically so that it can be passed back in callouts. It is + passed in the callout_data field of a pcre_extra or pcre16_extra data structure. If no such data was passed, the value of callout_data in a - pcre_callout block is NULL. There is a description of the pcre_extra - structure in the pcreapi documentation. + callout block is NULL. There is a description of the pcre_extra struc- + ture in the pcreapi documentation. - The pattern_position field is present from version 1 of the pcre_call- - out structure. It contains the offset to the next item to be matched in - the pattern string. + The pattern_position field is present from version 1 of the callout + structure. It contains the offset to the next item to be matched in the + pattern string. - The next_item_length field is present from version 1 of the pcre_call- - out structure. It contains the length of the next item to be matched in - the pattern string. When the callout immediately precedes an alterna- - tion bar, a closing parenthesis, or the end of the pattern, the length - is zero. When the callout precedes an opening parenthesis, the length - is that of the entire subpattern. + The next_item_length field is present from version 1 of the callout + structure. It contains the length of the next item to be matched in the + pattern string. When the callout immediately precedes an alternation + bar, a closing parenthesis, or the end of the pattern, the length is + zero. When the callout precedes an opening parenthesis, the length is + that of the entire subpattern. The pattern_position and next_item_length fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts. + The mark field is present from version 2 of the callout structure. In + callouts from pcre_exec() or pcre16_exec() it contains a pointer to the + zero-terminated name of the most recently passed (*MARK), (*PRUNE), or + (*THEN) item in the match, or NULL if no such items have been passed. + Instances of (*PRUNE) or (*THEN) without a name do not obliterate a + previous (*MARK). In callouts from the DFA matching functions this + field always contains NULL. + RETURN VALUES @@ -3037,8 +3674,8 @@ RETURN VALUES is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had - failed. If the value is less than zero, the match is abandoned, and - pcre_exec() or pcre_dfa_exec() returns the negative value. + failed. If the value is less than zero, the match is abandoned, the + matching function returns the negative value. Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a stan- @@ -3056,8 +3693,8 @@ AUTHOR REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 08 Janurary 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -3074,43 +3711,53 @@ DIFFERENCES BETWEEN PCRE AND PERL handle regular expressions. The differences described here are with respect to Perl versions 5.10 and above. - 1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details - of what it does have are given in the section on UTF-8 support in the - main pcre page. + 1. PCRE has only a subset of Perl's Unicode support. Details of what it + does have are given in the pcreunicode page. - 2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl - permits them, but they do not mean what you might think. For example, - (?!a){3} does not assert that the next three characters are not "a". It - just asserts that the next character is not "a" three times. + 2. PCRE allows repeat quantifiers only on parenthesized assertions, but + they do not mean what you might think. For example, (?!a){3} does not + assert that the next three characters are not "a". It just asserts that + the next character is not "a" three times (in principle: PCRE optimizes + this to run the assertion just once). Perl allows repeat quantifiers on + other assertions such as \b, but these do not seem to have any use. - 3. Capturing subpatterns that occur inside negative lookahead 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 + 3. Capturing subpatterns that occur inside negative lookahead asser- + tions are counted, but their entries in the offsets vector are never + set. Perl sets its numerical variables from any such patterns that are matched before the assertion fails to match something (thereby succeed- - ing), but only if the negative lookahead assertion contains just one + ing), but only if the negative lookahead assertion contains just one branch. - 4. Though binary zero characters are supported in the subject string, + 4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a nor- mal C string, terminated by zero. The escape sequence \0 can be used in the pattern to represent a binary zero. - 5. The following Perl escape sequences are not supported: \l, \u, \L, - \U, and \N. In fact these are implemented by Perl's general string-han- - dling and are not part of its pattern matching engine. If any of these - are encountered by PCRE, an error is generated. + 5. The following Perl escape sequences are not supported: \l, \u, \L, + \U, and \N when followed by a character name or Unicode value. (\N on + its own, matching a non-newline character, is supported.) In fact these + are implemented by Perl's general string-handling and are not part of + its pattern matching engine. If any of these are encountered by PCRE, + an error is generated by default. However, if the PCRE_JAVASCRIPT_COM- + PAT option is set, \U and \u are interpreted as JavaScript interprets + them. - 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE - is built with Unicode character property support. The properties that - can be tested with \p and \P are limited to the general category prop- - erties such as Lu and Nd, script names such as Greek or Han, and the - derived properties Any and L&. PCRE does support the Cs (surrogate) - property, which Perl does not; the Perl documentation says "Because + 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE + is built with Unicode character property support. The properties that + can be tested with \p and \P are limited to the general category prop- + erties such as Lu and Nd, script names such as Greek or Han, and the + derived properties Any and L&. PCRE does support the Cs (surrogate) + property, which Perl does not; the Perl documentation says "Because Perl hides the need for the user to understand the internal representa- - tion of Unicode characters, there is no need to implement the somewhat + tion of Unicode characters, there is no need to implement the somewhat messy concept of surrogates." - 7. PCRE does support the \Q...\E escape for quoting substrings. Charac- + 7. PCRE implements a simpler version of \X than Perl, which changed to + make \X match what Unicode calls an "extended grapheme cluster". This + is more complicated than an extended Unicode sequence, which is what + PCRE matches. + + 8. PCRE does support the \Q...\E escape for quoting substrings. Charac- ters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE @@ -3126,55 +3773,70 @@ DIFFERENCES BETWEEN PCRE AND PERL The \Q...\E sequence is recognized both inside and outside character classes. - 8. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) + 9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pat- tern matching. See the pcrecallout documentation for details. - 9. Subpatterns that are called recursively or as "subroutines" are - always treated as atomic groups in PCRE. This is like Python, but - unlike Perl. There is a discussion of an example that explains this in - more detail in the section on recursion differences from Perl in the - pcrepattern page. + 10. Subpatterns that are called as subroutines (whether or not recur- + sively) are always treated as atomic groups in PCRE. This is like + Python, but unlike Perl. Captured values that are set outside a sub- + routine call can be reference from inside in PCRE, but not in Perl. + There is a discussion that explains these differences in more detail in + the section on recursion differences from Perl in the pcrepattern page. - 10. There are some differences that are concerned with the settings of - captured strings when part of a pattern is repeated. For example, - matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 + 11. If any of the backtracking control verbs are used in an assertion + or in a subpattern that is called as a subroutine (whether or not + recursively), their effect is confined to that subpattern; it does not + extend to the surrounding pattern. This is not always the case in Perl. + In particular, if (*THEN) is present in a group that is called as a + subroutine, its action is limited to that group, even if the group does + not contain any | characters. There is one exception to this: the name + from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success- + ful positive assertion is passed back when a match succeeds (compare + capturing parentheses in assertions). Note that such subpatterns are + processed as anchored at the point where they are tested. + + 12. There are some differences that are concerned with the settings of + captured strings when part of a pattern is repeated. For example, + matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". - 11. PCRE's handling of duplicate subpattern numbers and duplicate sub- + 13. PCRE's handling of duplicate subpattern numbers and duplicate sub- pattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external ta- - ble to translate between numbers and names. In particular, a pattern - such as (?|(?A)|(?A)|(?\r\n|\n|\x0b|\f|\r|\x85) This is an example of an "atomic group", details of which are given below. This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, - U+000A), VT (vertical tab, U+000B), FF (formfeed, U+000C), CR (carriage - return, U+000D), or NEL (next line, U+0085). The two-character sequence - is treated as a single unit that cannot be split. + U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (car- + riage return, U+000D), or NEL (next line, U+0085). The two-character + sequence is treated as a single unit that cannot be split. - In UTF-8 mode, two additional characters whose codepoints are greater + In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph sepa- rator, U+2029). Unicode character property support is not needed for these characters to be recognized. @@ -3656,28 +4357,28 @@ BACKSLASH (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence - These override the default and the options given to pcre_compile() or - pcre_compile2(), but they can be overridden by options given to - pcre_exec() or pcre_dfa_exec(). Note that these special settings, which - are not Perl-compatible, are recognized only at the very start of a - pattern, and that they must be in upper case. If more than one of them - is present, the last one is used. They can be combined with a change of + These override the default and the options given to the compiling func- + tion, but they can themselves be overridden by options given to a + matching function. Note that these special settings, which are not + Perl-compatible, are recognized only at the very start of a pattern, + and that they must be in upper case. If more than one of them is + present, the last one is used. They can be combined with a change of newline convention; for example, a pattern can start with: (*ANY)(*BSR_ANYCRLF) - They can also be combined with the (*UTF8) or (*UCP) special sequences. - Inside a character class, \R is treated as an unrecognized escape - sequence, and so matches the letter "R" by default, but causes an error - if PCRE_EXTRA is set. + They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special + sequences. Inside a character class, \R is treated as an unrecognized + escape sequence, and so matches the letter "R" by default, but causes + an error if PCRE_EXTRA is set. Unicode character properties When PCRE is built with Unicode character property support, three addi- tional escape sequences that match characters with specific properties - are available. When not in UTF-8 mode, these sequences are of course - limited to testing characters whose codepoints are less than 256, but - they do work in this mode. The extra escape sequences are: + are available. When in 8-bit non-UTF-8 mode, these sequences are of + course limited to testing characters whose codepoints are less than + 256, but they do work in this mode. The extra escape sequences are: \p{xx} a character with the xx property \P{xx} a character without the xx property @@ -3700,20 +4401,22 @@ BACKSLASH Those that are not part of an identified script are lumped together as "Common". The current list of scripts is: - Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille, - Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, - Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp- - tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, - Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe- - rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, - Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, - Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, - Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, - Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, - Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian, - Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, - Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, - Ugaritic, Vai, Yi. + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, + Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, + Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, + Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- + tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, + Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, + Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, + Yi. Each character has exactly one Unicode general category property, spec- ified by a two-letter abbreviation. For compatibility with Perl, nega- @@ -3780,45 +4483,50 @@ BACKSLASH classified as a modifier or "other". The Cs (Surrogate) property applies only to characters in the range - U+D800 to U+DFFF. Such characters are not valid in UTF-8 strings (see - RFC 3629) and so cannot be tested by PCRE, unless UTF-8 validity check- - ing has been turned off (see the discussion of PCRE_NO_UTF8_CHECK in - the pcreapi page). Perl does not support the Cs property. + U+D800 to U+DFFF. Such characters are not valid in Unicode strings and + so cannot be tested by PCRE, unless UTF validity checking has been + turned off (see the discussion of PCRE_NO_UTF8_CHECK and + PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs + property. - The long synonyms for property names that Perl supports (such as - \p{Letter}) are not supported by PCRE, nor is it permitted to prefix + The long synonyms for property names that Perl supports (such as + \p{Letter}) are not supported by PCRE, nor is it permitted to prefix any of these properties with "Is". No character that is in the Unicode table has the Cn (unassigned) prop- erty. Instead, this property is assumed for any code point that is not in the Unicode table. - Specifying caseless matching does not affect these escape sequences. + Specifying caseless matching does not affect these escape sequences. For example, \p{Lu} always matches only upper case letters. - The \X escape matches any number of Unicode characters that form an + The \X escape matches any number of Unicode characters that form an extended Unicode sequence. \X is equivalent to (?>\PM\pM*) - That is, it matches a character without the "mark" property, followed - by zero or more characters with the "mark" property, and treats the - sequence as an atomic group (see below). Characters with the "mark" - property are typically accents that affect the preceding character. - None of them have codepoints less than 256, so in non-UTF-8 mode \X - matches any one character. + That is, it matches a character without the "mark" property, followed + by zero or more characters with the "mark" property, and treats the + sequence as an atomic group (see below). Characters with the "mark" + property are typically accents that affect the preceding character. + None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode + \X matches any one character. - Matching characters by Unicode property is not fast, because PCRE has - to search a structure that contains data for over fifteen thousand + Note that recent versions of Perl have changed \X to match what Unicode + calls an "extended grapheme cluster", which has a more complicated def- + inition. + + Matching characters by Unicode property is not fast, because PCRE has + to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and - \w do not use Unicode properties in PCRE by default, though you can - make them do so by setting the PCRE_UCP option for pcre_compile() or by - starting the pattern with (*UCP). + \w do not use Unicode properties in PCRE by default, though you can + make them do so by setting the PCRE_UCP option or by starting the pat- + tern with (*UCP). PCRE's additional properties - As well as the standard Unicode properties described in the previous - section, PCRE supports four more that make it possible to convert tra- + As well as the standard Unicode properties described in the previous + section, PCRE supports four more that make it possible to convert tra- ditional escape sequences such as \w and \s and POSIX character classes to use Unicode properties. PCRE uses these non-standard, non-Perl prop- erties internally when PCRE_UCP is set. They are: @@ -3828,40 +4536,40 @@ BACKSLASH Xsp Any Perl space character Xwd Any Perl "word" character - Xan matches characters that have either the L (letter) or the N (num- - ber) property. Xps matches the characters tab, linefeed, vertical tab, - formfeed, or carriage return, and any other character that has the Z + Xan matches characters that have either the L (letter) or the N (num- + ber) property. Xps matches the characters tab, linefeed, vertical tab, + form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. Resetting the match start - The escape sequence \K causes any previously matched characters not to + The escape sequence \K causes any previously matched characters not to be included in the final matched sequence. For example, the pattern: foo\Kbar - matches "foobar", but reports that it has matched "bar". This feature - is similar to a lookbehind assertion (described below). However, in - this case, the part of the subject before the real match does not have - to be of fixed length, as lookbehind assertions do. The use of \K does - not interfere with the setting of captured substrings. For example, + matches "foobar", but reports that it has matched "bar". This feature + is similar to a lookbehind assertion (described below). However, in + this case, the part of the subject before the real match does not have + to be of fixed length, as lookbehind assertions do. The use of \K does + not interfere with the setting of captured substrings. For example, when the pattern (foo)\Kbar matches "foobar", the first substring is still set to "foo". - Perl documents that the use of \K within assertions is "not well - defined". In PCRE, \K is acted upon when it occurs inside positive + Perl documents that the use of \K within assertions is "not well + defined". In PCRE, \K is acted upon when it occurs inside positive assertions, but is ignored in negative assertions. Simple assertions - The final use of backslash is for certain simple assertions. An asser- - tion specifies a condition that has to be met at a particular point in - a match, without consuming any characters from the subject string. The - use of subpatterns for more complicated assertions is described below. + The final use of backslash is for certain simple assertions. An asser- + tion specifies a condition that has to be met at a particular point in + a match, without consuming any characters from the subject string. The + use of subpatterns for more complicated assertions is described below. The backslashed assertions are: \b matches at a word boundary @@ -3872,49 +4580,49 @@ 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 - UTF-8 mode, the meanings of \w and \W can be changed by setting the - PCRE_UCP option. When this is done, it also affects \b and \B. Neither - PCRE nor Perl has a separate "start of word" or "end of word" metase- - quence. However, whatever follows \b normally determines which it is. + A word boundary is a position in the subject string where the current + character and the previous character do not both match \w or \W (i.e. + one matches \w and the other matches \W), or the start or end of the + string if the first or last character matches \w, respectively. In a + UTF mode, the meanings of \w and \W can be changed by setting the + PCRE_UCP option. When this is done, it also affects \b and \B. Neither + PCRE nor Perl has a separate "start of word" or "end of word" metase- + quence. However, whatever follows \b normally determines which it is. For example, the fragment \ba matches "a" at the start of a word. - The \A, \Z, and \z assertions differ from the traditional circumflex + The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match - at the very start and end of the subject string, whatever options are - set. Thus, they are independent of multiline mode. These three asser- + at the very start and end of the subject string, whatever options are + set. Thus, they are independent of multiline mode. These three asser- tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which - affect only the behaviour of the circumflex and dollar metacharacters. - However, if the startoffset argument of pcre_exec() is non-zero, indi- + affect only the behaviour of the circumflex and dollar metacharacters. + However, if the startoffset argument of pcre_exec() is non-zero, indi- cating that matching is to start at a point other than the beginning of - the subject, \A can never match. The difference between \Z and \z is + the subject, \A can never match. The difference between \Z and \z is that \Z matches before a newline at the end of the string as well as at the very end, whereas \z matches only at the end. - The \G assertion is true only when the current matching position is at - the start point of the match, as specified by the startoffset argument - of pcre_exec(). It differs from \A when the value of startoffset is - non-zero. By calling pcre_exec() multiple times with appropriate argu- + The \G assertion is true only when the current matching position is at + the start point of the match, as specified by the startoffset argument + of pcre_exec(). It differs from \A when the value of startoffset is + non-zero. By calling pcre_exec() multiple times with appropriate argu- ments, you can mimic Perl's /g option, and it is in this kind of imple- mentation where \G can be useful. - Note, however, that PCRE's interpretation of \G, as the start of the + Note, however, that PCRE's interpretation of \G, as the start of the current match, is subtly different from Perl's, which defines it as the - end of the previous match. In Perl, these can be different when the - previously matched string was empty. Because PCRE does just one match + end of the previous match. In Perl, these can be different when the + previously matched string was empty. Because PCRE does just one match at a time, it cannot reproduce this behaviour. - If all the alternatives of a pattern begin with \G, the expression is + If all the alternatives of a pattern begin with \G, the expression is anchored to the starting match position, and the "anchored" flag is set in the compiled regular expression. @@ -3922,60 +4630,59 @@ BACKSLASH CIRCUMFLEX AND DOLLAR Outside a character class, in the default matching mode, the circumflex - character is an assertion that is true only if the current matching - point is at the start of the subject string. If the startoffset argu- - ment of pcre_exec() is non-zero, circumflex can never match if the - PCRE_MULTILINE option is unset. Inside a character class, circumflex + character is an assertion that is true only if the current matching + point is at the start of the subject string. If the startoffset argu- + ment of pcre_exec() is non-zero, circumflex can never match if the + PCRE_MULTILINE option is unset. Inside a character class, circumflex has an entirely different meaning (see below). - Circumflex need not be the first character of the pattern if a number - of alternatives are involved, but it should be the first thing in each - alternative in which it appears if the pattern is ever to match that - branch. If all possible alternatives start with a circumflex, that is, - if the pattern is constrained to match only at the start of the sub- - ject, it is said to be an "anchored" pattern. (There are also other + Circumflex need not be the first character of the pattern if a number + of alternatives are involved, but it should be the first thing in each + alternative in which it appears if the pattern is ever to match that + branch. If all possible alternatives start with a circumflex, that is, + if the pattern is constrained to match only at the start of the sub- + ject, it is said to be an "anchored" pattern. (There are also other constructs that can cause a pattern to be anchored.) - A dollar character is an assertion that is true only if the current - matching point is at the end of the subject string, or immediately + A dollar character is an assertion that is true only if the current + matching point is at the end of the subject string, or immediately before a newline at the end of the string (by default). Dollar need not - be the last character of the pattern if a number of alternatives are - involved, but it should be the last item in any branch in which it + be the last character of the pattern if a number of alternatives are + involved, but it should be the last item in any branch in which it appears. Dollar has no special meaning in a character class. - The meaning of dollar can be changed so that it matches only at the - very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at + The meaning of dollar can be changed so that it matches only at the + very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at compile time. This does not affect the \Z assertion. The meanings of the circumflex and dollar characters are changed if the - PCRE_MULTILINE option is set. When this is the case, a circumflex - matches immediately after internal newlines as well as at the start of - the subject string. It does not match after a newline that ends the - string. A dollar matches before any newlines in the string, as well as - at the very end, when PCRE_MULTILINE is set. When newline is specified - as the two-character sequence CRLF, isolated CR and LF characters do + PCRE_MULTILINE option is set. When this is the case, a circumflex + matches immediately after internal newlines as well as at the start of + the subject string. It does not match after a newline that ends the + string. A dollar matches before any newlines in the string, as well as + at the very end, when PCRE_MULTILINE is set. When newline is specified + as the two-character sequence CRLF, isolated CR and LF characters do not indicate newlines. - For example, the pattern /^abc$/ matches the subject string "def\nabc" - (where \n represents a newline) in multiline mode, but not otherwise. - Consequently, patterns that are anchored in single line mode because - all branches start with ^ are not anchored in multiline mode, and a - match for circumflex is possible when the startoffset argument of - pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if + For example, the pattern /^abc$/ matches the subject string "def\nabc" + (where \n represents a newline) in multiline mode, but not otherwise. + Consequently, patterns that are anchored in single line mode because + all branches start with ^ are not anchored in multiline mode, and a + match for circumflex is possible when the startoffset argument of + pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is set. - Note that the sequences \A, \Z, and \z can be used to match the start - and end of the subject in both modes, and if all branches of a pattern - start with \A it is always anchored, whether or not PCRE_MULTILINE is + Note that the sequences \A, \Z, and \z can be used to match the start + and end of the subject in both modes, and if all branches of a pattern + start with \A it is always anchored, whether or not PCRE_MULTILINE is set. FULL STOP (PERIOD, DOT) AND \N Outside a character class, a dot in the pattern matches any one charac- - ter in the subject string except (by default) a character that signi- - fies the end of a line. In UTF-8 mode, the matched character may be - more than one byte long. + ter in the subject string except (by default) a character that signi- + fies the end of a line. When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does @@ -3995,23 +4702,47 @@ FULL STOP (PERIOD, DOT) AND \N The escape sequence \N behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any - character except one that signifies the end of a line. + character except one that signifies the end of a line. Perl also uses + \N to match characters by name; PCRE does not support this. -MATCHING A SINGLE BYTE +MATCHING A SINGLE DATA UNIT - Outside a character class, the escape sequence \C matches any one byte, - both in and out of UTF-8 mode. Unlike a dot, it always matches any - line-ending characters. The feature is provided in Perl in order to - match individual bytes in UTF-8 mode. Because it breaks up UTF-8 char- - acters into individual bytes, the rest of the string may start with a - malformed UTF-8 character. For this reason, the \C escape sequence is - best avoided. + Outside a character class, the escape sequence \C matches any one data + unit, whether or not a UTF mode is set. In the 8-bit library, one data + unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a + dot, \C always matches line-ending characters. The feature is provided + in Perl in order to match individual bytes in UTF-8 mode, but it is + unclear how it can usefully be used. Because \C breaks up characters + into individual data units, matching one unit with \C in a UTF mode + means that the rest of the string may start with a malformed UTF char- + acter. This has undefined results, because PCRE assumes that it is + dealing with valid UTF strings (and by default it checks this at the + start of processing unless the PCRE_NO_UTF8_CHECK or + PCRE_NO_UTF16_CHECK option is used). PCRE does not allow \C to appear in lookbehind assertions (described - below), because in UTF-8 mode this would make it impossible to calcu- + below) in a UTF mode, because this would make it impossible to calcu- late the length of the lookbehind. + In general, the \C escape sequence is best avoided. However, one way of + using it that avoids the problem of malformed UTF characters is to use + a lookahead to check the length of the next character, as in this pat- + tern, which could be used with a UTF-8 string (ignore white space and + line breaks): + + (?| (?=[\x00-\x7f])(\C) | + (?=[\x80-\x{7ff}])(\C)(\C) | + (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) | + (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C)) + + A group that starts with (?| resets the capturing parentheses numbers + in each alternative (see "Duplicate Subpattern Numbers" below). The + assertions at the start of each branch check the next UTF-8 character + for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The + character's individual bytes are then captured by the appropriate num- + ber of groups. + SQUARE BRACKETS AND CHARACTER CLASSES @@ -4019,109 +4750,109 @@ 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 UTF-8 - mode, the character may be more than one byte long. A matched character - must be in the set of characters defined by the class, unless the first - character in the class definition is a circumflex, in which case the - subject character must not be in the set defined by the class. If a - circumflex is actually required as a member of the class, ensure it is - not the first character, or escape it with a backslash. + A character class matches a single character in the subject. In a UTF + mode, the character may be more than one data unit long. A matched + character must be in the set of characters defined by the class, unless + the first character in the class definition is a circumflex, in which + case the subject character must not be in the set defined by the class. + If a circumflex is actually required as a member of the class, ensure + it is not the first character, or escape it with a backslash. - For example, the character class [aeiou] matches any lower case vowel, - while [^aeiou] matches any character that is not a lower case vowel. + For example, the character class [aeiou] matches any lower case vowel, + while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the - characters that are in the class by enumerating those that are not. A - class that starts with a circumflex is not an assertion; it still con- - sumes a character from the subject string, and therefore it fails if + characters that are in the class by enumerating those that are not. A + class that starts with a circumflex is not an assertion; it still con- + sumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string. - In UTF-8 mode, characters with values greater than 255 can be included - in a class as a literal string of bytes, or by using the \x{ escaping - mechanism. + In UTF-8 (UTF-16) mode, characters with values greater than 255 + (0xffff) can be included in a class as a literal string of data units, + or by using the \x{ escaping mechanism. - When caseless matching is set, any letters in a class represent both - their upper case and lower case versions, so for example, a caseless - [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not - match "A", whereas a caseful version would. In UTF-8 mode, PCRE always - understands the concept of case for characters whose values are less - than 128, so caseless matching is always possible. For characters with - higher values, the concept of case is supported if PCRE is compiled - with Unicode property support, but not otherwise. If you want to use - caseless matching in UTF8-mode for characters 128 and above, you must - ensure that PCRE is compiled with Unicode property support as well as - with UTF-8 support. + 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 + The minus (hyphen) character can be used to specify a range of charac- + ters in a character class. For example, [d-m] matches any letter + between d and m, inclusive. If a minus character is required in a + class, it must be escaped with a backslash or appear in a position + where it cannot be interpreted as indicating a range, typically as the first or last character in the class. It is not possible to have the literal character "]" as the end charac- - ter of a range. A pattern such as [W-]46] is interpreted as a class of - two characters ("W" and "-") followed by a literal string "46]", so it - would match "W46]" or "-46]". However, if the "]" is escaped with a - backslash it is interpreted as the end of range, so [W-\]46] is inter- - preted as a class containing a range followed by two other characters. - The octal or hexadecimal representation of "]" can also be used to end + ter of a range. A pattern such as [W-]46] is interpreted as a class of + two characters ("W" and "-") followed by a literal string "46]", so it + would match "W46]" or "-46]". However, if the "]" is escaped with a + backslash it is interpreted as the end of range, so [W-\]46] is inter- + preted as a class containing a range followed by two other characters. + The octal or hexadecimal representation of "]" can also be used to end a range. - Ranges operate in the collating sequence of character values. They can - also be used for characters specified numerically, for example - [\000-\037]. In UTF-8 mode, ranges can include characters whose values - are greater than 255, for example [\x{100}-\x{2ff}]. + Ranges operate in the collating sequence of character values. They can + also be used for characters specified numerically, for example + [\000-\037]. Ranges can include any characters that are valid for the + current mode. If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent - to [][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if - character tables for a French locale are in use, [\xc8-\xcb] matches - accented E characters in both cases. In UTF-8 mode, PCRE supports the - concept of case for characters with values greater than 128 only when + to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if + character tables for a French locale are in use, [\xc8-\xcb] matches + accented E characters in both cases. In UTF modes, PCRE supports the + concept of case for characters with values greater than 128 only when it is compiled with Unicode property support. - The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, + The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, \w, and \W may appear in a character class, and add the characters that - they match to the class. For example, [\dABCDEF] matches any hexadeci- - mal digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of - \d, \s, \w and their upper case partners, just as it does when they - appear outside a character class, as described in the section entitled + they match to the class. For example, [\dABCDEF] matches any hexadeci- + mal digit. In UTF modes, the PCRE_UCP option affects the meanings of + \d, \s, \w and their upper case partners, just as it does when they + appear outside a character class, as described in the section entitled "Generic character types" above. The escape sequence \b has a different - meaning inside a character class; it matches the backspace character. - The sequences \B, \N, \R, and \X are not special inside a character - class. Like any other unrecognized escape sequences, they are treated - as the literal characters "B", "N", "R", and "X" by default, but cause + meaning inside a character class; it matches the backspace character. + The sequences \B, \N, \R, and \X are not special inside a character + class. Like any other unrecognized escape sequences, they are treated + as the literal characters "B", "N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. - A circumflex can conveniently be used with the upper case character - types to specify a more restricted set of characters than the matching - lower case type. For example, the class [^\W_] matches any letter or + A circumflex can conveniently be used with the upper case character + types to specify a more restricted set of characters than the matching + lower case type. For example, the class [^\W_] matches any letter or digit, but not underscore, whereas [\w] includes underscore. A positive character class should be read as "something OR something OR ..." and a negative class as "NOT something AND NOT something AND NOT ...". - The only metacharacters that are recognized in character classes are - backslash, hyphen (only where it can be interpreted as specifying a - range), circumflex (only at the start), opening square bracket (only - when it can be interpreted as introducing a POSIX class name - see the - next section), and the terminating closing square bracket. However, + The only metacharacters that are recognized in character classes are + backslash, hyphen (only where it can be interpreted as specifying a + range), circumflex (only at the start), opening square bracket (only + when it can be interpreted as introducing a POSIX class name - see the + next section), and the terminating closing square bracket. However, escaping other non-alphanumeric characters does no harm. POSIX CHARACTER CLASSES Perl supports the POSIX notation for character classes. This uses names - enclosed by [: and :] within the enclosing square brackets. PCRE also + enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example, [01[:alpha:]%] @@ -4144,24 +4875,24 @@ POSIX CHARACTER CLASSES word "word" characters (same as \w) xdigit hexadecimal digits - The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), - and space (32). Notice that this list includes the VT character (code + The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), + and space (32). Notice that this list includes the VT character (code 11). This makes "space" different to \s, which does not include VT (for Perl compatibility). - The name "word" is a Perl extension, and "blank" is a GNU extension - from Perl 5.8. Another Perl extension is negation, which is indicated + The name "word" is a Perl extension, and "blank" is a GNU extension + from Perl 5.8. Another Perl extension is negation, which is indicated by a ^ character after the colon. For example, [12[:^digit:]] - matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the + matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. - By default, in UTF-8 mode, characters with values greater than 128 do - not match any of the POSIX character classes. However, if the PCRE_UCP - option is passed to pcre_compile(), some of the classes are changed so + By default, in UTF modes, characters with values greater than 128 do + not match any of the POSIX character classes. However, if the PCRE_UCP + option is passed to pcre_compile(), some of the classes are changed so that Unicode character properties are used. This is achieved by replac- ing the POSIX classes by other sequences, as follows: @@ -4174,31 +4905,31 @@ POSIX CHARACTER CLASSES [:upper:] becomes \p{Lu} [:word:] becomes \p{Xwd} - Negated versions, such as [:^alpha:] use \P instead of \p. The other + Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX classes are unchanged, and match only characters with code points less than 128. VERTICAL BAR - Vertical bar characters are used to separate alternative patterns. For + Vertical bar characters are used to separate alternative patterns. For example, the pattern gilbert|sullivan - matches either "gilbert" or "sullivan". Any number of alternatives may - appear, and an empty alternative is permitted (matching the empty + matches either "gilbert" or "sullivan". Any number of alternatives may + appear, and an empty alternative is permitted (matching the empty string). The matching process tries each alternative in turn, from left - to right, and the first one that succeeds is used. If the alternatives - are within a subpattern (defined below), "succeeds" means matching the + to right, and the first one that succeeds is used. If the alternatives + are within a subpattern (defined below), "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern. INTERNAL OPTION SETTING - The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and - PCRE_EXTENDED options (which are Perl-compatible) can be changed from - within the pattern by a sequence of Perl option letters enclosed + The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and + PCRE_EXTENDED options (which are Perl-compatible) can be changed from + within the pattern by a sequence of Perl option letters enclosed between "(?" and ")". The option letters are i for PCRE_CASELESS @@ -4208,48 +4939,49 @@ INTERNAL OPTION SETTING For example, (?im) sets caseless, multiline matching. It is also possi- ble to unset these options by preceding the letter with a hyphen, and a - combined setting and unsetting such as (?im-sx), which sets PCRE_CASE- - LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, - is also permitted. If a letter appears both before and after the + combined setting and unsetting such as (?im-sx), which sets PCRE_CASE- + LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, + is also permitted. If a letter appears both before and after the hyphen, the option is unset. - The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA - can be changed in the same way as the Perl-compatible options by using + The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA + can be changed in the same way as the Perl-compatible options by using the characters J, U and X respectively. - When one of these option changes occurs at top level (that is, not - inside subpattern parentheses), the change applies to the remainder of + When one of these option changes occurs at top level (that is, not + inside subpattern parentheses), the change applies to the remainder of the pattern that follows. If the change is placed right at the start of a pattern, PCRE extracts it into the global options (and it will there- fore show up in data extracted by the pcre_fullinfo() function). - An option change within a subpattern (see below for a description of - subpatterns) affects only that part of the subpattern that follows it, + An option change within a subpattern (see below for a description of + subpatterns) affects only that part of the subpattern that follows it, so (a(?i)b)c matches abc and aBc and no other strings (assuming PCRE_CASELESS is not - used). By this means, options can be made to have different settings - in different parts of the pattern. Any changes made in one alternative - do carry on into subsequent branches within the same subpattern. For + used). By this means, options can be made to have different settings + in different parts of the pattern. Any changes made in one alternative + do carry on into subsequent branches within the same subpattern. For example, (a(?i)b|c) - matches "ab", "aB", "c", and "C", even though when matching "C" the - first branch is abandoned before the option setting. This is because - the effects of option settings happen at compile time. There would be + matches "ab", "aB", "c", and "C", even though when matching "C" the + first branch is abandoned before the option setting. This is because + the effects of option settings happen at compile time. There would be some very weird behaviour otherwise. - Note: There are other PCRE-specific options that can be set by the - application when the compile or match functions are called. In some - cases the pattern can contain special leading sequences such as (*CRLF) - to override what the application has set or what has been defaulted. - Details are given in the section entitled "Newline sequences" above. - There are also the (*UTF8) and (*UCP) leading sequences that can be - used to set UTF-8 and Unicode property modes; they are equivalent to - setting the PCRE_UTF8 and the PCRE_UCP options, respectively. + Note: There are other PCRE-specific options that can be set by the + application when the compiling or matching functions are called. In + some cases the pattern can contain special leading sequences such as + (*CRLF) to override what the application has set or what has been + defaulted. Details are given in the section entitled "Newline + sequences" above. There are also the (*UTF8), (*UTF16), and (*UCP) + leading sequences that can be used to set UTF and Unicode property + modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and + the PCRE_UCP options, respectively. SUBPATTERNS @@ -4267,22 +4999,25 @@ SUBPATTERNS 2. It sets up the subpattern as a capturing subpattern. This means that, when the whole pattern matches, that portion of the subject string that matched the subpattern is passed back to the caller via the - ovector argument of pcre_exec(). Opening parentheses are counted from - left to right (starting from 1) to obtain numbers for the capturing - subpatterns. For example, if the string "the red king" is matched - against the pattern + ovector argument of the matching function. (This applies only to the + traditional matching functions; the DFA matching functions do not sup- + port capturing.) + + Opening parentheses are counted from left to right (starting from 1) to + obtain numbers for the capturing subpatterns. For example, if the + string "the red king" is matched against the pattern the ((red|white) (king|queen)) the captured substrings are "red king", "red", and "king", and are num- bered 1, 2, and 3, respectively. - The fact that plain parentheses fulfil two functions is not always - helpful. There are often times when a grouping subpattern is required - without a capturing requirement. If an opening parenthesis is followed - by a question mark and a colon, the subpattern does not do any captur- - ing, and is not counted when computing the number of any subsequent - capturing subpatterns. For example, if the string "the white queen" is + The fact that plain parentheses fulfil two functions is not always + helpful. There are often times when a grouping subpattern is required + without a capturing requirement. If an opening parenthesis is followed + by a question mark and a colon, the subpattern does not do any captur- + ing, and is not counted when computing the number of any subsequent + capturing subpatterns. For example, if the string "the white queen" is matched against the pattern the ((?:red|white) (king|queen)) @@ -4290,37 +5025,37 @@ SUBPATTERNS the captured substrings are "white queen" and "queen", and are numbered 1 and 2. The maximum number of capturing subpatterns is 65535. - As a convenient shorthand, if any option settings are required at the - start of a non-capturing subpattern, the option letters may appear + As a convenient shorthand, if any option settings are required at the + start of a non-capturing subpattern, the option letters may appear between the "?" and the ":". Thus the two patterns (?i:saturday|sunday) (?:(?i)saturday|sunday) match exactly the same set of strings. Because alternative branches are - tried from left to right, and options are not reset until the end of - the subpattern is reached, an option setting in one branch does affect - subsequent branches, so the above patterns match "SUNDAY" as well as + tried from left to right, and options are not reset until the end of + the subpattern is reached, an option setting in one branch does affect + subsequent branches, so the above patterns match "SUNDAY" as well as "Saturday". DUPLICATE SUBPATTERN NUMBERS Perl 5.10 introduced a feature whereby each alternative in a subpattern - uses the same numbers for its capturing parentheses. Such a subpattern - starts with (?| and is itself a non-capturing subpattern. For example, + uses the same numbers for its capturing parentheses. Such a subpattern + starts with (?| and is itself a non-capturing subpattern. For example, consider this pattern: (?|(Sat)ur|(Sun))day - Because the two alternatives are inside a (?| group, both sets of cap- - turing parentheses are numbered one. Thus, when the pattern matches, - you can look at captured substring number one, whichever alternative - matched. This construct is useful when you want to capture part, but + Because the two alternatives are inside a (?| group, both sets of cap- + turing parentheses are numbered one. Thus, when the pattern matches, + you can look at captured substring number one, whichever alternative + matched. This construct is useful when you want to capture part, but not all, of one of a number of alternatives. Inside a (?| group, paren- - theses are numbered as usual, but the number is reset at the start of - each branch. The numbers of any capturing parentheses that follow the - subpattern start after the highest number used in any branch. The fol- + theses are numbered as usual, but the number is reset at the start of + each branch. The numbers of any capturing parentheses that follow the + subpattern start after the highest number used in any branch. The fol- lowing example is taken from the Perl documentation. The numbers under- neath show in which buffer the captured content will be stored. @@ -4328,58 +5063,58 @@ DUPLICATE SUBPATTERN NUMBERS / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x # 1 2 2 3 2 3 4 - A back reference to a numbered subpattern uses the most recent value - that is set for that number by any subpattern. The following pattern + A back reference to a numbered subpattern uses the most recent value + that is set for that number by any subpattern. The following pattern matches "abcabc" or "defdef": /(?|(abc)|(def))\1/ - In contrast, a recursive or "subroutine" call to a numbered subpattern - always refers to the first one in the pattern with the given number. - The following pattern matches "abcabc" or "defabc": + In contrast, a subroutine call to a numbered subpattern always refers + to the first one in the pattern with the given number. The following + pattern matches "abcabc" or "defabc": /(?|(abc)|(def))(?1)/ - If a condition test for a subpattern's having matched refers to a non- - unique number, the test is true if any of the subpatterns of that num- + If a condition test for a subpattern's having matched refers to a non- + unique number, the test is true if any of the subpatterns of that num- ber have matched. - An alternative approach to using this "branch reset" feature is to use + An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section. NAMED SUBPATTERNS - Identifying capturing parentheses by number is simple, but it can be - very hard to keep track of the numbers in complicated regular expres- - sions. Furthermore, if an expression is modified, the numbers may - change. To help with this difficulty, PCRE supports the naming of sub- + Identifying capturing parentheses by number is simple, but it can be + very hard to keep track of the numbers in complicated regular expres- + sions. Furthermore, if an expression is modified, the numbers may + change. To help with this difficulty, PCRE supports the naming of sub- patterns. This feature was not added to Perl until release 5.10. Python - had the feature earlier, and PCRE introduced it at release 4.0, using - the Python syntax. PCRE now supports both the Perl and the Python syn- - tax. Perl allows identically numbered subpatterns to have different + had the feature earlier, and PCRE introduced it at release 4.0, using + the Python syntax. PCRE now supports both the Perl and the Python syn- + tax. Perl allows identically numbered subpatterns to have different names, but PCRE does not. - In PCRE, a subpattern can be named in one of three ways: (?...) - or (?'name'...) as in Perl, or (?P...) as in Python. References - to capturing parentheses from other parts of the pattern, such as back - references, recursion, and conditions, can be made by name as well as + In PCRE, a subpattern can be named in one of three ways: (?...) + or (?'name'...) as in Perl, or (?P...) as in Python. References + to capturing parentheses from other parts of the pattern, such as back + references, recursion, and conditions, can be made by name as well as by number. - Names consist of up to 32 alphanumeric characters and underscores. - Named capturing parentheses are still allocated numbers as well as - names, exactly as if the names were not present. The PCRE API provides + Names consist of up to 32 alphanumeric characters and underscores. + Named capturing parentheses are still allocated numbers as well as + names, exactly as if the names were not present. The PCRE API provides function calls for extracting the name-to-number translation table from a compiled pattern. There is also a convenience function for extracting a captured substring by name. - By default, a name must be unique within a pattern, but it is possible + By default, a name must be unique within a pattern, but it is possible to relax this constraint by setting the PCRE_DUPNAMES option at compile - time. (Duplicate names are also always permitted for subpatterns with - the same number, set up as described in the previous section.) Dupli- - cate names can be useful for patterns where only one instance of the - named parentheses can match. Suppose you want to match the name of a - weekday, either as a 3-letter abbreviation or as the full name, and in + time. (Duplicate names are also always permitted for subpatterns with + the same number, set up as described in the previous section.) Dupli- + cate names can be useful for patterns where only one instance of the + named parentheses can match. Suppose you want to match the name of a + weekday, either as a 3-letter abbreviation or as the full name, and in both cases you want to extract the abbreviation. This pattern (ignoring the line breaks) does the job: @@ -4389,62 +5124,62 @@ NAMED SUBPATTERNS (?Thu)(?:rsday)?| (?Sat)(?:urday)? - There are five capturing substrings, but only one is ever set after a + There are five capturing substrings, but only one is ever set after a match. (An alternative way of solving this problem is to use a "branch reset" subpattern, as described in the previous section.) - The convenience function for extracting the data by name returns the - substring for the first (and in this example, the only) subpattern of - that name that matched. This saves searching to find which numbered + The convenience function for extracting the data by name returns the + substring for the first (and in this example, the only) subpattern of + that name that matched. This saves searching to find which numbered subpattern it was. - If you make a back reference to a non-unique named subpattern from - elsewhere in the pattern, the one that corresponds to the first occur- + If you make a back reference to a non-unique named subpattern from + elsewhere in the pattern, the one that corresponds to the first occur- rence of the name is used. In the absence of duplicate numbers (see the - previous section) this is the one with the lowest number. If you use a - named reference in a condition test (see the section about conditions - below), either to check whether a subpattern has matched, or to check - for recursion, all subpatterns with the same name are tested. If the - condition is true for any one of them, the overall condition is true. + previous section) this is the one with the lowest number. If you use a + named reference in a condition test (see the section about conditions + below), either to check whether a subpattern has matched, or to check + for recursion, all subpatterns with the same name are tested. If the + condition is true for any one of them, the overall condition is true. This is the same behaviour as testing by number. For further details of the interfaces for handling named subpatterns, see the pcreapi documen- tation. Warning: You cannot use different names to distinguish between two sub- - patterns with the same number because PCRE uses only the numbers when + patterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if differ- - ent names are given to subpatterns with the same number. However, you - can give the same name to subpatterns with the same number, even when + ent names are given to subpatterns with the same number. However, you + can give the same name to subpatterns with the same number, even when PCRE_DUPNAMES is not set. REPETITION - Repetition is specified by quantifiers, which can follow any of the + Repetition is specified by quantifiers, which can follow any of the following items: a literal data character the dot metacharacter the \C escape sequence - the \X escape sequence (in UTF-8 mode with Unicode properties) + the \X escape sequence the \R escape sequence an escape such as \d or \pL that matches a single character a character class a back reference (see next section) - a parenthesized subpattern (unless it is an assertion) - a recursive or "subroutine" call to a subpattern + a parenthesized subpattern (including assertions) + a subroutine call to a subpattern (recursive or otherwise) - The general repetition quantifier specifies a minimum and maximum num- - ber of permitted matches, by giving the two numbers in curly brackets - (braces), separated by a comma. The numbers must be less than 65536, + The general repetition quantifier specifies a minimum and maximum num- + ber of permitted matches, by giving the two numbers in curly brackets + (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example: z{2,4} - matches "zz", "zzz", or "zzzz". A closing brace on its own is not a - special character. If the second number is omitted, but the comma is - present, there is no upper limit; if the second number and the comma - are both omitted, the quantifier specifies an exact number of required + matches "zz", "zzz", or "zzzz". A closing brace on its own is not a + special character. If the second number is omitted, but the comma is + present, there is no upper limit; if the second number and the comma + are both omitted, the quantifier specifies an exact number of required matches. Thus [aeiou]{3,} @@ -4453,17 +5188,16 @@ 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-8 mode, quantifiers apply to UTF-8 characters rather than to - individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 char- - acters, each of which is represented by a two-byte sequence. Similarly, - when Unicode property support is available, \X{3} matches three Unicode - extended sequences, each of which may be several bytes long (and they - may be of different lengths). + In UTF modes, quantifiers apply to characters rather than to individual + data units. Thus, for example, \x{100}{2} matches two characters, each + of which is represented by a two-byte sequence in a UTF-8 string. Simi- + larly, \X{3} matches three Unicode extended sequences, each of which + may be several data units long (and they may be of different lengths). The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be use- @@ -4769,8 +5503,8 @@ BACK REFERENCES its following a backslash are taken as part of a potential back refer- ence number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the - PCRE_EXTENDED option is set, this can be whitespace. Otherwise, the \g{ - syntax or an empty comment (see "Comments" below) can be used. + PCRE_EXTENDED option is set, this can be white space. Otherwise, the + \g{ syntax or an empty comment (see "Comments" below) can be used. Recursive back references @@ -4807,13 +5541,29 @@ ASSERTIONS matched in the normal way, except that it does not cause the current matching position to be changed. - Assertion subpatterns are not capturing subpatterns, and may not be - repeated, because it makes no sense to assert the same thing several - times. If any kind of assertion contains capturing subpatterns within - it, these are counted for the purposes of numbering the capturing sub- - patterns in the whole pattern. However, substring capturing is carried - out only for positive assertions, because it does not make sense for - negative assertions. + Assertion subpatterns are not capturing subpatterns. If such an asser- + tion contains capturing subpatterns within it, these are counted for + the purposes of numbering the capturing subpatterns in the whole pat- + tern. However, substring capturing is carried out only for positive + assertions, because it does not make sense for negative assertions. + + For compatibility with Perl, assertion subpatterns may be repeated; + though it makes no sense to assert the same thing several times, the + side effect of capturing parentheses may occasionally be useful. In + practice, there only three cases: + + (1) If the quantifier is {0}, the assertion is never obeyed during + matching. However, it may contain internal capturing parenthesized + groups that are called from elsewhere via the subroutine mechanism. + + (2) If quantifier is {0,n} where n is greater than zero, it is treated + as if it were {0,1}. At run time, the rest of the pattern match is + tried with and without the assertion, the order depending on the greed- + iness of the quantifier. + + (3) If the minimum repetition is greater than zero, the quantifier is + ignored. The assertion is obeyed just once when encountered during + matching. Lookahead assertions @@ -4883,40 +5633,41 @@ ASSERTIONS then try to match. If there are insufficient characters before the cur- rent position, the assertion fails. - PCRE does not allow the \C escape (which matches a single byte in UTF-8 - mode) to appear in lookbehind assertions, because it makes it impossi- - ble to calculate the length of the lookbehind. The \X and \R escapes, - which can match different numbers of bytes, are also not permitted. + In a UTF mode, PCRE does not allow the \C escape (which matches a sin- + gle data unit even in a UTF mode) to appear in lookbehind assertions, + because it makes it impossible to calculate the length of the lookbe- + hind. The \X and \R escapes, which can match different numbers of data + units, are also not permitted. - "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in - lookbehinds, as long as the subpattern matches a fixed-length string. + "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in + lookbehinds, as long as the subpattern matches a fixed-length string. Recursion, however, is not supported. - Possessive quantifiers can be used in conjunction with lookbehind + Possessive quantifiers can be used in conjunction with lookbehind assertions to specify efficient matching of fixed-length strings at the end of subject strings. Consider a simple pattern such as abcd$ - when applied to a long string that does not match. Because matching + when applied to a long string that does not match. Because matching proceeds from left to right, PCRE will look for each "a" in the subject - and then see if what follows matches the rest of the pattern. If the + and then see if what follows matches the rest of the pattern. If the pattern is specified as ^.*abcd$ - the initial .* matches the entire string at first, but when this fails + the initial .* matches the entire string at first, but when this fails (because there is no following "a"), it backtracks to match all but the - last character, then all but the last two characters, and so on. Once - again the search for "a" covers the entire string, from right to left, + last character, then all but the last two characters, and so on. Once + again the search for "a" covers the entire string, from right to left, so we are no better off. However, if the pattern is written as ^.*+(?<=abcd) - there can be no backtracking for the .*+ item; it can match only the - entire string. The subsequent lookbehind assertion does a single test - on the last four characters. If it fails, the match fails immediately. - For long strings, this approach makes a significant difference to the + there can be no backtracking for the .*+ item; it can match only the + entire string. The subsequent lookbehind assertion does a single test + on the last four characters. If it fails, the match fails immediately. + For long strings, this approach makes a significant difference to the processing time. Using multiple assertions @@ -4925,18 +5676,18 @@ ASSERTIONS (?<=\d{3})(?)...) or (?('name')...) to test for a - used subpattern by name. For compatibility with earlier versions of - PCRE, which had this facility before Perl, the syntax (?(name)...) is - also recognized. However, there is a possible ambiguity with this syn- - tax, because subpattern names may consist entirely of digits. PCRE - looks first for a named subpattern; if it cannot find one and the name - consists entirely of digits, PCRE looks for a subpattern of that num- - ber, which must be greater than zero. Using subpattern names that con- + Perl uses the syntax (?()...) or (?('name')...) to test for a + used subpattern by name. For compatibility with earlier versions of + PCRE, which had this facility before Perl, the syntax (?(name)...) is + also recognized. However, there is a possible ambiguity with this syn- + tax, because subpattern names may consist entirely of digits. PCRE + looks first for a named subpattern; if it cannot find one and the name + consists entirely of digits, PCRE looks for a subpattern of that num- + ber, which must be greater than zero. Using subpattern names that con- sist entirely of digits is not recommended. Rewriting the above example to use a named subpattern gives this: (? \( )? [^()]+ (?() \) ) - If the name used in a condition of this kind is a duplicate, the test - is applied to all subpatterns of the same name, and is true if any one + If the name used in a condition of this kind is a duplicate, the test + is applied to all subpatterns of the same name, and is true if any one of them has matched. Checking for pattern recursion If the condition is the string (R), and there is no subpattern with the - name R, the condition is true if a recursive call to the whole pattern + name R, the condition is true if a recursive call to the whole pattern or any subpattern has been made. If digits or a name preceded by amper- sand follow the letter R, for example: @@ -5049,24 +5800,23 @@ 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 ref- - erenced from elsewhere. (The use of "subroutines" is described below.) - For example, a pattern to match an IPv4 address such as - "192.168.23.245" could be written like this (ignore whitespace and line - breaks): + If the condition is the string (DEFINE), and there is no subpattern + with the name DEFINE, the condition is always false. In this case, + there may be only one alternative in the subpattern. It is always + skipped if control reaches this point in the pattern; the idea of + DEFINE is that it can be used to define subroutines that can be refer- + enced from elsewhere. (The use of subroutines is described below.) For + example, a pattern to match an IPv4 address such as "192.168.23.245" + could be written like this (ignore white space and line breaks): (?(DEFINE) (? 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) \b (?&byte) (\.(?&byte)){3} \b @@ -5112,12 +5862,12 @@ COMMENTS comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which charac- ters are interpreted as newlines is controlled by the options passed to - pcre_compile() or by a special sequence at the start of the pattern, as - described in the section entitled "Newline conventions" above. Note - that the end of this type of comment is a literal newline sequence in - the pattern; escape sequences that happen to represent a newline do not - count. For example, consider this pattern when PCRE_EXTENDED is set, - and the default newline convention is in force: + a compiling function or by a special sequence at the start of the pat- + tern, as described in the section entitled "Newline conventions" above. + Note that the end of this type of comment is a literal newline sequence + in the pattern; escape sequences that happen to represent a newline do + not count. For example, consider this pattern when PCRE_EXTENDED is + set, and the default newline convention is in force: abc #comment \n still comment @@ -5153,11 +5903,11 @@ RECURSIVE PATTERNS into Perl at release 5.10. A special item that consists of (? followed by a number greater than - zero and a closing parenthesis is a recursive call of the subpattern of - the given number, provided that it occurs inside that subpattern. (If - not, it is a "subroutine" call, which is described in the next sec- - tion.) The special item (?R) or (?0) is a recursive call of the entire - regular expression. + zero and a closing parenthesis is a recursive subroutine call of the + subpattern of the given number, provided that it occurs inside that + subpattern. (If not, it is a non-recursive subroutine call, which is + described in the next section.) The special item (?R) or (?0) is a + recursive call of the entire regular expression. This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): @@ -5189,8 +5939,8 @@ RECURSIVE PATTERNS It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are refer- - enced. They are always "subroutine" calls, as described in the next - section. + enced. They are always non-recursive subroutine calls, as described in + the next section. An alternative approach is to use named parentheses instead. The Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also @@ -5223,28 +5973,30 @@ RECURSIVE PATTERNS the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing sub- - pattern is not matched at the top level, its final value is unset, even - if it is (temporarily) set at a deeper level. + pattern is not matched at the top level, its final captured value is + unset, even if it was (temporarily) set at a deeper level during the + matching process. - If there are more than 15 capturing parentheses in a pattern, PCRE has - to obtain extra memory to store data during a recursion, which it does + If there are more than 15 capturing parentheses in a pattern, PCRE has + to obtain extra memory to store data during a recursion, which it does by using pcre_malloc, freeing it via pcre_free afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. - Do not confuse the (?R) item with the condition (R), which tests for - recursion. Consider this pattern, which matches text in angle brack- - ets, allowing for arbitrary nesting. Only digits are allowed in nested - brackets (that is, when recursing), whereas any characters are permit- + Do not confuse the (?R) item with the condition (R), which tests for + recursion. Consider this pattern, which matches text in angle brack- + ets, allowing for arbitrary nesting. Only digits are allowed in nested + brackets (that is, when recursing), whereas any characters are permit- ted at the outer level. < (?: (?(R) \d++ | [^<>]*+) | (?R)) * > - In this pattern, (?(R) is the start of a conditional subpattern, with - two different alternatives for the recursive and non-recursive cases. + In this pattern, (?(R) is the start of a conditional subpattern, with + two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call. - Recursion difference from Perl + Differences in recursion processing between PCRE and Perl + Recursion processing in PCRE differs from Perl in two important ways. In PCRE (like Python, but unlike Perl), a recursive subpattern call is always treated as an atomic group. That is, once it has matched some of the subject string, it is never re-entered, even if it contains untried @@ -5317,14 +6069,30 @@ RECURSIVE PATTERNS Once again, it cannot jump back into the recursion to try other alter- natives, so the entire match fails. + The second way in which PCRE and Perl differ in their recursion pro- + cessing is in the handling of captured values. In Perl, when a subpat- + tern is called recursively or as a subpattern (see the next section), + it has no access to any values that were captured outside the recur- + sion, whereas in PCRE these values can be referenced. Consider this + pattern: + + ^(.)(\1|a(?2)) + + In PCRE, this pattern matches "bab". The first capturing parentheses + match "b", then in the second group, when the back reference \1 fails + to match "b", the second alternative matches "a" and then recurses. In + the recursion, \1 does now match "b" and so the whole match succeeds. + In Perl, the pattern fails to match because inside the recursive call + \1 cannot access the externally set value. + SUBPATTERNS AS SUBROUTINES - If the syntax for a recursive subpattern reference (either by number or - by name) is used outside the parentheses to which it refers, it oper- - ates like a subroutine in a programming language. The "called" subpat- - tern may be defined before or after the reference. A numbered reference - can be absolute or relative, as in these examples: + If the syntax for a recursive subpattern call (either by number or by + name) is used outside the parentheses to which it refers, it operates + like a subroutine in a programming language. The called subpattern may + be defined before or after the reference. A numbered reference can be + absolute or relative, as in these examples: (...(absolute)...)...(?2)... (...(relative)...)...(?-1)... @@ -5343,15 +6111,15 @@ SUBPATTERNS AS SUBROUTINES two strings. Another example is given in the discussion of DEFINE above. - Like recursive subpatterns, a subroutine call is always treated as an - atomic group. That is, once it has matched some of the subject string, - it is never re-entered, even if it contains untried alternatives and - there is a subsequent matching failure. Any capturing parentheses that - are set during the subroutine call revert to their previous values - afterwards. + All subroutine calls, whether recursive or not, are always treated as + atomic groups. That is, once a subroutine has matched some of the sub- + ject string, it is never re-entered, even if it contains untried alter- + natives and there is a subsequent matching failure. Any capturing + parentheses that are set during the subroutine call revert to their + previous values afterwards. - When a subpattern is used as a subroutine, processing options such as - case-independence are fixed when the subpattern is defined. They cannot + Processing options such as case-independence are fixed when a subpat- + tern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern: (abc)(?i:(?-1)) @@ -5392,8 +6160,8 @@ CALLOUTS PCRE provides a similar feature, but of course it cannot obey arbitrary Perl code. The feature is called "callout". The caller of PCRE provides an external function by putting its entry point in the global variable - pcre_callout. By default, this variable contains NULL, which disables - all calling out. + pcre_callout (8-bit library) or pcre16_callout (16-bit library). By + default, this variable contains NULL, which disables all calling out. Within a regular expression, (?C) indicates the points at which the external function is to be called. If you want to identify different @@ -5403,17 +6171,17 @@ CALLOUTS (?C1)abc(?C2)def - If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are - automatically installed before each item in the pattern. They are all - numbered 255. + If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- + outs are automatically installed before each item in the pattern. They + are all numbered 255. - During matching, when PCRE reaches a callout point (and pcre_callout is - set), the external function is called. It is provided with the number - of the callout, the position in the pattern, and, optionally, one item - of data originally supplied by the caller of pcre_exec(). The callout - function may cause matching to proceed, to backtrack, or to fail alto- - gether. A complete description of the interface to the callout function - is given in the pcrecallout documentation. + During matching, when PCRE reaches a callout point, the external func- + tion is called. It is provided with the number of the callout, the + position in the pattern, and, optionally, one item of data originally + supplied by the caller of the matching function. The callout function + may cause matching to proceed, to backtrack, or to fail altogether. A + complete description of the interface to the callout function is given + in the pcrecallout documentation. BACKTRACKING CONTROL @@ -5426,25 +6194,33 @@ BACKTRACKING CONTROL in this section. Since these verbs are specifically related to backtracking, most of - them can be used only when the pattern is to be matched using - pcre_exec(), which uses a backtracking algorithm. With the exception of - (*FAIL), which behaves like a failing negative assertion, they cause an - error if encountered by pcre_dfa_exec(). + 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. - If any of these verbs are used in an assertion or subroutine subpattern - (including recursive subpatterns), their effect is confined to that - subpattern; it does not extend to the surrounding pattern. Note that - such subpatterns are processed as anchored at the point where they are - tested. + If any of these verbs are used in an assertion or in a subpattern that + is called as a subroutine (whether or not recursively), their effect is + confined to that subpattern; it does not extend to the surrounding 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. An name is - a sequence of letters, digits, and underscores. If the name is empty, - that is, if the closing parenthesis immediately follows the colon, the - effect is as if the colon were not there. Any number of these verbs may - occur in a pattern. + (*VERB) or (*VERB:NAME). Some may take either form, with differing be- + haviour, depending on whether or not an argument is present. A name is + any sequence of characters that does not include a closing parenthesis. + The maximum length of name is 255 in the 8-bit library and 65535 in the + 16-bit library. If the name is empty, that is, if the closing parenthe- + sis immediately follows the colon, the effect is as if the colon were + not there. Any number of these verbs may occur in a pattern. + + Optimizations that affect backtracking verbs PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it @@ -5454,60 +6230,64 @@ BACKTRACKING CONTROL course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com- pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT). + There is more discussion of this option in the section entitled "Option + bits for pcre_exec()" in the pcreapi documentation. + + Experiments with Perl suggest that it too has similar optimizations, + sometimes leading to anomalous results. Verbs that act immediately - The following verbs act as soon as they are encountered. They may not + The following verbs act as soon as they are encountered. They may not be followed by a name. (*ACCEPT) - This verb causes the match to end successfully, skipping the remainder - of the pattern. When inside a recursion, only the innermost pattern is - ended immediately. If (*ACCEPT) is inside capturing parentheses, the - data so far is captured. (This feature was added to PCRE at release - 8.00.) For example: + This verb causes the match to end successfully, skipping the remainder + of the pattern. However, when it is inside a subpattern that is called + as a subroutine, only that subpattern is ended successfully. Matching + then continues at the outer level. If (*ACCEPT) is inside capturing + parentheses, the data so far is captured. For example: A((?:A|B(*ACCEPT)|C)D) - This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- + This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- tured by the outer parentheses. (*FAIL) or (*F) - This verb causes the match to fail, forcing backtracking to occur. It - is equivalent to (?!) but easier to read. The Perl documentation notes - that it is probably useful only when combined with (?{}) or (??{}). - Those are, of course, Perl features that are not present in PCRE. The - nearest equivalent is the callout feature, as for example in this pat- + This verb causes a matching failure, forcing backtracking to occur. It + is equivalent to (?!) but easier to read. The Perl documentation notes + that it is probably useful only when combined with (?{}) or (??{}). + Those are, of course, Perl features that are not present in PCRE. The + nearest equivalent is the callout feature, as for example in this pat- tern: a+(?C)(*FAIL) - A match with the string "aaaa" always fails, but the callout is taken + A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times). Recording which path was taken - There is one verb whose main purpose is to track how a match was - arrived at, though it also has a secondary use in conjunction with + There is one verb whose main purpose is to track how a match was + arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below). (*MARK:NAME) or (*:NAME) - A name is always required with this verb. There may be as many - instances of (*MARK) as you like in a pattern, and their names do not + A name is always required with this verb. There may be as many + instances of (*MARK) as you like in a pattern, and their names do not have to be unique. - When a match succeeds, the name of the last-encountered (*MARK) is - passed back to the caller via the pcre_extra data structure, as - described in the section on pcre_extra in the pcreapi documentation. No - data is returned for a partial match. Here is an example of pcretest - output, where the /K modifier requests the retrieval and outputting of - (*MARK) data: + When a match succeeds, the name of the last-encountered (*MARK) on the + matching path is passed back to the caller as described in the section + entitled "Extra data for pcre_exec()" in the pcreapi documentation. + Here is an example of pcretest output, where the /K modifier requests + the retrieval and outputting of (*MARK) data: - /X(*MARK:A)Y|X(*MARK:B)Z/K - XY + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XY 0: XY MK: A XZ @@ -5519,98 +6299,86 @@ BACKTRACKING CONTROL efficient way of obtaining this information than putting each alterna- tive in its own capturing parentheses. - A name may also be returned after a failed match if the final path - through the pattern involves (*MARK). However, unless (*MARK) used in - conjunction with (*COMMIT), this is unlikely to happen for an unan- - chored pattern because, as the starting point for matching is advanced, - the final check is often with an empty string, causing a failure before - (*MARK) is reached. For example: + 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. - /X(*MARK:A)Y|X(*MARK:B)Z/K - XP - No match + 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: - There are three potential starting points for this match (starting with - X, starting with P, and with an empty string). If the pattern is - anchored, the result is different: - - /^X(*MARK:A)Y|^X(*MARK:B)Z/K - XP + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XP No match, mark = B - PCRE's start-of-match optimizations can also interfere with this. For - example, if, as a result of a call to pcre_study(), it knows the mini- - mum subject length for a match, a shorter subject will not be scanned - at all. + Note that in this unanchored example the mark is retained from the + match attempt that started at the letter "X" in the subject. Subsequent + match attempts starting at "P" and then with an empty string do not get + as far as the (*MARK) item, but nevertheless do not reset it. - Note that similar anomalies (though different in detail) exist in Perl, - no doubt for the same reasons. The use of (*MARK) data after a failed - match of an unanchored pattern is not recommended, unless (*COMMIT) is - involved. + If you are interested in (*MARK) values after failed matches, you + should probably set the PCRE_NO_START_OPTIMIZE option (see above) to + ensure that the match is always attempted. Verbs that act after backtracking The following verbs do nothing when they are encountered. Matching con- - tinues with what follows, but if there is no subsequent match, causing - a backtrack to the verb, a failure is forced. That is, backtracking - cannot pass to the left of the verb. However, when one of these verbs - appears inside an atomic group, its effect is confined to that group, - because once the group has been matched, there is never any backtrack- - ing into it. In this situation, backtracking can "jump back" to the - left of the entire atomic group. (Remember also, as stated above, that + tinues with what follows, but if there is no subsequent match, causing + a backtrack to the verb, a failure is forced. That is, backtracking + cannot pass to the left of the verb. However, when one of these verbs + appears inside an atomic group, its effect is confined to that group, + because once the group has been matched, there is never any backtrack- + ing into it. In this situation, backtracking can "jump back" to the + left of the entire atomic group. (Remember also, as stated above, that this localization also applies in subroutine calls and assertions.) - These verbs differ in exactly what kind of failure occurs when back- + These verbs differ in exactly what kind of failure occurs when back- tracking reaches them. (*COMMIT) - This verb, which may not be followed by a name, causes the whole match + This verb, which may not be followed by a name, causes the whole match to fail outright if the rest of the pattern does not match. Even if the pattern is unanchored, no further attempts to find a match by advancing the starting point take place. Once (*COMMIT) has been passed, - pcre_exec() is committed to finding a match at the current starting + pcre_exec() is committed to finding a match at the current starting point, or not at all. For example: a+(*COMMIT)b - This matches "xxaab" but not "aacaab". It can be thought of as a kind + This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the - most recently passed (*MARK) in the path is passed back when (*COMMIT) + most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure. - Note that (*COMMIT) at the start of a pattern is not the same as an - anchor, unless PCRE's start-of-match optimizations are turned off, as + Note that (*COMMIT) at the start of a pattern is not the same as an + anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this pcretest example: - /(*COMMIT)abc/ - xyzabc + re> /(*COMMIT)abc/ + data> xyzabc 0: abc xyzabc\Y No match - PCRE knows that any match must start with "a", so the optimization - skips along the subject to "a" before running the first match attempt, - which succeeds. When the optimization is disabled by the \Y escape in + PCRE knows that any match must start with "a", so the optimization + skips along the subject to "a" before running the first match attempt, + which succeeds. When the optimization is disabled by the \Y escape in the second subject, the match starts at "x" and so the (*COMMIT) causes it to fail without trying any other starting points. (*PRUNE) or (*PRUNE:NAME) - This verb causes the match to fail at the current starting position in - the subject if the rest of the pattern does not match. If the pattern - is unanchored, the normal "bumpalong" advance to the next starting - character then happens. Backtracking can occur as usual to the left of - (*PRUNE), before it is reached, or when matching to the right of - (*PRUNE), but if there is no match to the right, backtracking cannot - cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter- - native to an atomic group or possessive quantifier, but there are some + This verb causes the match to fail at the current starting position in + the subject if the rest of the pattern does not match. If the pattern + is unanchored, the normal "bumpalong" advance to the next starting + character then happens. Backtracking can occur as usual to the left of + (*PRUNE), before it is reached, or when matching to the right of + (*PRUNE), but if there is no match to the right, backtracking cannot + cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter- + native to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. The behav- - iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the - match fails completely; the name is passed back if this is the final - attempt. (*PRUNE:NAME) does not pass back a name if the match suc- - ceeds. In an anchored pattern (*PRUNE) has the same effect as (*COM- - MIT). + iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an + anchored pattern (*PRUNE) has the same effect as (*COMMIT). (*SKIP) @@ -5637,49 +6405,85 @@ BACKTRACKING CONTROL is searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that cor- responds to that (*MARK) instead of to where (*SKIP) was encountered. - If no (*MARK) with a matching name is found, normal "bumpalong" of one - character happens (the (*SKIP) is ignored). + If no (*MARK) with a matching name is found, the (*SKIP) is ignored. (*THEN) or (*THEN:NAME) - This verb causes a skip to the next alternation in the innermost - enclosing group if the rest of the pattern does not match. That is, it - cancels pending backtracking, but only within the current alternation. - Its name comes from the observation that it can be used for a pattern- - based if-then-else block: + This verb causes a skip to the next innermost alternative if the rest + of the pattern does not match. That is, it cancels pending backtrack- + ing, but only within the current alternative. Its name comes from the + observation that it can be used for a pattern-based if-then-else block: ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... If the COND1 pattern matches, FOO is tried (and possibly further items - after the end of the group if FOO succeeds); on failure the matcher + after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The behaviour of (*THEN:NAME) is exactly the same as - (*MARK:NAME)(*THEN) if the overall match fails. If (*THEN) is not - directly inside an alternation, it acts like (*PRUNE). + (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts + like (*PRUNE). - The above verbs provide four different "strengths" of control when sub- - sequent matching fails. (*THEN) is the weakest, carrying on the match - at the next alternation. (*PRUNE) comes next, failing the match at the - current starting position, but allowing an advance to the next charac- - ter (for an unanchored pattern). (*SKIP) is similar, except that the - advance may be more than one character. (*COMMIT) is the strongest, + Note that a subpattern that does not contain a | character is just a + part of the enclosing alternative; it is not a nested alternation with + only one alternative. The effect of (*THEN) extends beyond such a sub- + pattern to the enclosing alternative. Consider this pattern, where A, + B, etc. are complex pattern fragments that do not contain any | charac- + ters at this level: + + A (B(*THEN)C) | D + + If A and B are matched, but there is a failure in C, matching does not + backtrack into A; instead it moves to the next alternative, that is, D. + However, if the subpattern containing (*THEN) is given an alternative, + it behaves differently: + + A (B(*THEN)C | (*FAIL)) | D + + The effect of (*THEN) is now confined to the inner subpattern. After a + failure in C, matching moves to (*FAIL), which causes the whole subpat- + tern to fail because there are no more alternatives to try. In this + case, matching does now backtrack into A. + + Note also that a conditional subpattern is not considered as having two + alternatives, because only one is ever used. In other words, the | + character in a conditional subpattern has a different meaning. Ignoring + white space, consider: + + ^.*? (?(?=a) a | b(*THEN)c ) + + If the subject is "ba", this pattern does not match. Because .*? is + ungreedy, it initially matches zero characters. The condition (?=a) + then fails, the character "b" is matched, but "c" is not. At this + point, matching does not backtrack to .*? as might perhaps be expected + from the presence of the | character. The conditional subpattern is + part of the single alternative that comprises the whole pattern, and so + the match fails. (If there was a backtrack into .*?, allowing it to + match "b", the match would succeed.) + + The verbs just described provide four different "strengths" of control + when subsequent matching fails. (*THEN) is the weakest, carrying on the + match at the next alternative. (*PRUNE) comes next, failing the match + at the current starting position, but allowing an advance to the next + character (for an unanchored pattern). (*SKIP) is similar, except that + the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail. - If more than one is present in a pattern, the "stongest" one wins. For - example, consider this pattern, where A, B, etc. are complex pattern - fragments: + If more than one such verb is present in a pattern, the "strongest" one + wins. For example, consider this pattern, where A, B, etc. are complex + pattern fragments: (A(*COMMIT)B(*THEN)C|D) - Once A has matched, PCRE is committed to this match, at the current - starting position. If subsequently B matches, but C does not, the nor- - mal (*THEN) action of trying the next alternation (that is, D) does not + Once A has matched, PCRE is committed to this match, at the current + starting position. If subsequently B matches, but C does not, the nor- + mal (*THEN) action of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides. SEE ALSO - pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3). + pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), + pcre16(3). AUTHOR @@ -5691,8 +6495,8 @@ AUTHOR REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 17 June 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -5707,7 +6511,7 @@ PCRE REGULAR EXPRESSION SYNTAX SUMMARY The full syntax and semantics of the regular expressions that are sup- ported by PCRE are described in the pcrepattern documentation. This - document contains just a quick-reference summary of the syntax. + document contains a quick-reference summary of the syntax. QUOTING @@ -5721,7 +6525,7 @@ CHARACTERS \a alarm, that is, the BEL character (hex 07) \cx "control-x", where x is any ASCII character \e escape (hex 1B) - \f formfeed (hex 0C) + \f form feed (hex 0C) \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) @@ -5734,25 +6538,25 @@ CHARACTER TYPES . any character except newline; in dotall mode, any character whatsoever - \C one byte, even in UTF-8 mode (best avoided) + \C one data unit, even in UTF mode (best avoided) \d a decimal digit \D a character that is not a decimal digit - \h a horizontal whitespace character - \H a character that is not a horizontal whitespace character + \h a horizontal white space character + \H a character that is not a horizontal white space character \N a character that is not a newline \p{xx} a character with the xx property \P{xx} a character without the xx property \R a newline sequence - \s a whitespace character - \S a character that is not a whitespace character - \v a vertical whitespace character - \V a character that is not a vertical whitespace character + \s a white space character + \S a character that is not a white space character + \v a vertical white space character + \V a character that is not a vertical white space character \w a "word" character \W a "non-word" character \X an extended Unicode sequence In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII - characters, even in UTF-8 mode. However, this can be changed by setting + characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option. @@ -5814,20 +6618,22 @@ PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P SCRIPT NAMES FOR \p AND \P - Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille, - Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, - Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp- - tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, - Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe- - rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, - Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, - Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, - Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, - Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, - Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian, - Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, - Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, - Ugaritic, Vai, Yi. + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, + Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, + Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, + Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- + tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, + Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, + Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, + Yi. CHARACTER CLASSES @@ -5848,7 +6654,7 @@ CHARACTER CLASSES lower lower case letter print printing, including space punct printing, excluding alphanumeric - space whitespace + space white space upper upper case letter word same as \w xdigit hexadecimal digit @@ -5939,7 +6745,8 @@ OPTION SETTING one of the newline-setting options with similar syntax: (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) - (*UTF8) set UTF-8 mode (PCRE_UTF8) + (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) + (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UCP) set PCRE_UCP (use Unicode properties for \d etc) @@ -6008,6 +6815,7 @@ BACKTRACKING CONTROL (*ACCEPT) force successful match (*FAIL) force backtrack; synonym (*F) + (*MARK:NAME) set name to be passed back; synonym (*:NAME) The following act only when a subsequent match failure causes a back- track to reach them. They all force a match failure, but they differ in @@ -6016,14 +6824,18 @@ BACKTRACKING CONTROL (*COMMIT) overall failure, no advance of starting point (*PRUNE) advance to next starting character - (*SKIP) advance start to current matching position + (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE) + (*SKIP) advance to current matching position + (*SKIP:NAME) advance to position corresponding to an earlier + (*MARK:NAME); if not found, the (*SKIP) is ignored (*THEN) local failure, backtrack to next alternation + (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) NEWLINE CONVENTIONS These are recognized only at the very start of the pattern or after a - (*BSR_...) or (*UTF8) or (*UCP) option. + (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option. (*CR) carriage return only (*LF) linefeed only @@ -6035,7 +6847,7 @@ NEWLINE CONVENTIONS WHAT \R MATCHES These are recognized only at the very start of the pattern or after a - (*...) option that sets the newline convention or UTF-8 or UCP mode. + (*...) option that sets the newline convention or a UTF or UCP mode. (*BSR_ANYCRLF) CR, LF, or CRLF (*BSR_UNICODE) any Unicode newline sequence @@ -6061,8 +6873,594 @@ AUTHOR REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREUNICODE(3) PCREUNICODE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT + + From Release 8.30, in addition to its previous UTF-8 support, PCRE also + supports UTF-16 by means of a separate 16-bit library. This can be + built as well as, or instead of, the 8-bit library. + + +UTF-8 SUPPORT + + In order process UTF-8 strings, you must build PCRE's 8-bit library + with UTF support, and, in addition, you must call pcre_compile() with + the PCRE_UTF8 option flag, or the pattern must start with the sequence + (*UTF8). When either of these is the case, both the pattern and any + subject strings that are matched against it are treated as UTF-8 + strings instead of strings of 1-byte characters. + + +UTF-16 SUPPORT + + In order process UTF-16 strings, you must build PCRE's 16-bit library + with UTF support, and, in addition, you must call pcre16_compile() with + the PCRE_UTF16 option flag, or the pattern must start with the sequence + (*UTF16). When either of these is the case, both the pattern and any + subject strings that are matched against it are treated as UTF-16 + strings instead of strings of 16-bit characters. + + +UTF SUPPORT OVERHEAD + + If you compile PCRE with UTF support, but do not use it at run time, + the library will be a bit bigger, but the additional run time overhead + is limited to testing the PCRE_UTF8/16 flag occasionally, so should not + be very big. + + +UNICODE PROPERTY SUPPORT + + If PCRE is built with Unicode character property support (which implies + UTF support), the escape sequences \p{..}, \P{..}, and \X can be used. + The available properties that can be tested are limited to the general + category properties such as Lu for an upper case letter or Nd for a + decimal number, the Unicode script names such as Arabic or Han, and the + derived properties Any and L&. A full list is given in the pcrepattern + documentation. Only the short names for properties are supported. For + example, \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not + supported. Furthermore, in Perl, many properties may optionally be + prefixed by "Is", for compatibility with Perl 5.6. PCRE does not sup- + port this. + + Validity of UTF-8 strings + + When you set the PCRE_UTF8 flag, the byte strings passed as patterns + and subjects are (by default) checked for validity on entry to the rel- + evant functions. The entire string is checked before any other process- + ing takes place. From release 7.3 of PCRE, the check is according the + rules of RFC 3629, which are themselves derived from the Unicode speci- + fication. Earlier releases of PCRE followed the rules of RFC 2279, + which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The + current check allows only values in the range U+0 to U+10FFFF, exclud- + ing U+D800 to U+DFFF. + + The excluded code points are the "Surrogate Area" of Unicode. They are + reserved for use by UTF-16, where they are used in pairs to encode + codepoints with values greater than 0xFFFF. The code points that are + encoded by UTF-16 pairs are available independently in the UTF-8 encod- + ing. (In other words, the whole surrogate thing is a fudge for UTF-16 + which unfortunately messes up UTF-8.) + + If an invalid UTF-8 string is passed to PCRE, an error return is given. + At compile time, the only additional information is the offset to the + first byte of the failing character. The run-time functions pcre_exec() + and pcre_dfa_exec() also pass back this information, as well as a more + detailed reason code if the caller has provided memory in which to do + this. + + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance, for example in the case of a long subject string that is being + scanned repeatedly with different patterns. If you set the + PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes + that the pattern or subject it is given (respectively) contains only + valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8 + string. + + If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, + what happens depends on why the string is invalid. If the string con- + forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a + string of characters in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() + and the interpreted version of pcre_exec(). In other words, apart from + the initial validity test, these functions (when in UTF-8 mode) handle + strings according to the more liberal rules of RFC 2279. However, the + just-in-time (JIT) optimization for pcre_exec() supports only RFC 3629. + If you are using JIT optimization, or if the string does not even con- + form to RFC 2279, the result is undefined. Your program may crash. + + If you want to process strings of values in the full range 0 to + 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can + set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in + this situation, you will have to apply your own validity check, and + avoid the use of JIT optimization. + + Validity of UTF-16 strings + + When you set the PCRE_UTF16 flag, the strings of 16-bit data units that + are passed as patterns and subjects are (by default) checked for valid- + ity on entry to the relevant functions. Values other than those in the + surrogate range U+D800 to U+DFFF are independent code points. Values in + the surrogate range must be used in pairs in the correct manner. + + If an invalid UTF-16 string is passed to PCRE, an error return is + given. At compile time, the only additional information is the offset + to the first data unit of the failing character. The run-time functions + pcre16_exec() and pcre16_dfa_exec() also pass back this information, as + well as a more detailed reason code if the caller has provided memory + in which to do this. + + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at + run time, PCRE assumes that the pattern or subject it is given (respec- + tively) contains only valid UTF-16 sequences. In this case, it does not + diagnose an invalid UTF-16 string. + + General comments about UTF modes + + 1. Codepoints less than 256 can be specified by either braced or + unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3). + Larger values have to use braced sequences. + + 2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they + match two-byte characters for values greater than \177. + + 3. Repeat quantifiers apply to complete UTF characters, not to individ- + ual data units, for example: \x{100}{3}. + + 4. The dot metacharacter matches one UTF character instead of a single + data unit. + + 5. The escape sequence \C can be used to match a single byte in UTF-8 + mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead + to some strange effects because it breaks up multi-unit characters (see + the description of \C in the pcrepattern documentation). The use of \C + is not supported in the alternative matching function + pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT opti- + mization of pcre[16]_exec(). If JIT optimization is requested for a UTF + pattern that contains \C, it will not succeed, and so the matching will + be carried out by the normal interpretive function. + + 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly + test characters of any code value, but, by default, the characters that + PCRE recognizes as digits, spaces, or word characters remain the same + set as in non-UTF mode, all with values less than 256. This remains + true even when PCRE is built to include Unicode property support, + because to do otherwise would slow down PCRE in many common cases. Note + in particular that this applies to \b and \B, because they are defined + in terms of \w and \W. If you really want to test for a wider sense of, + say, "digit", you can use explicit Unicode property tests such as + \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the + character escapes work is changed so that Unicode properties are used + to determine which characters match. There are more details in the sec- + tion on generic character types in the pcrepattern documentation. + + 7. Similarly, characters that match the POSIX named character classes + are all low-valued characters, unless the PCRE_UCP option is set. + + 8. However, the horizontal and vertical white space matching escapes + (\h, \H, \v, and \V) do match all the appropriate Unicode characters, + whether or not PCRE_UCP is set. + + 9. Case-insensitive matching applies only to characters whose values + are less than 128, unless PCRE is built with Unicode property support. + Even when Unicode property support is available, PCRE still uses its + own character tables when checking the case of low-valued characters, + so as not to degrade performance. The Unicode property information is + used only for characters with higher values. Furthermore, PCRE supports + case-insensitive matching only when there is a one-to-one mapping + between a letter's cases. There are a small number of many-to-one map- + pings in Unicode; these are not supported by PCRE. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 14 April 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREJIT(3) PCREJIT(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE JUST-IN-TIME COMPILER SUPPORT + + Just-in-time compiling is a heavyweight optimization that can greatly + speed up pattern matching. However, it comes at the cost of extra pro- + cessing before the match is performed. Therefore, it is of most benefit + when the same pattern is going to be matched many times. This does not + necessarily mean many calls of a matching function; if the pattern is + not anchored, matching attempts may take place many times at various + positions in the subject, even for a single call. Therefore, if the + subject string is very long, it may still pay to use JIT for one-off + matches. + + JIT support applies only to the traditional Perl-compatible matching + function. It does not apply when the DFA matching function is being + used. The code for this support was written by Zoltan Herczeg. + + +8-BIT and 16-BIT SUPPORT + + JIT support is available for both the 8-bit and 16-bit PCRE libraries. + To keep this documentation simple, only the 8-bit interface is + described in what follows. If you are using the 16-bit library, substi- + tute the 16-bit functions and 16-bit structures (for example, + pcre16_jit_stack instead of pcre_jit_stack). + + +AVAILABILITY OF JIT SUPPORT + + JIT support is an optional feature of PCRE. The "configure" option + --enable-jit (or equivalent CMake option) must be set when PCRE is + built if you want to use JIT. The support is limited to the following + hardware platforms: + + ARM v5, v7, and Thumb2 + Intel x86 32-bit and 64-bit + MIPS 32-bit + Power PC 32-bit and 64-bit + + If --enable-jit is set on an unsupported platform, compilation fails. + + A program that is linked with PCRE 8.20 or later can tell if JIT sup- + port is available by calling pcre_config() with the PCRE_CONFIG_JIT + option. The result is 1 when JIT is available, and 0 otherwise. How- + ever, a simple program does not need to check this in order to use JIT. + The API is implemented in a way that falls back to the interpretive + code if JIT is not available. + + If your program may sometimes be linked with versions of PCRE that are + older than 8.20, but you want to use JIT when it is available, you can + test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT + macro such as PCRE_CONFIG_JIT, for compile-time control of your code. + + +SIMPLE USE OF JIT + + You have to do two things to make use of the JIT support in the sim- + plest way: + + (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for + each compiled pattern, and pass the resulting pcre_extra block to + pcre_exec(). + + (2) Use pcre_free_study() to free the pcre_extra block when it is + no longer needed, instead of just freeing it yourself. This + ensures that any JIT data is also freed. + + For a program that may be linked with pre-8.20 versions of PCRE, you + can insert + + #ifndef PCRE_STUDY_JIT_COMPILE + #define PCRE_STUDY_JIT_COMPILE 0 + #endif + + so that no option is passed to pcre_study(), and then use something + like this to free the study data: + + #ifdef PCRE_CONFIG_JIT + pcre_free_study(study_ptr); + #else + pcre_free(study_ptr); + #endif + + PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for + complete matches. If you want to run partial matches using the + PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you + should set one or both of the following options in addition to, or + instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study(): + + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + The JIT compiler generates different optimized code for each of the + three modes (normal, soft partial, hard partial). When pcre_exec() is + called, the appropriate code is run if it is available. Otherwise, the + pattern is matched using interpretive code. + + In some circumstances you may need to call additional functions. These + are described in the section entitled "Controlling the JIT stack" + below. + + If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are + ignored, and no JIT data is created. Otherwise, the compiled pattern is + passed to the JIT compiler, which turns it into machine code that exe- + cutes much faster than the normal interpretive code. When pcre_exec() + is passed a pcre_extra block containing a pointer to JIT code of the + appropriate mode (normal or hard/soft partial), it obeys that code + instead of running the interpreter. The result is identical, but the + compiled JIT code runs much faster. + + There are some pcre_exec() options that are not supported for JIT exe- + cution. There are also some pattern items that JIT cannot handle. + Details are given below. In both cases, execution automatically falls + back to the interpretive code. If you want to know whether JIT was + actually used for a particular match, you should arrange for a JIT + callback function to be set up as described in the section entitled + "Controlling the JIT stack" below, even if you do not need to supply a + non-default JIT stack. Such a callback function is called whenever JIT + code is about to be obeyed. If the execution options are not right for + JIT execution, the callback function is not obeyed. + + If the JIT compiler finds an unsupported item, no JIT data is gener- + ated. You can find out if JIT execution is available after studying a + pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A + result of 1 means that JIT compilation was successful. A result of 0 + means that JIT support is not available, or the pattern was not studied + with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to + handle the pattern. + + Once a pattern has been studied, with or without JIT, it can be used as + many times as you like for matching different subject strings. + + +UNSUPPORTED OPTIONS AND PATTERN ITEMS + + The only pcre_exec() options that are supported for JIT execution are + PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, + PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PAR- + TIAL_SOFT. + + The unsupported pattern items are: + + \C match a single byte; not supported in UTF-8 mode + (?Cn) callouts + (*PRUNE) ) + (*SKIP) ) backtracking control verbs + (*THEN) ) + + Support for some of these may be added in future. + + +RETURN VALUES FROM JIT EXECUTION + + When a pattern is matched using JIT execution, the return values are + the same as those given by the interpretive pcre_exec() code, with the + addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means + that the memory used for the JIT stack was insufficient. See "Control- + ling the JIT stack" below for a discussion of JIT stack usage. For com- + patibility with the interpretive pcre_exec() code, no more than two- + thirds of the ovector argument is used for passing back captured sub- + strings. + + The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if + searching a very large pattern tree goes on for too long, as it is in + the same circumstance when JIT is not used, but the details of exactly + what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error + code is never returned by JIT execution. + + +SAVING AND RESTORING COMPILED PATTERNS + + The code that is generated by the JIT compiler is architecture-spe- + cific, and is also position dependent. For those reasons it cannot be + saved (in a file or database) and restored later like the bytecode and + other data of a compiled pattern. Saving and restoring compiled pat- + terns is not something many people do. More detail about this facility + is given in the pcreprecompile documentation. It should be possible to + run pcre_study() on a saved and restored pattern, and thereby recreate + the JIT data, but because JIT compilation uses significant resources, + it is probably not worth doing this; you might as well recompile the + original pattern. + + +CONTROLLING THE JIT STACK + + When the compiled JIT code runs, it needs a block of memory to use as a + stack. By default, it uses 32K on the machine stack. However, some + large or complicated patterns need more than this. The error + PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. + Three functions are provided for managing blocks of memory for use as + JIT stacks. There is further discussion about the use of JIT stacks in + the section entitled "JIT stack FAQ" below. + + The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments + are a starting size and a maximum size, and it returns a pointer to an + opaque structure of type pcre_jit_stack, or NULL if there is an error. + The pcre_jit_stack_free() function can be used to free a stack that is + no longer needed. (For the technically minded: the address space is + allocated by mmap or VirtualAlloc.) + + JIT uses far less memory for recursion than the interpretive code, and + a maximum stack size of 512K to 1M should be more than enough for any + pattern. + + The pcre_assign_jit_stack() function specifies which stack JIT code + should use. Its arguments are as follows: + + pcre_extra *extra + pcre_jit_callback callback + void *data + + The extra argument must be the result of studying a pattern with + PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the + other two options: + + (1) If callback is NULL and data is NULL, an internal 32K block + on the machine stack is used. + + (2) If callback is NULL and data is not NULL, data must be + a valid JIT stack, the result of calling pcre_jit_stack_alloc(). + + (3) If callback is not NULL, it must point to a function that is + called with data as an argument at the start of matching, in + order to set up a JIT stack. If the return from the callback + function is NULL, the internal 32K stack is used; otherwise the + return value must be a valid JIT stack, the result of calling + pcre_jit_stack_alloc(). + + A callback function is obeyed whenever JIT code is about to be run; it + is not obeyed when pcre_exec() is called with options that are incom- + patible for JIT execution. A callback function can therefore be used to + determine whether a match operation was executed by JIT or by the + interpreter. + + You may safely use the same JIT stack for more than one pattern (either + by assigning directly or by callback), as long as the patterns are all + matched sequentially in the same thread. In a multithread application, + if you do not specify a JIT stack, or if you assign or pass back NULL + from a callback, that is thread-safe, because each thread has its own + machine stack. However, if you assign or pass back a non-NULL JIT + stack, this must be a different stack for each thread so that the + application is thread-safe. + + Strictly speaking, even more is allowed. You can assign the same non- + NULL stack to any number of patterns as long as they are not used for + matching by multiple threads at the same time. For example, you can + assign the same stack to all compiled patterns, and use a global mutex + in the callback to wait until the stack is available for use. However, + this is an inefficient solution, and not recommended. + + This is a suggestion for how a multithreaded program that needs to set + up non-default JIT stacks might operate: + + During thread initalization + thread_local_var = pcre_jit_stack_alloc(...) + + During thread exit + pcre_jit_stack_free(thread_local_var) + + Use a one-line callback function + return thread_local_var + + All the functions described in this section do nothing if JIT is not + available, and pcre_assign_jit_stack() does nothing unless the extra + argument is non-NULL and points to a pcre_extra block that is the + result of a successful study with PCRE_STUDY_JIT_COMPILE etc. + + +JIT STACK FAQ + + (1) Why do we need JIT stacks? + + PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack + where the local data of the current node is pushed before checking its + child nodes. Allocating real machine stack on some platforms is diffi- + cult. For example, the stack chain needs to be updated every time if we + extend the stack on PowerPC. Although it is possible, its updating + time overhead decreases performance. So we do the recursion in memory. + + (2) Why don't we simply allocate blocks of memory with malloc()? + + Modern operating systems have a nice feature: they can reserve an + address space instead of allocating memory. We can safely allocate mem- + ory pages inside this address space, so the stack could grow without + moving memory data (this is important because of pointers). Thus we can + allocate 1M address space, and use only a single memory page (usually + 4K) if that is enough. However, we can still grow up to 1M anytime if + needed. + + (3) Who "owns" a JIT stack? + + The owner of the stack is the user program, not the JIT studied pattern + or anything else. The user program must ensure that if a stack is used + by pcre_exec(), (that is, it is assigned to the pattern currently run- + ning), that stack must not be used by any other threads (to avoid over- + writing the same memory area). The best practice for multithreaded pro- + grams is to allocate a stack for each thread, and return this stack + through the JIT callback function. + + (4) When should a JIT stack be freed? + + You can free a JIT stack at any time, as long as it will not be used by + pcre_exec() again. When you assign the stack to a pattern, only a + pointer is set. There is no reference counting or any other magic. You + can free the patterns and stacks in any order, anytime. Just do not + call pcre_exec() with a pattern pointing to an already freed stack, as + that will cause SEGFAULT. (Also, do not free a stack currently used by + pcre_exec() in another thread). You can also replace the stack for a + pattern at any time. You can even free the previous stack before + assigning a replacement. + + (5) Should I allocate/free a stack every time before/after calling + pcre_exec()? + + No, because this is too costly in terms of resources. However, you + could implement some clever idea which release the stack if it is not + used in let's say two minutes. The JIT callback can help to achive this + without keeping a list of the currently JIT studied patterns. + + (6) OK, the stack is for long term memory allocation. But what happens + if a pattern causes stack overflow with a stack of 1M? Is that 1M kept + until the stack is freed? + + Especially on embedded sytems, it might be a good idea to release mem- + ory sometimes without freeing the stack. There is no API for this at + the moment. Probably a function call which returns with the currently + allocated memory for any stack and another which allows releasing mem- + ory (shrinking the stack) would be a good idea if someone needs this. + + (7) This is too much of a headache. Isn't there any better solution for + JIT stack handling? + + No, thanks to Windows. If POSIX threads were used everywhere, we could + throw out this complicated API. + + +EXAMPLE CODE + + This is a single-threaded example that specifies a JIT stack without + using a callback. + + int rc; + int ovector[30]; + pcre *re; + pcre_extra *extra; + pcre_jit_stack *jit_stack; + + re = pcre_compile(pattern, 0, &error, &erroffset, NULL); + /* Check for errors */ + extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); + jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); + /* Check for error (NULL) */ + pcre_assign_jit_stack(extra, NULL, jit_stack); + rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30); + /* Check results */ + pcre_free(re); + pcre_free_study(extra); + pcre_jit_stack_free(jit_stack); + + +SEE ALSO + + pcreapi(3) + + +AUTHOR + + Philip Hazel (FAQ by Zoltan Herczeg) + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 04 May 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6075,11 +7473,11 @@ NAME PARTIAL MATCHING IN PCRE - In normal use of PCRE, if the subject string that is passed to - pcre_exec() or pcre_dfa_exec() matches as far as it goes, but is too - short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. - There are circumstances where it might be helpful to distinguish this - case from other cases in which there is no match. + In normal use of PCRE, if the subject string that is passed to a match- + ing function matches as far as it goes, but is too short to match the + entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances + where it might be helpful to distinguish this case from other cases in + which there is no match. Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example @@ -6097,41 +7495,52 @@ PARTIAL MATCHING IN PCRE available at once. PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and - PCRE_PARTIAL_HARD options, which can be set when calling pcre_exec() or - pcre_dfa_exec(). For backwards compatibility, PCRE_PARTIAL is a synonym - for PCRE_PARTIAL_SOFT. The essential difference between the two options - is whether or not a partial match is preferred to an alternative com- - plete match, though the details differ between the two matching func- - tions. If both options are set, PCRE_PARTIAL_HARD takes precedence. + PCRE_PARTIAL_HARD options, which can be set when calling any of the + matching functions. For backwards compatibility, PCRE_PARTIAL is a syn- + onym for PCRE_PARTIAL_SOFT. The essential difference between the two + options is whether or not a partial match is preferred to an alterna- + tive complete match, though the details differ between the two types of + matching function. If both options are set, PCRE_PARTIAL_HARD takes + precedence. - Setting a partial matching option disables two of PCRE's optimizations. - PCRE remembers the last literal byte in a pattern, and abandons match- - ing immediately if such a byte is not present in the subject string. - This optimization cannot be used for a subject string that might match - only partially. If the pattern was studied, PCRE knows the minimum - length of a matching string, and does not bother to run the matching - function on shorter strings. This optimization is also disabled for - partial matching. + If you want to use partial matching with just-in-time optimized code, + you must call pcre_study() or pcre16_study() with one or both of these + options: + + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + + PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non- + partial matches on the same pattern. If the appropriate JIT study mode + has not been set for a match, the interpretive matching code is used. + + Setting a partial matching option disables two of PCRE's standard opti- + mizations. PCRE remembers the last literal data unit in a pattern, and + abandons matching immediately if it is not present in the subject + string. This optimization cannot be used for a subject string that + might match only partially. If the pattern was studied, PCRE knows the + minimum length of a matching string, and does not bother to run the + matching function on shorter strings. This optimization is also dis- + abled for partial matching. -PARTIAL MATCHING USING pcre_exec() +PARTIAL MATCHING USING pcre_exec() OR pcre16_exec() - A partial match occurs during a call to pcre_exec() when the end of the - subject string is reached successfully, but matching cannot continue - because more characters are needed. However, at least one character in - the subject must have been inspected. This character need not form part - of the final matched string; lookbehind assertions and the \K escape - sequence provide ways of inspecting characters before the start of a - matched substring. The requirement for inspecting at least one charac- - ter exists because an empty string can always be matched; without such - a restriction there would always be a partial match of an empty string - at the end of the subject. + A partial match occurs during a call to pcre_exec() or pcre16_exec() + when the end of the subject string is reached successfully, but match- + ing cannot continue because more characters are needed. However, at + least one character in the subject must have been inspected. This char- + acter need not form part of the final matched string; lookbehind asser- + tions and the \K escape sequence provide ways of inspecting characters + before the start of a matched substring. The requirement for inspecting + at least one character exists because an empty string can always be + matched; without such a restriction there would always be a partial + match of an empty string at the end of the subject. - If there are at least two slots in the offsets vector when pcre_exec() - returns with a partial match, the first slot is set to the offset of - the earliest character that was inspected when the partial match was - found. For convenience, the second offset points to the end of the sub- - ject so that a substring can easily be identified. + If there are at least two slots in the offsets vector when a partial + match is returned, the first slot is set to the offset of the earliest + character that was inspected. For convenience, the second offset points + to the end of the subject so that a substring can easily be identified. For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain look- @@ -6148,13 +7557,13 @@ PARTIAL MATCHING USING pcre_exec() What happens when a partial match is identified depends on which of the two partial matching options are set. - PCRE_PARTIAL_SOFT with pcre_exec() + PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec() - If PCRE_PARTIAL_SOFT is set when pcre_exec() identifies a partial - match, the partial match is remembered, but matching continues as nor- - mal, and other alternatives in the pattern are tried. If no complete - match can be found, pcre_exec() returns PCRE_ERROR_PARTIAL instead of - PCRE_ERROR_NOMATCH. + If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() identi- + fies a partial match, the partial match is remembered, but matching + continues as normal, and other alternatives in the pattern are tried. + If no complete match can be found, PCRE_ERROR_PARTIAL is returned + instead of PCRE_ERROR_NOMATCH. This option is "soft" because it prefers a complete match over a par- tial match. All the various matching items in a pattern behave as if @@ -6174,22 +7583,24 @@ PARTIAL MATCHING USING pcre_exec() (In this example, there are two partial matches, because "dog" on its own partially matches the second alternative.) - PCRE_PARTIAL_HARD with pcre_exec() + PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec() - If PCRE_PARTIAL_HARD is set for pcre_exec(), it returns PCRE_ERROR_PAR- - TIAL as soon as a partial match is found, without continuing to search - for possible complete matches. This option is "hard" because it prefers - an earlier partial match over a later complete match. For this reason, - the assumption is made that the end of the supplied subject string may - not be the true end of the available data, and so, if \z, \Z, \b, \B, - or $ are encountered at the end of the subject, the result is - PCRE_ERROR_PARTIAL. + If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(), + PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, + without continuing to search for possible complete matches. This option + is "hard" because it prefers an earlier partial match over a later com- + plete match. For this reason, the assumption is made that the end of + the supplied subject string may not be the true end of the available + data, and so, if \z, \Z, \b, \B, or $ are encountered at the end of the + subject, the result is PCRE_ERROR_PARTIAL, provided that at least one + character in the subject has been inspected. - Setting PCRE_PARTIAL_HARD also affects the way pcre_exec() checks UTF-8 - subject strings for validity. Normally, an invalid UTF-8 sequence - causes the error PCRE_ERROR_BADUTF8. However, in the special case of a - truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT- - UTF8 is returned when PCRE_PARTIAL_HARD is set. + Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject + strings are checked for validity. Normally, an invalid sequence causes + the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the + special case of a truncated character at the end of the subject, + PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when + PCRE_PARTIAL_HARD is set. Comparing hard and soft partial matching @@ -6207,25 +7618,25 @@ PARTIAL MATCHING USING pcre_exec() /dog(sbody)??/ - In this case the result is always a complete match because pcre_exec() - finds that first, and it never continues after finding a match. It - might be easier to follow this explanation by thinking of the two pat- - terns like this: + In this case the result is always a complete match because that is + found first, and matching never continues after finding a complete + match. It might be easier to follow this explanation by thinking of the + two patterns like this: /dog(sbody)?/ is the same as /dogsbody|dog/ /dog(sbody)??/ is the same as /dog|dogsbody/ - The second pattern will never match "dogsbody" when pcre_exec() is - used, because it will always find the shorter match first. + The second pattern will never match "dogsbody", because it will always + find the shorter match first. -PARTIAL MATCHING USING pcre_dfa_exec() +PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec() - The pcre_dfa_exec() function moves along the subject string character - by character, without backtracking, searching for all possible matches - simultaneously. If the end of the subject is reached before the end of - the pattern, there is the possibility of a partial match, again pro- - vided that at least one character has been inspected. + The DFA functions move along the subject string character by character, + without backtracking, searching for all possible matches simultane- + ously. If the end of the subject is reached before the end of the pat- + tern, there is the possibility of a partial match, again provided that + at least one character has been inspected. When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches @@ -6235,17 +7646,17 @@ PARTIAL MATCHING USING pcre_dfa_exec() the first matching string, provided there are at least two slots in the offsets vector. - Because pcre_dfa_exec() always searches for all possible matches, and - there is no difference between greedy and ungreedy repetition, its be- - haviour is different from pcre_exec when PCRE_PARTIAL_HARD is set. Con- - sider the string "dog" matched against the ungreedy pattern shown - above: + Because the DFA functions always search for all possible matches, and + there is no difference between greedy and ungreedy repetition, their + behaviour is different from the standard functions when PCRE_PAR- + TIAL_HARD is set. Consider the string "dog" matched against the + ungreedy pattern shown above: /dog(sbody)??/ - Whereas pcre_exec() stops as soon as it finds the complete match for - "dog", pcre_dfa_exec() also finds the partial match for "dogsbody", and - so returns that when PCRE_PARTIAL_HARD is set. + Whereas the standard functions stop as soon as they find the complete + match for "dog", the DFA functions also find the partial match for + "dogsbody", and so return that when PCRE_PARTIAL_HARD is set. PARTIAL MATCHING AND WORD BOUNDARIES @@ -6259,37 +7670,34 @@ PARTIAL MATCHING AND WORD BOUNDARIES This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following character cannot take place, so a partial match is found. - However, pcre_exec() carries on with normal matching, which matches \b - at the end of the subject when the last character is a letter, thus - finding a complete match. The result, therefore, is not PCRE_ERROR_PAR- - TIAL. The same thing happens with pcre_dfa_exec(), because it also - finds the complete match. - - Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, - because then the partial match takes precedence. + However, normal matching carries on, and \b matches at the end of the + subject when the last character is a letter, so a complete match is + found. The result, therefore, is not PCRE_ERROR_PARTIAL. Using + PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because + then the partial match takes precedence. FORMERLY RESTRICTED PATTERNS For releases of PCRE prior to 8.00, because of the way certain internal - optimizations were implemented in the pcre_exec() function, the - PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be - used with all patterns. From release 8.00 onwards, the restrictions no - longer apply, and partial matching with pcre_exec() can be requested - for any pattern. + optimizations were implemented in the pcre_exec() function, the + PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be + used with all patterns. From release 8.00 onwards, the restrictions no + longer apply, and partial matching with can be requested for any pat- + tern. Items that were formerly restricted were repeated single characters and - repeated metasequences. If PCRE_PARTIAL was set for a pattern that did - not conform to the restrictions, pcre_exec() returned the error code - PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The - PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled + repeated metasequences. If PCRE_PARTIAL was set for a pattern that did + not conform to the restrictions, pcre_exec() returned the error code + PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The + PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled pattern can be used for partial matching now always returns 1. EXAMPLE OF PARTIAL MATCHING USING PCRETEST - If the escape sequence \P is present in a pcretest data line, the - PCRE_PARTIAL_SOFT option is used for the match. Here is a run of + If the escape sequence \P is present in a pcretest data line, the + PCRE_PARTIAL_SOFT option is used for the match. Here is a run of pcretest that uses the date example quoted above: re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ @@ -6305,25 +7713,25 @@ EXAMPLE OF PARTIAL MATCHING USING PCRETEST data> j\P No match - The first data string is matched completely, so pcretest shows the - matched substrings. The remaining four strings do not match the com- + The first data string is matched completely, so pcretest shows the + matched substrings. The remaining four strings do not match the com- plete pattern, but the first two are partial matches. Similar output is - obtained when pcre_dfa_exec() is used. + obtained if DFA matching is used. - If the escape sequence \P is present more than once in a pcretest data + If the escape sequence \P is present more than once in a pcretest data line, the PCRE_PARTIAL_HARD option is set for the match. -MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() +MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec() - When a partial match has been found using pcre_dfa_exec(), it is possi- - ble to continue the match by providing additional subject data and - calling pcre_dfa_exec() again with the same compiled regular expres- - sion, this time setting the PCRE_DFA_RESTART option. You must pass the + When a partial match has been found using a DFA matching function, it + is possible to continue the match by providing additional subject data + and calling the function again with the same compiled regular expres- + sion, this time setting the PCRE_DFA_RESTART option. You must pass the same working space as before, because this is where details of the pre- - vious partial match are stored. Here is an example using pcretest, - using the \R escape sequence to set the PCRE_DFA_RESTART option (\D - specifies the use of pcre_dfa_exec()): + vious partial match are stored. Here is an example using pcretest, + using the \R escape sequence to set the PCRE_DFA_RESTART option (\D + specifies the use of the DFA matching function): re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ data> 23ja\P\D @@ -6331,46 +7739,49 @@ MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() data> n05\R\D 0: n05 - The first call has "23ja" as the subject, and requests partial match- - ing; the second call has "n05" as the subject for the continued - (restarted) match. Notice that when the match is complete, only the - last part is shown; PCRE does not retain the previously partially- - matched string. It is up to the calling program to do that if it needs + The first call has "23ja" as the subject, and requests partial match- + ing; the second call has "n05" as the subject for the continued + (restarted) match. Notice that when the match is complete, only the + last part is shown; PCRE does not retain the previously partially- + matched string. It is up to the calling program to do that if it needs to. - You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with - PCRE_DFA_RESTART to continue partial matching over multiple segments. - This facility can be used to pass very long subject strings to - pcre_dfa_exec(). + You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with + PCRE_DFA_RESTART to continue partial matching over multiple segments. + This facility can be used to pass very long subject strings to the DFA + matching functions. -MULTI-SEGMENT MATCHING WITH pcre_exec() +MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec() - From release 8.00, pcre_exec() can also be used to do multi-segment - matching. Unlike pcre_dfa_exec(), it is not possible to restart the - previous match with a new segment of data. Instead, new data must be - added to the previous subject string, and the entire match re-run, - starting from the point where the partial match occurred. Earlier data - can be discarded. It is best to use PCRE_PARTIAL_HARD in this situa- - tion, because it does not treat the end of a segment as the end of the - subject when matching \z, \Z, \b, \B, and $. Consider an unanchored - pattern that matches dates: + From release 8.00, the standard matching functions can also be used to + do multi-segment matching. Unlike the DFA functions, it is not possible + to restart the previous match with a new segment of data. Instead, new + data must be added to the previous subject string, and the entire match + re-run, starting from the point where the partial match occurred. Ear- + lier data can be discarded. + + It is best to use PCRE_PARTIAL_HARD in this situation, because it does + not treat the end of a segment as the end of the subject when matching + \z, \Z, \b, \B, and $. Consider an unanchored pattern that matches + dates: re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/ data> The date is 23ja\P\P Partial match: 23ja - At this stage, an application could discard the text preceding "23ja", - add on text from the next segment, and call pcre_exec() again. Unlike - pcre_dfa_exec(), the entire matching string must always be available, - and the complete matching process occurs for each call, so more memory - and more processing time is needed. + At this stage, an application could discard the text preceding "23ja", + add on text from the next segment, and call the matching function + again. Unlike the DFA matching functions, the entire matching string + must always be available, and the complete matching process occurs for + each call, so more memory and more processing time is needed. - Note: If the pattern contains lookbehind assertions, or \K, or starts - with \b or \B, the string that is returned for a partial match will - include characters that precede the partially matched string itself, - because these must be retained when adding on more characters for a - subsequent matching attempt. + Note: If the pattern contains lookbehind assertions, or \K, or starts + with \b or \B, the string that is returned for a partial match includes + characters that precede the partially matched string itself, because + these must be retained when adding on more characters for a subsequent + matching attempt. However, in some cases you may need to retain even + earlier characters, as discussed in the next section. ISSUES WITH MULTI-SEGMENT MATCHING @@ -6384,23 +7795,40 @@ ISSUES WITH MULTI-SEGMENT MATCHING option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. - 2. Lookbehind assertions at the start of a pattern are catered for in - the offsets that are returned for a partial match. However, in theory, - a lookbehind assertion later in the pattern could require even earlier - characters to be inspected, and it might not have been reached when a - partial match occurs. This is probably an extremely unlikely case; you - could guard against it to a certain extent by always including extra - characters at the start. + 2. Lookbehind assertions that have already been obeyed are catered for + in the offsets that are returned for a partial match. However a lookbe- + hind assertion later in the pattern could require even earlier charac- + ters to be inspected. You can handle this case by using the + PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or + pcre16_fullinfo() functions to obtain the length of the largest lookbe- + hind in the pattern. This length is given in characters, not bytes. If + you always retain at least that many characters before the partially + matched string, all should be well. (Of course, near the start of the + subject, fewer characters may be present; in that case all characters + should be retained.) - 3. Matching a subject string that is split into multiple segments may - not always produce exactly the same result as matching over one single - long string, especially when PCRE_PARTIAL_SOFT is used. The section - "Partial Matching and Word Boundaries" above describes an issue that - arises if the pattern ends with \b or \B. Another kind of difference - may occur when there are multiple matching possibilities, because (for - PCRE_PARTIAL_SOFT) a partial match result is given only when there are + 3. Because a partial match must always contain at least one character, + what might be considered a partial match of an empty string actually + gives a "no match" result. For example: + + re> /c(?<=abc)x/ + data> ab\P + No match + + If the next segment begins "cx", a match should be found, but this will + only happen if characters from the previous segment are retained. For + this reason, a "no match" result should be interpreted as "partial + match of an empty string" when the pattern contains lookbehinds. + + 4. Matching a subject string that is split into multiple segments may + not always produce exactly the same result as matching over one single + long string, especially when PCRE_PARTIAL_SOFT is used. The section + "Partial Matching and Word Boundaries" above describes an issue that + arises if the pattern ends with \b or \B. Another kind of difference + may occur when there are multiple matching possibilities, because (for + PCRE_PARTIAL_SOFT) a partial match result is given only when there are no completed matches. This means that as soon as the shortest match has - been found, continuation to a new subject segment is no longer possi- + been found, continuation to a new subject segment is no longer possi- ble. Consider again this pcretest example: re> /dog(sbody)?/ @@ -6414,14 +7842,15 @@ ISSUES WITH MULTI-SEGMENT MATCHING 0: dogsbody 1: dog - The first data line passes the string "dogsb" to pcre_exec(), setting - the PCRE_PARTIAL_SOFT option. Although the string is a partial match - for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the - shorter string "dog" is a complete match. Similarly, when the subject - is presented to pcre_dfa_exec() in several parts ("do" and "gsb" being - the first two) the match stops when "dog" has been found, and it is not - possible to continue. On the other hand, if "dogsbody" is presented as - a single string, pcre_dfa_exec() finds both matches. + The first data line passes the string "dogsb" to a standard matching + function, setting the PCRE_PARTIAL_SOFT option. Although the string is + a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL, + because the shorter string "dog" is a complete match. Similarly, when + the subject is presented to a DFA matching function in several parts + ("do" and "gsb" being the first two) the match stops when "dog" has + been found, and it is not possible to continue. On the other hand, if + "dogsbody" is presented as a single string, a DFA matching function + finds both matches. Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differ- @@ -6435,28 +7864,27 @@ ISSUES WITH MULTI-SEGMENT MATCHING data> gsb\R\P\P\D Partial match: gsb - 4. Patterns that contain alternatives at the top level which do not all + 5. Patterns that contain alternatives at the top level which do not all start with the same pattern item may not work as expected when - PCRE_DFA_RESTART is used with pcre_dfa_exec(). For example, consider - this pattern: + PCRE_DFA_RESTART is used. For example, consider this pattern: 1234|3789 - If the first part of the subject is "ABC123", a partial match of the - first alternative is found at offset 3. There is no partial match for + If the first part of the subject is "ABC123", a partial match of the + first alternative is found at offset 3. There is no partial match for the second alternative, because such a match does not start at the same - point in the subject string. Attempting to continue with the string - "7890" does not yield a match because only those alternatives that - match at one point in the subject are remembered. The problem arises - because the start of the second alternative matches within the first - alternative. There is no problem with anchored patterns or patterns + point in the subject string. Attempting to continue with the string + "7890" does not yield a match because only those alternatives that + match at one point in the subject are remembered. The problem arises + because the start of the second alternative matches within the first + alternative. There is no problem with anchored patterns or patterns such as: 1234|ABCD - where no string can be a partial match for both alternatives. This is - not a problem if pcre_exec() is used, because the entire match has to - be rerun each time: + where no string can be a partial match for both alternatives. This is + not a problem if a standard matching function is used, because the + entire match has to be rerun each time: re> /1234|3789/ data> ABC123\P\P @@ -6465,11 +7893,11 @@ ISSUES WITH MULTI-SEGMENT MATCHING 0: 3789 Of course, instead of using PCRE_DFA_RESTART, the same technique of re- - running the entire match can also be used with pcre_dfa_exec(). Another - possibility is to work with two buffers. If a partial match at offset n - in the first buffer is followed by "no match" when PCRE_DFA_RESTART is - used on the second buffer, you can then try a new match starting at - offset n+1 in the first buffer. + running the entire match can also be used with the DFA matching func- + tions. Another possibility is to work with two buffers. If a partial + match at offset n in the first buffer is followed by "no match" when + PCRE_DFA_RESTART is used on the second buffer, you can then try a new + match starting at offset n+1 in the first buffer. AUTHOR @@ -6481,8 +7909,8 @@ AUTHOR REVISION - Last updated: 07 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 24 February 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6500,26 +7928,32 @@ SAVING AND RE-USING PRECOMPILED PCRE PATTERNS form instead of having to compile them every time the application is run. If you are not using any private character tables (see the pcre_maketables() documentation), this is relatively straightforward. - If you are using private tables, it is a little bit more complicated. + If you are using private tables, it is a little bit more complicated. + However, if you are using the just-in-time optimization feature, it is + not possible to save and reload the JIT data. If you save compiled patterns to a file, you can copy them to a differ- - ent host and run them there. This works even if the new host has the - opposite endianness to the one on which the patterns were compiled. - There may be a small performance penalty, but it should be insignifi- - cant. However, compiling regular expressions with one version of PCRE - for use with a different version is not guaranteed to work and may - cause crashes. + ent host and run them there. If the two hosts have different endianness + (byte order), you should run the pcre[16]_pattern_to_host_byte_order() + function on the new host before trying to match the pattern. The match- + ing functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern + with the wrong endianness. + + Compiling regular expressions with one version of PCRE for use with a + different version is not guaranteed to work and may cause crashes, and + saving and restoring a compiled pattern loses any JIT optimization + data. SAVING A COMPILED PATTERN - The value returned by pcre_compile() points to a single block of memory - that holds the compiled pattern and associated data. You can find the - length of this block in bytes by calling pcre_fullinfo() with an argu- - ment of PCRE_INFO_SIZE. You can then save the data in any appropriate - manner. Here is sample code that compiles a pattern and writes it to a - file. It assumes that the variable fd refers to a file that is open for - output: + The value returned by pcre[16]_compile() points to a single block of + memory that holds the compiled pattern and associated data. You can + find the length of this block in bytes by calling pcre[16]_fullinfo() + with an argument of PCRE_INFO_SIZE. You can then save the data in any + appropriate manner. Here is sample code for the 8-bit library that com- + piles a pattern and writes it to a file. It assumes that the variable + fd refers to a file that is open for output: int erroroffset, rc, size; char *error; @@ -6549,45 +7983,49 @@ SAVING A COMPILED PATTERN in the memory of some daemon process that passes them via sockets to the processes that want them. - If the pattern has been studied, it is also possible to save the study - data in a similar way to the compiled pattern itself. When studying - generates additional information, pcre_study() returns a pointer to a - pcre_extra data block. Its format is defined in the section on matching - a pattern in the pcreapi documentation. The study_data field points to - the binary study data, and this is what you must save (not the - pcre_extra block itself). The length of the study data can be obtained - by calling pcre_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. - Remember to check that pcre_study() did return a non-NULL value before - trying to save the study data. + If the pattern has been studied, it is also possible to save the normal + study data in a similar way to the compiled pattern itself. However, if + the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is cre- + ated cannot be saved because it is too dependent on the current envi- + ronment. When studying generates additional information, + pcre[16]_study() returns a pointer to a pcre[16]_extra data block. Its + format is defined in the section on matching a pattern in the pcreapi + documentation. The study_data field points to the binary study data, + and this is what you must save (not the pcre[16]_extra block itself). + The length of the study data can be obtained by calling + pcre[16]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remember + to check that pcre[16]_study() did return a non-NULL value before try- + ing to save the study data. RE-USING A PRECOMPILED PATTERN - Re-using a precompiled pattern is straightforward. Having reloaded it - into main memory, you pass its pointer to pcre_exec() or - pcre_dfa_exec() in the usual way. This should work even on another - host, and even if that host has the opposite endianness to the one - where the pattern was compiled. + Re-using a precompiled pattern is straightforward. Having reloaded it + into main memory, called pcre[16]_pattern_to_host_byte_order() if nec- + essary, you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() + in the usual way. However, if you passed a pointer to custom character tables when the - pattern was compiled (the tableptr argument of pcre_compile()), you - must now pass a similar pointer to pcre_exec() or pcre_dfa_exec(), - because the value saved with the compiled pattern will obviously be - nonsense. A field in a pcre_extra() block is used to pass this data, as - described in the section on matching a pattern in the pcreapi documen- - tation. + pattern was compiled (the tableptr argument of pcre[16]_compile()), you + must now pass a similar pointer to pcre[16]_exec() or + pcre[16]_dfa_exec(), because the value saved with the compiled pattern + will obviously be nonsense. A field in a pcre[16]_extra() block is used + to pass this data, as described in the section on matching a pattern in + the pcreapi documentation. If you did not provide custom character tables when the pattern was - compiled, the pointer in the compiled pattern is NULL, which causes - pcre_exec() to use PCRE's internal tables. Thus, you do not need to - take any special action at run time in this case. + compiled, the pointer in the compiled pattern is NULL, which causes the + matching functions to use PCRE's internal tables. Thus, you do not need + to take any special action at run time in this case. If you saved study data with the compiled pattern, you need to create - your own pcre_extra data block and set the study_data field to point to - the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA - bit in the flags field to indicate that study data is present. Then - pass the pcre_extra block to pcre_exec() or pcre_dfa_exec() in the - usual way. + your own pcre[16]_extra data block and set the study_data field to + point to the reloaded study data. You must also set the + PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study + data is present. Then pass the pcre[16]_extra block to the matching + function in the usual way. If the pattern was studied for just-in-time + optimization, that data cannot be saved, and so is lost by a + save/restore cycle. COMPATIBILITY WITH DIFFERENT PCRE RELEASES @@ -6606,8 +8044,8 @@ AUTHOR REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6627,12 +8065,12 @@ PCRE PERFORMANCE COMPILED PATTERN MEMORY USAGE - Patterns are compiled by PCRE into a reasonably efficient byte code, so - that most simple patterns do not use much memory. However, there is one - case where the memory usage of a compiled pattern can be unexpectedly - large. If a parenthesized subpattern has a quantifier with a minimum - greater than 1 and/or a limited maximum, the whole subpattern is - repeated in the compiled code. For example, the pattern + Patterns are compiled by PCRE into a reasonably efficient interpretive + code, so that most simple patterns do not use much memory. However, + there is one case where the memory usage of a compiled pattern can be + unexpectedly large. If a parenthesized subpattern has a quantifier with + a minimum greater than 1 and/or a limited maximum, the whole subpattern + is repeated in the compiled code. For example, the pattern (abc|def){2,4} @@ -6650,64 +8088,66 @@ COMPILED PATTERN MEMORY USAGE ((ab){1,1000}c){1,3} - uses 51K bytes when compiled. When PCRE is compiled with its default - internal pointer size of two bytes, the size limit on a compiled pat- - tern is 64K, and this is reached with the above pattern if the outer - repetition is increased from 3 to 4. PCRE can be compiled to use larger - internal pointers and thus handle larger compiled patterns, but it is - better to try to rewrite your pattern to use less memory if you can. + uses 51K bytes when compiled using the 8-bit library. When PCRE is com- + piled with its default internal pointer size of two bytes, the size + limit on a compiled pattern is 64K data units, and this is reached with + the above pattern if the outer repetition is increased from 3 to 4. + PCRE can be compiled to use larger internal pointers and thus handle + larger compiled patterns, but it is better to try to rewrite your pat- + tern to use less memory if you can. - One way of reducing the memory usage for such patterns is to make use + One way of reducing the memory usage for such patterns is to make use of PCRE's "subroutine" facility. Re-writing the above pattern as ((ab)(?2){0,999}c)(?1){0,2} reduces the memory requirements to 18K, and indeed it remains under 20K - even with the outer repetition increased to 100. However, this pattern - is not exactly equivalent, because the "subroutine" calls are treated - as atomic groups into which there can be no backtracking if there is a - subsequent matching failure. Therefore, PCRE cannot do this kind of - rewriting automatically. Furthermore, there is a noticeable loss of - speed when executing the modified pattern. Nevertheless, if the atomic - grouping is not a problem and the loss of speed is acceptable, this - kind of rewriting will allow you to process patterns that PCRE cannot + even with the outer repetition increased to 100. However, this pattern + is not exactly equivalent, because the "subroutine" calls are treated + as atomic groups into which there can be no backtracking if there is a + subsequent matching failure. Therefore, PCRE cannot do this kind of + rewriting automatically. Furthermore, there is a noticeable loss of + speed when executing the modified pattern. Nevertheless, if the atomic + grouping is not a problem and the loss of speed is acceptable, this + kind of rewriting will allow you to process patterns that PCRE cannot otherwise handle. STACK USAGE AT RUN TIME - When pcre_exec() is used for matching, certain kinds of pattern can - cause it to use large amounts of the process stack. In some environ- - ments the default process stack is quite small, and if it runs out the - result is often SIGSEGV. This issue is probably the most frequently - raised problem with PCRE. Rewriting your pattern can often help. The - pcrestack documentation discusses this issue in detail. + When pcre_exec() or pcre16_exec() is used for matching, certain kinds + of pattern can cause it to use large amounts of the process stack. In + some environments the default process stack is quite small, and if it + runs out the result is often SIGSEGV. This issue is probably the most + frequently raised problem with PCRE. Rewriting your pattern can often + help. The pcrestack documentation discusses this issue in detail. PROCESSING TIME - Certain items in regular expression patterns are processed more effi- + Certain items in regular expression patterns are processed more effi- ciently than others. It is more efficient to use a character class like - [aeiou] than a set of single-character alternatives such as - (a|e|i|o|u). In general, the simplest construction that provides the + [aeiou] than a set of single-character alternatives such as + (a|e|i|o|u). In general, the simplest construction that provides the required behaviour is usually the most efficient. Jeffrey Friedl's book - contains a lot of useful general discussion about optimizing regular - expressions for efficient performance. This document contains a few + contains a lot of useful general discussion about optimizing regular + expressions for efficient performance. This document contains a few observations about PCRE. - Using Unicode character properties (the \p, \P, and \X escapes) is - slow, because PCRE has to scan a structure that contains data for over - fifteen thousand characters whenever it needs a character's property. - If you can find an alternative pattern that does not use character + Using Unicode character properties (the \p, \P, and \X escapes) is + slow, because PCRE has to scan a structure that contains data for over + fifteen thousand characters whenever it needs a character's property. + If you can find an alternative pattern that does not use character properties, it will probably be faster. - By default, the escape sequences \b, \d, \s, and \w, and the POSIX - character classes such as [:alpha:] do not use Unicode properties, + By default, the escape sequences \b, \d, \s, and \w, and the POSIX + character classes such as [:alpha:] do not use Unicode properties, partly for backwards compatibility, and partly for performance reasons. - However, you can set PCRE_UCP if you want Unicode character properties - to be used. This can double the matching time for items such as \d, - when matched with pcre_exec(); the performance loss is less with - pcre_dfa_exec(), and in both cases there is not much difference for \b. + However, you can set PCRE_UCP if you want Unicode character properties + to be used. This can double the matching time for items such as \d, + when matched with a traditional matching function; the performance loss + is less with a DFA matching function, and in both cases there is not + much difference for \b. When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option @@ -6774,8 +8214,8 @@ AUTHOR REVISION - Last updated: 16 May 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 09 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6804,51 +8244,52 @@ SYNOPSIS OF POSIX API DESCRIPTION - This set of functions provides a POSIX-style API to the PCRE regular - expression package. See the pcreapi documentation for a description of - PCRE's native API, which contains much additional functionality. + This set of functions provides a POSIX-style API for the PCRE regular + expression 8-bit library. See the pcreapi documentation for a descrip- + tion of PCRE's native API, which contains much additional functional- + ity. There is no POSIX-style wrapper for PCRE's 16-bit library. The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the - pcreposix.h header file, and on Unix systems the library itself is - called pcreposix.a, so can be accessed by adding -lpcreposix to the - command for linking an application that uses them. Because the POSIX + pcreposix.h header file, and on Unix systems the library itself is + called pcreposix.a, so can be accessed by adding -lpcreposix to the + command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add -lpcre. - I have implemented only those POSIX option bits that can be reasonably - mapped to PCRE native options. In addition, the option REG_EXTENDED is - defined with the value zero. This has no effect, but since programs - that are written to the POSIX interface often use it, this makes it - easier to slot in PCRE as a replacement library. Other POSIX options + I have implemented only those POSIX option bits that can be reasonably + mapped to PCRE native options. In addition, the option REG_EXTENDED is + defined with the value zero. This has no effect, but since programs + that are written to the POSIX interface often use it, this makes it + easier to slot in PCRE as a replacement library. Other POSIX options are not even defined. - There are also some other options that are not defined by POSIX. These + There are also some other options that are not defined by POSIX. These have been added at the request of users who want to make use of certain PCRE-specific features via the POSIX calling interface. - When PCRE is called via these functions, it is only the API that is - POSIX-like in style. The syntax and semantics of the regular expres- - sions themselves are still those of Perl, subject to the setting of - various PCRE options, as described below. "POSIX-like in style" means - that the API approximates to the POSIX definition; it is not fully - POSIX-compatible, and in multi-byte encoding domains it is probably + When PCRE is called via these functions, it is only the API that is + POSIX-like in style. The syntax and semantics of the regular expres- + sions themselves are still those of Perl, subject to the setting of + various PCRE options, as described below. "POSIX-like in style" means + that the API approximates to the POSIX definition; it is not fully + POSIX-compatible, and in multi-byte encoding domains it is probably even less compatible. - The header for these functions is supplied as pcreposix.h to avoid any - potential clash with other POSIX libraries. It can, of course, be + The header for these functions is supplied as pcreposix.h to avoid any + potential clash with other POSIX libraries. It can, of course, be renamed or aliased as regex.h, which is the "correct" name. It provides - two structure types, regex_t for compiled internal forms, and reg- - match_t for returning captured substrings. It also defines some con- - stants whose names start with "REG_"; these are used for setting + two structure types, regex_t for compiled internal forms, and reg- + match_t for returning captured substrings. It also defines some con- + stants whose names start with "REG_"; these are used for setting options and identifying error codes. COMPILING A PATTERN - The function regcomp() is called to compile a pattern into an internal - form. The pattern is a C string terminated by a binary zero, and is - passed in the argument pattern. The preg argument is a pointer to a - regex_t structure that is used as a base for storing information about + The function regcomp() is called to compile a pattern into an internal + form. The pattern is a C string terminated by a binary zero, and is + passed in the argument pattern. The preg argument is a pointer to a + regex_t structure that is used as a base for storing information about the compiled regular expression. The argument cflags is either zero, or contains one or more of the bits @@ -6862,58 +8303,58 @@ COMPILING A PATTERN REG_ICASE - The PCRE_CASELESS option is set when the regular expression is passed + The PCRE_CASELESS option is set when the regular expression is passed for compilation to the native function. REG_NEWLINE - The PCRE_MULTILINE option is set when the regular expression is passed - for compilation to the native function. Note that this does not mimic - the defined POSIX behaviour for REG_NEWLINE (see the following sec- + The PCRE_MULTILINE option is set when the regular expression is passed + for compilation to the native function. Note that this does not mimic + the defined POSIX behaviour for REG_NEWLINE (see the following sec- tion). REG_NOSUB - The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is + The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed for compilation to the native function. In addition, when a pat- - tern that is compiled with this flag is passed to regexec() for match- - ing, the nmatch and pmatch arguments are ignored, and no captured + tern that is compiled with this flag is passed to regexec() for match- + ing, the nmatch and pmatch arguments are ignored, and no captured strings are returned. REG_UCP - The PCRE_UCP option is set when the regular expression is passed for - compilation to the native function. This causes PCRE to use Unicode - properties when matchine \d, \w, etc., instead of just recognizing + The PCRE_UCP option is set when the regular expression is passed for + compilation to the native function. This causes PCRE to use Unicode + properties when matchine \d, \w, etc., instead of just recognizing ASCII values. Note that REG_UTF8 is not part of the POSIX standard. REG_UNGREEDY - The PCRE_UNGREEDY option is set when the regular expression is passed - for compilation to the native function. Note that REG_UNGREEDY is not + The PCRE_UNGREEDY option is set when the regular expression is passed + for compilation to the native function. Note that REG_UNGREEDY is not part of the POSIX standard. REG_UTF8 - The PCRE_UTF8 option is set when the regular expression is passed for - compilation to the native function. This causes the pattern itself and - all data strings used for matching it to be treated as UTF-8 strings. + The PCRE_UTF8 option is set when the regular expression is passed for + compilation to the native function. This causes the pattern itself and + all data strings used for matching it to be treated as UTF-8 strings. Note that REG_UTF8 is not part of the POSIX standard. - In the absence of these flags, no options are passed to the native - function. This means the the regex is compiled with PCRE default - semantics. In particular, the way it handles newline characters in the - subject string is the Perl way, not the POSIX way. Note that setting - PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. - It does not affect the way newlines are matched by . (they are not) or + In the absence of these flags, no options are passed to the native + function. This means the the regex is compiled with PCRE default + semantics. In particular, the way it handles newline characters in the + subject string is the Perl way, not the POSIX way. Note that setting + PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. + It does not affect the way newlines are matched by . (they are not) or by a negative class such as [^a] (they are). - The yield of regcomp() is zero on success, and non-zero otherwise. The + The yield of regcomp() is zero on success, and non-zero otherwise. The preg structure is filled in on success, and one member of the structure - is public: re_nsub contains the number of capturing subpatterns in the + is public: re_nsub contains the number of capturing subpatterns in the regular expression. Various error codes are defined in the header file. - NOTE: If the yield of regcomp() is non-zero, you must not attempt to + NOTE: If the yield of regcomp() is non-zero, you must not attempt to use the contents of the preg structure. If, for example, you pass it to regexec(), the result is undefined and your program is likely to crash. @@ -6921,9 +8362,9 @@ COMPILING A PATTERN MATCHING NEWLINE CHARACTERS This area is not simple, because POSIX and Perl take different views of - things. It is not possible to get PCRE to obey POSIX semantics, but - then PCRE was never intended to be a POSIX engine. The following table - lists the different possibilities for matching newline characters in + things. It is not possible to get PCRE to obey POSIX semantics, but + then PCRE was never intended to be a POSIX engine. The following table + lists the different possibilities for matching newline characters in PCRE: Default Change with @@ -6945,19 +8386,19 @@ MATCHING NEWLINE CHARACTERS ^ matches \n in middle no REG_NEWLINE PCRE's behaviour is the same as Perl's, except that there is no equiva- - lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is + lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop newline from matching [^a]. - The default POSIX newline handling can be obtained by setting - PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE + The default POSIX newline handling can be obtained by setting + PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE behave exactly as for the REG_NEWLINE action. MATCHING A PATTERN - The function regexec() is called to match a compiled pattern preg - against a given string, which is by default terminated by a zero byte - (but see REG_STARTEND below), subject to the options in eflags. These + The function regexec() is called to match a compiled pattern preg + against a given string, which is by default terminated by a zero byte + (but see REG_STARTEND below), subject to the options in eflags. These can be: REG_NOTBOL @@ -6979,17 +8420,17 @@ MATCHING A PATTERN REG_STARTEND - The string is considered to start at string + pmatch[0].rm_so and to - have a terminating NUL located at string + pmatch[0].rm_eo (there need - not actually be a NUL at that location), regardless of the value of - nmatch. This is a BSD extension, compatible with but not specified by - IEEE Standard 1003.2 (POSIX.2), and should be used with caution in + The string is considered to start at string + pmatch[0].rm_so and to + have a terminating NUL located at string + pmatch[0].rm_eo (there need + not actually be a NUL at that location), regardless of the value of + nmatch. This is a BSD extension, compatible with but not specified by + IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software intended to be portable to other systems. Note that a non-zero rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not how it is matched. - If the pattern was compiled with the REG_NOSUB flag, no data about any - matched strings is returned. The nmatch and pmatch arguments of + If the pattern was compiled with the REG_NOSUB flag, no data about any + matched strings is returned. The nmatch and pmatch arguments of regexec() are ignored. If the value of nmatch is zero, or if the value pmatch is NULL, no data @@ -6997,34 +8438,34 @@ MATCHING A PATTERN Otherwise,the portion of the string that was matched, and also any cap- tured substrings, are returned via the pmatch argument, which points to - an array of nmatch structures of type regmatch_t, containing the mem- - bers rm_so and rm_eo. These contain the offset to the first character - of each substring and the offset to the first character after the end - of each substring, respectively. The 0th element of the vector relates - to the entire portion of string that was matched; subsequent elements - relate to the capturing subpatterns of the regular expression. Unused + an array of nmatch structures of type regmatch_t, containing the mem- + bers rm_so and rm_eo. These contain the offset to the first character + of each substring and the offset to the first character after the end + of each substring, respectively. The 0th element of the vector relates + to the entire portion of string that was matched; subsequent elements + relate to the capturing subpatterns of the regular expression. Unused entries in the array have both structure members set to -1. - A successful match yields a zero return; various error codes are - defined in the header file, of which REG_NOMATCH is the "expected" + A successful match yields a zero return; various error codes are + defined in the header file, of which REG_NOMATCH is the "expected" failure code. ERROR MESSAGES The regerror() function maps a non-zero errorcode from either regcomp() - or regexec() to a printable message. If preg is not NULL, the error + or regexec() to a printable message. If preg is not NULL, the error should have arisen from the use of that structure. A message terminated - by a binary zero is placed in errbuf. The length of the message, - including the zero, is limited to errbuf_size. The yield of the func- + by a binary zero is placed in errbuf. The length of the message, + including the zero, is limited to errbuf_size. The yield of the func- tion is the size of buffer needed to hold the whole message. MEMORY USAGE - Compiling a regular expression causes memory to be allocated and asso- - ciated with the preg structure. The function regfree() frees all such - memory, after which preg may no longer be used as a compiled expres- + Compiling a regular expression causes memory to be allocated and asso- + ciated with the preg structure. The function regfree() frees all such + memory, after which preg may no longer be used as a compiled expres- sion. @@ -7037,8 +8478,8 @@ AUTHOR REVISION - Last updated: 16 May 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 09 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -7059,13 +8500,14 @@ DESCRIPTION The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was con- structed from the notes in the pcrecpp.h file, which should be con- - sulted for further details. + sulted for further details. Note that the C++ wrapper supports only the + original 8-bit PCRE library. There is no 16-bit support at present. MATCHING INTERFACE - The "FullMatch" operation checks that supplied text matches a supplied - pattern exactly. If pointer arguments are supplied, it copies matched + The "FullMatch" operation checks that supplied text matches a supplied + pattern exactly. If pointer arguments are supplied, it copies matched sub-strings that match sub-patterns into them. Example: successful match @@ -7079,10 +8521,10 @@ MATCHING INTERFACE Example: creating a temporary RE object: pcrecpp::RE("h.*o").FullMatch("hello"); - You can pass in a "const char*" or a "string" for "text". The examples - below tend to use a const char*. You can, as in the different examples - above, store the RE object explicitly in a variable or use a temporary - RE object. The examples below use one mode or the other arbitrarily. + You can pass in a "const char*" or a "string" for "text". The examples + below tend to use a const char*. You can, as in the different examples + above, store the RE object explicitly in a variable or use a temporary + RE object. The examples below use one mode or the other arbitrarily. Either could correctly be used for any of these examples. You must supply extra pointer arguments to extract matched subpieces. @@ -7108,7 +8550,7 @@ MATCHING INTERFACE Example: fails because string cannot be stored in integer !pcrecpp::RE("(.*)").FullMatch("ruby", &i); - The provided pointer arguments can be pointers to any scalar numeric + The provided pointer arguments can be pointers to any scalar numeric type, or one of: string (matched piece is copied to string) @@ -7116,7 +8558,7 @@ MATCHING INTERFACE T (where "bool T::ParseFrom(const char*, int)" exists) NULL (the corresponding matched sub-pattern is not copied) - The function returns true iff all of the following conditions are sat- + The function returns true iff all of the following conditions are sat- isfied: a. "text" matches "pattern" exactly; @@ -7131,41 +8573,41 @@ MATCHING INTERFACE number of sub-patterns, "i"th captured sub-pattern is ignored. - CAVEAT: An optional sub-pattern that does not exist in the matched - string is assigned the empty string. Therefore, the following will + CAVEAT: An optional sub-pattern that does not exist in the matched + string is assigned the empty string. Therefore, the following will return false (because the empty string is not a valid number): int number; pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); - The matching interface supports at most 16 arguments per call. If you - need more, consider using the more general interface + The matching interface supports at most 16 arguments per call. If you + need more, consider using the more general interface pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch. - NOTE: Do not use no_arg, which is used internally to mark the end of a - list of optional arguments, as a placeholder for missing arguments, as + NOTE: Do not use no_arg, which is used internally to mark the end of a + list of optional arguments, as a placeholder for missing arguments, as this can lead to segfaults. QUOTING METACHARACTERS - You can use the "QuoteMeta" operation to insert backslashes before all - potentially meaningful characters in a string. The returned string, + You can use the "QuoteMeta" operation to insert backslashes before all + potentially meaningful characters in a string. The returned string, used as a regular expression, will exactly match the original string. Example: string quoted = RE::QuoteMeta(unquoted); - Note that it's legal to escape a character even if it has no special - meaning in a regular expression -- so this function does that. (This - also makes it identical to the perl function of the same name; see - "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes + Note that it's legal to escape a character even if it has no special + meaning in a regular expression -- so this function does that. (This + also makes it identical to the perl function of the same name; see + "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes "1\.5\-2\.0\?". PARTIAL MATCHES - You can use the "PartialMatch" operation when you want the pattern to + You can use the "PartialMatch" operation when you want the pattern to match any substring of the text. Example: simple search for a string: @@ -7180,13 +8622,13 @@ PARTIAL MATCHES UTF-8 AND THE MATCHING INTERFACE - By default, pattern and text are plain text, one byte per character. - The UTF8 flag, passed to the constructor, causes both pattern and + By default, pattern and text are plain text, one byte per character. + The UTF8 flag, passed to the constructor, causes both pattern and string to be treated as UTF-8 text, still a byte stream but potentially - multiple bytes per character. In practice, the text is likelier to be - UTF-8 than the pattern, but the match returned may depend on the UTF8 - flag, so always use it when matching UTF8 text. For example, "." will - match one byte normally but with UTF8 set may match up to three bytes + multiple bytes per character. In practice, the text is likelier to be + UTF-8 than the pattern, but the match returned may depend on the UTF8 + flag, so always use it when matching UTF8 text. For example, "." will + match one byte normally but with UTF8 set may match up to three bytes of a multi-byte character. Example: @@ -7205,9 +8647,9 @@ UTF-8 AND THE MATCHING INTERFACE PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE - PCRE defines some modifiers to change the behavior of the regular - expression engine. The C++ wrapper defines an auxiliary class, - RE_Options, as a vehicle to pass such modifiers to a RE class. Cur- + PCRE defines some modifiers to change the behavior of the regular + expression engine. The C++ wrapper defines an auxiliary class, + RE_Options, as a vehicle to pass such modifiers to a RE class. Cur- rently, the following modifiers are supported: modifier description Perl corresponding @@ -7217,20 +8659,20 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE PCRE_DOTALL dot matches newlines /s PCRE_DOLLAR_ENDONLY $ matches only at end N/A PCRE_EXTRA strict escape parsing N/A - PCRE_EXTENDED ignore whitespaces /x + PCRE_EXTENDED ignore white spaces /x PCRE_UTF8 handles UTF8 chars built-in PCRE_UNGREEDY reverses * and *? N/A PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*) - (*) Both Perl and PCRE allow non capturing parentheses by means of the - "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap- + (*) Both Perl and PCRE allow non capturing parentheses by means of the + "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap- ture, while (ab|cd) does. - For a full account on how each modifier works, please check the PCRE + For a full account on how each modifier works, please check the PCRE API reference page. - For each modifier, there are two member functions whose name is made - out of the modifier in lowercase, without the "PCRE_" prefix. For + For each modifier, there are two member functions whose name is made + out of the modifier in lowercase, without the "PCRE_" prefix. For instance, PCRE_CASELESS is handled by bool caseless() @@ -7240,28 +8682,28 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE RE_Options & set_caseless(bool) which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can - be accessed through the set_match_limit() and match_limit() member - functions. Setting match_limit to a non-zero value will limit the exe- - cution of pcre to keep it from doing bad things like blowing the stack - or taking an eternity to return a result. A value of 5000 is good - enough to stop stack blowup in a 2MB thread stack. Setting match_limit - to zero disables match limiting. Alternatively, you can call - match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to - limit how much PCRE recurses. match_limit() limits the number of + be accessed through the set_match_limit() and match_limit() member + functions. Setting match_limit to a non-zero value will limit the exe- + cution of pcre to keep it from doing bad things like blowing the stack + or taking an eternity to return a result. A value of 5000 is good + enough to stop stack blowup in a 2MB thread stack. Setting match_limit + to zero disables match limiting. Alternatively, you can call + match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to + limit how much PCRE recurses. match_limit() limits the number of matches PCRE does; match_limit_recursion() limits the depth of internal recursion, and therefore the amount of stack that is used. - Normally, to pass one or more modifiers to a RE class, you declare a + Normally, to pass one or more modifiers to a RE class, you declare a RE_Options object, set the appropriate options, and pass this object to a RE constructor. Example: - RE_options opt; + RE_Options opt; opt.set_caseless(true); if (RE("HELLO", opt).PartialMatch("hello world")) ... RE_options has two constructors. The default constructor takes no argu- - ments and creates a set of flags that are off by default. The optional - parameter option_flags is to facilitate transfer of legacy code from C + ments and creates a set of flags that are off by default. The optional + parameter option_flags is to facilitate transfer of legacy code from C programs. This lets you do RE(pattern, @@ -7275,15 +8717,15 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE If you are going to pass one of the most used modifiers, there are some convenience functions that return a RE_Options class with the appropri- - ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), + ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), and EXTENDED(). - If you need to set several options at once, and you don't want to go - through the pains of declaring a RE_Options object and setting several - options, there is a parallel method that give you such ability on the - fly. You can concatenate several set_xxxxx() member functions, since - each of them returns a reference to its class object. For example, to - pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one + If you need to set several options at once, and you don't want to go + through the pains of declaring a RE_Options object and setting several + options, there is a parallel method that give you such ability on the + fly. You can concatenate several set_xxxxx() member functions, since + each of them returns a reference to its class object. For example, to + pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one statement, you may write: RE(" ^ xyz \\s+ .* blah$", @@ -7295,10 +8737,10 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE SCANNING TEXT INCREMENTALLY - The "Consume" operation may be useful if you want to repeatedly match + The "Consume" operation may be useful if you want to repeatedly match regular expressions at the front of a string and skip over them as they - match. This requires use of the "StringPiece" type, which represents a - sub-range of a real string. Like RE, StringPiece is defined in the + match. This requires use of the "StringPiece" type, which represents a + sub-range of a real string. Like RE, StringPiece is defined in the pcrecpp namespace. Example: read lines of the form "var = value" from a string. @@ -7312,11 +8754,11 @@ SCANNING TEXT INCREMENTALLY ...; } - Each successful call to "Consume" will set "var/value", and also + Each successful call to "Consume" will set "var/value", and also advance "input" so it points past the matched text. - The "FindAndConsume" operation is similar to "Consume" but does not - anchor your match at the beginning of the string. For example, you + The "FindAndConsume" operation is similar to "Consume" but does not + anchor your match at the beginning of the string. For example, you could extract all words from a string by repeatedly calling pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) @@ -7325,10 +8767,10 @@ SCANNING TEXT INCREMENTALLY PARSING HEX/OCTAL/C-RADIX NUMBERS By default, if you pass a pointer to a numeric value, the corresponding - text is interpreted as a base-10 number. You can instead wrap the + text is interpreted as a base-10 number. You can instead wrap the pointer with a call to one of the operators Hex(), Octal(), or CRadix() - to interpret the text in another base. The CRadix operator interprets - C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to + to interpret the text in another base. The CRadix operator interprets + C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to base-10. Example: @@ -7343,30 +8785,30 @@ PARSING HEX/OCTAL/C-RADIX NUMBERS REPLACING PARTS OF STRINGS - You can replace the first match of "pattern" in "str" with "rewrite". - Within "rewrite", backslash-escaped digits (\1 to \9) can be used to - insert text matching corresponding parenthesized group from the pat- + You can replace the first match of "pattern" in "str" with "rewrite". + Within "rewrite", backslash-escaped digits (\1 to \9) can be used to + insert text matching corresponding parenthesized group from the pat- tern. \0 in "rewrite" refers to the entire matching text. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").Replace("d", &s); - will leave "s" containing "yada dabba doo". The result is true if the + will leave "s" containing "yada dabba doo". The result is true if the pattern matches and a replacement occurs, false otherwise. - GlobalReplace is like Replace except that it replaces all occurrences - of the pattern in the string with the rewrite. Replacements are not + GlobalReplace is like Replace except that it replaces all occurrences + of the pattern in the string with the rewrite. Replacements are not subject to re-matching. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").GlobalReplace("d", &s); - will leave "s" containing "yada dada doo". It returns the number of + will leave "s" containing "yada dada doo". It returns the number of replacements made. - Extract is like Replace, except that if the pattern matches, "rewrite" - is copied into "out" (an additional argument) with substitutions. The - non-matching portions of "text" are ignored. Returns true iff a match + Extract is like Replace, except that if the pattern matches, "rewrite" + is copied into "out" (an additional argument) with substitutions. The + non-matching portions of "text" are ignored. Returns true iff a match occurred and the extraction happened successfully; if no match occurs, the string is left unaffected. @@ -7379,7 +8821,7 @@ AUTHOR REVISION - Last updated: 17 March 2009 + Last updated: 08 January 2012 ------------------------------------------------------------------------------ @@ -7398,57 +8840,58 @@ PCRE SAMPLE PROGRAM do not have a copy of the PCRE distribution, you can save this listing to re-create pcredemo.c. - The program compiles the regular expression that is its first argument, - and matches it against the subject string in its second argument. No - PCRE options are set, and default character tables are used. If match- - ing succeeds, the program outputs the portion of the subject that - matched, together with the contents of any captured substrings. + The demonstration program, which uses the original PCRE 8-bit library, + compiles the regular expression that is its first argument, and matches + it against the subject string in its second argument. No PCRE options + are set, and default character tables are used. If matching succeeds, + the program outputs the portion of the subject that matched, together + with the contents of any captured substrings. If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same - subject string. The logic is a little bit tricky because of the possi- - bility of matching an empty string. Comments in the code explain what + subject string. The logic is a little bit tricky because of the possi- + bility of matching an empty string. Comments in the code explain what is going on. - If PCRE is installed in the standard include and library directories + If PCRE is installed in the standard include and library directories for your operating system, you should be able to compile the demonstra- tion program using this command: gcc -o pcredemo pcredemo.c -lpcre - If PCRE is installed elsewhere, you may need to add additional options - to the command line. For example, on a Unix-like system that has PCRE - installed in /usr/local, you can compile the demonstration program + If PCRE is installed elsewhere, you may need to add additional options + to the command line. For example, on a Unix-like system that has PCRE + installed in /usr/local, you can compile the demonstration program using a command like this: gcc -o pcredemo -I/usr/local/include pcredemo.c \ -L/usr/local/lib -lpcre - In a Windows environment, if you want to statically link the program + In a Windows environment, if you want to statically link the program against a non-dll pcre.a file, you must uncomment the line that defines - PCRE_STATIC before including pcre.h, because otherwise the pcre_mal- + PCRE_STATIC before including pcre.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. - Once you have compiled and linked the demonstration program, you can + Once you have compiled and linked the demonstration program, you can run simple tests like this: ./pcredemo 'cat|dog' 'the cat sat on the mat' ./pcredemo -g 'cat|dog' 'the dog sat on the cat' - Note that there is a much more comprehensive test program, called - pcretest, which supports many more facilities for testing regular - expressions and the PCRE library. The pcredemo program is provided as a - simple coding example. + Note that there is a much more comprehensive test program, called + pcretest, which supports many more facilities for testing regular + expressions and both PCRE libraries. The pcredemo program is provided + as a simple coding example. - If you try to run pcredemo when PCRE is not installed in the standard - library directory, you may get an error like this on some operating + If you try to run pcredemo when PCRE is not installed in the standard + library directory, you may get an error like this on some operating systems (e.g. Solaris): - ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or + ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory - This is caused by the way shared library support works on those sys- + This is caused by the way shared library support works on those sys- tems. You need to add -R/usr/local/lib @@ -7465,9 +8908,71 @@ AUTHOR REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ +PCRELIMITS(3) PCRELIMITS(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +SIZE AND OTHER LIMITATIONS + + There are some size limitations in PCRE but it is hoped that they will + never in practice be relevant. + + The maximum length of a compiled pattern is approximately 64K data + units (bytes for the 8-bit library, 16-bit units for the 16-bit + library) if PCRE is compiled with the default internal linkage size of + 2 bytes. If you want to process regular expressions that are truly + enormous, you can compile PCRE with an internal linkage size of 3 or 4 + (when building the 16-bit library, 3 is rounded up to 4). See the + README file in the source distribution and the pcrebuild documentation + for details. In these cases the limit is substantially larger. How- + ever, the speed of execution is slower. + + All values in repeating quantifiers must be less than 65536. + + There is no limit to the number of parenthesized subpatterns, but there + can be no more than 65535 capturing subpatterns. + + There is a limit to the number of forward references to subsequent sub- + patterns of around 200,000. Repeated forward references with fixed + upper limits, for example, (?2){0,100} when subpattern number 2 is to + the right, are included in the count. There is no limit to the number + of backward references. + + The maximum length of name for a named subpattern is 32 characters, and + the maximum number of named subpatterns is 10000. + + The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or + (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit + library. + + The maximum length of a subject string is the largest positive number + that an integer variable can hold. However, when using the traditional + matching function, PCRE uses recursion to handle subpatterns and indef- + inite repetition. This means that the available stack space may limit + the size of a subject string that can be processed by certain patterns. + For a discussion of stack issues, see the pcrestack documentation. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 04 May 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + PCRESTACK(3) PCRESTACK(3) @@ -7477,12 +8982,14 @@ NAME PCRE DISCUSSION OF STACK USAGE - When you call pcre_exec(), it makes use of an internal function called - match(). This calls itself recursively at branch points in the pattern, - in order to remember the state of the match so that it can back up and - try a different alternative if the first one fails. As matching pro- - ceeds deeper and deeper into the tree of possibilities, the recursion - depth increases. + When you call pcre[16]_exec(), it makes use of an internal function + called match(). This calls itself recursively at branch points in the + pattern, in order to remember the state of the match so that it can + back up and try a different alternative if the first one fails. As + matching proceeds deeper and deeper into the tree of possibilities, the + recursion depth increases. The match() function is also called in other + circumstances, for example, whenever a parenthesized sub-pattern is + entered, and in certain cases of repetition. Not all calls of match() increase the recursion depth; for an item such as a* it may be called several times at the same level, after matching @@ -7491,20 +8998,28 @@ PCRE DISCUSSION OF STACK USAGE result of the current call (a "tail recursion"), the function is just restarted instead. - The pcre_dfa_exec() function operates in an entirely different way, and - uses recursion only when there is a regular expression recursion or + The above comments apply when pcre[16]_exec() is run in its normal + interpretive manner. If the pattern was studied with the + PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was success- + ful, and the options passed to pcre[16]_exec() were not incompatible, + the matching process uses the JIT-compiled code instead of the match() + function. In this case, the memory requirements are handled entirely + differently. See the pcrejit documentation for details. + + The pcre[16]_dfa_exec() function operates in an entirely different way, + and uses recursion only when there is a regular expression recursion or subroutine call in the pattern. This includes the processing of asser- tion and "once-only" subpatterns, which are handled like subroutine calls. Normally, these are never very deep, and the limit on the com- - plexity of pcre_dfa_exec() is controlled by the amount of workspace it - is given. However, it is possible to write patterns with runaway infi- - nite recursions; such patterns will cause pcre_dfa_exec() to run out of - stack. At present, there is no protection against this. + plexity of pcre[16]_dfa_exec() is controlled by the amount of workspace + it is given. However, it is possible to write patterns with runaway + infinite recursions; such patterns will cause pcre[16]_dfa_exec() to + run out of stack. At present, there is no protection against this. - The comments that follow do NOT apply to pcre_dfa_exec(); they are rel- - evant only for pcre_exec(). + The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are + relevant only for pcre[16]_exec() without the JIT optimization. - Reducing pcre_exec()'s stack usage + Reducing pcre[16]_exec()'s stack usage Each time that match() is actually called recursively, it uses memory from the process stack. For certain kinds of pattern and data, very @@ -7537,31 +9052,31 @@ PCRE DISCUSSION OF STACK USAGE ing long subject strings is to write repeated parenthesized subpatterns to match more than one character whenever possible. - Compiling PCRE to use heap instead of stack for pcre_exec() + Compiling PCRE to use heap instead of stack for pcre[16]_exec() In environments where stack memory is constrained, you might want to compile PCRE to use heap memory instead of stack for remembering back- - up points when pcre_exec() is running. This makes it run a lot more + up points when pcre[16]_exec() is running. This makes it run a lot more slowly, however. Details of how to do this are given in the pcrebuild documentation. When built in this way, instead of using the stack, PCRE obtains and frees memory by calling the functions that are pointed to - by the pcre_stack_malloc and pcre_stack_free variables. By default, - these point to malloc() and free(), but you can replace the pointers to - cause PCRE to use your own functions. Since the block sizes are always - the same, and are always freed in reverse order, it may be possible to - implement customized memory handlers that are more efficient than the - standard functions. + by the pcre[16]_stack_malloc and pcre[16]_stack_free variables. By + default, these point to malloc() and free(), but you can replace the + pointers to cause PCRE to use your own functions. Since the block sizes + are always the same, and are always freed in reverse order, it may be + possible to implement customized memory handlers that are more effi- + cient than the standard functions. - Limiting pcre_exec()'s stack usage + Limiting pcre[16]_exec()'s stack usage You can set limits on the number of times that match() is called, both - in total and recursively. If a limit is exceeded, pcre_exec() returns - an error code. Setting suitable limits should prevent it from running - out of stack. The default values of the limits are very large, and - unlikely ever to operate. They can be changed when PCRE is built, and - they can also be set when pcre_exec() is called. For details of these - interfaces, see the pcrebuild documentation and the section on extra - data for pcre_exec() in the pcreapi documentation. + in total and recursively. If a limit is exceeded, pcre[16]_exec() + returns an error code. Setting suitable limits should prevent it from + running out of stack. The default values of the limits are very large, + and unlikely ever to operate. They can be changed when PCRE is built, + and they can also be set when pcre[16]_exec() is called. For details of + these interfaces, see the pcrebuild documentation and the section on + extra data for pcre[16]_exec() in the pcreapi documentation. As a very rough rule of thumb, you should reckon on about 500 bytes per recursion. Thus, if you want to limit your stack usage to 8Mb, you @@ -7572,9 +9087,33 @@ PCRE DISCUSSION OF STACK USAGE option (-S) that can be used to increase the size of its stack. As long as the stack is large enough, another option (-M) can be used to find the smallest limits that allow a particular pattern to match a given - subject string. This is done by calling pcre_exec() repeatedly with + subject string. This is done by calling pcre[16]_exec() repeatedly with different limits. + Obtaining an estimate of stack usage + + The actual amount of stack used per recursion can vary quite a lot, + depending on the compiler that was used to build PCRE and the optimiza- + tion or debugging options that were set for it. The rule of thumb value + of 500 bytes mentioned above may be larger or smaller than what is + actually needed. A better approximation can be obtained by running this + command: + + pcretest -m -C + + The -C option causes pcretest to output information about the options + with which PCRE was compiled. When -m is also given (before -C), infor- + mation about stack use is given in a line like this: + + Match recursion uses stack: approximate frame size = 640 bytes + + The value is approximate because some recursions need a bit more (up to + perhaps 16 more bytes). + + If the above command is given when PCRE is compiled to use the heap + instead of the stack for recursion, the value that is output is the + size of each block that is obtained from the heap. + Changing stack size in Unix-like systems In Unix-like environments, there is not often a problem with the stack @@ -7595,7 +9134,7 @@ PCRE DISCUSSION OF STACK USAGE This reads the current limits (soft and hard) using getrlimit(), then attempts to increase the soft limit to 100Mb using setrlimit(). You - must do this before calling pcre_exec(). + must do this before calling pcre[16]_exec(). Changing stack size in Mac OS X @@ -7614,8 +9153,8 @@ AUTHOR REVISION - Last updated: 03 January 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 21 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ diff --git a/ext/pcre/pcrelib/pcre.h b/ext/pcre/pcrelib/pcre.h index 21c46737243..b71ead37a8f 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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 12 +#define PCRE_MINOR 31 #define PCRE_PRERELEASE -#define PCRE_DATE 2011-01-15 +#define PCRE_DATE 2012-07-06 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate @@ -98,28 +98,37 @@ extern "C" { /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. However, almost all the bits in the options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. */ +compile-time only bits for runtime options, or vice versa. In the comments +below, "compile", "exec", and "DFA exec" mean that the option is permitted to +be set for those functions; "used in" means that an option may be set only for +compile, but is subsequently referenced in exec and/or DFA exec. Any of the +compile-time options may be inspected during studying (and therefore JIT +compiling). */ #define PCRE_CASELESS 0x00000001 /* Compile */ #define PCRE_MULTILINE 0x00000002 /* Compile */ #define PCRE_DOTALL 0x00000004 /* Compile */ #define PCRE_EXTENDED 0x00000008 /* Compile */ #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ -#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ #define PCRE_EXTRA 0x00000040 /* Compile */ #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ #define PCRE_UNGREEDY 0x00000200 /* Compile */ #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ -#define PCRE_UTF8 0x00000800 /* Compile */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ +#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ -#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ -#define PCRE_FIRSTLINE 0x00040000 /* Compile */ +#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ #define PCRE_DUPNAMES 0x00080000 /* Compile */ #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ @@ -128,41 +137,82 @@ compile-time only bits for runtime options, or vice versa. */ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ -#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ -#define PCRE_UCP 0x20000000 /* Compile */ +#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ -#define PCRE_ERROR_NOMATCH (-1) -#define PCRE_ERROR_NULL (-2) -#define PCRE_ERROR_BADOPTION (-3) -#define PCRE_ERROR_BADMAGIC (-4) -#define PCRE_ERROR_UNKNOWN_OPCODE (-5) -#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ -#define PCRE_ERROR_NOMEMORY (-6) -#define PCRE_ERROR_NOSUBSTRING (-7) -#define PCRE_ERROR_MATCHLIMIT (-8) -#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ -#define PCRE_ERROR_BADUTF8 (-10) -#define PCRE_ERROR_BADUTF8_OFFSET (-11) -#define PCRE_ERROR_PARTIAL (-12) -#define PCRE_ERROR_BADPARTIAL (-13) -#define PCRE_ERROR_INTERNAL (-14) -#define PCRE_ERROR_BADCOUNT (-15) -#define PCRE_ERROR_DFA_UITEM (-16) -#define PCRE_ERROR_DFA_UCOND (-17) -#define PCRE_ERROR_DFA_UMLIMIT (-18) -#define PCRE_ERROR_DFA_WSSIZE (-19) -#define PCRE_ERROR_DFA_RECURSE (-20) -#define PCRE_ERROR_RECURSIONLIMIT (-21) -#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ -#define PCRE_ERROR_BADNEWLINE (-23) -#define PCRE_ERROR_BADOFFSET (-24) -#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_OPCODE (-5) +#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) +#define PCRE_ERROR_DFA_UITEM (-16) +#define PCRE_ERROR_DFA_UCOND (-17) +#define PCRE_ERROR_DFA_UMLIMIT (-18) +#define PCRE_ERROR_DFA_WSSIZE (-19) +#define PCRE_ERROR_DFA_RECURSE (-20) +#define PCRE_ERROR_RECURSIONLIMIT (-21) +#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ +#define PCRE_ERROR_BADNEWLINE (-23) +#define PCRE_ERROR_BADOFFSET (-24) +#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ +#define PCRE_ERROR_RECURSELOOP (-26) +#define PCRE_ERROR_JIT_STACKLIMIT (-27) +#define PCRE_ERROR_BADMODE (-28) +#define PCRE_ERROR_BADENDIANNESS (-29) +#define PCRE_ERROR_DFA_BADRESTART (-30) + +/* Specific error codes for UTF-8 validity checks */ + +#define PCRE_UTF8_ERR0 0 +#define PCRE_UTF8_ERR1 1 +#define PCRE_UTF8_ERR2 2 +#define PCRE_UTF8_ERR3 3 +#define PCRE_UTF8_ERR4 4 +#define PCRE_UTF8_ERR5 5 +#define PCRE_UTF8_ERR6 6 +#define PCRE_UTF8_ERR7 7 +#define PCRE_UTF8_ERR8 8 +#define PCRE_UTF8_ERR9 9 +#define PCRE_UTF8_ERR10 10 +#define PCRE_UTF8_ERR11 11 +#define PCRE_UTF8_ERR12 12 +#define PCRE_UTF8_ERR13 13 +#define PCRE_UTF8_ERR14 14 +#define PCRE_UTF8_ERR15 15 +#define PCRE_UTF8_ERR16 16 +#define PCRE_UTF8_ERR17 17 +#define PCRE_UTF8_ERR18 18 +#define PCRE_UTF8_ERR19 19 +#define PCRE_UTF8_ERR20 20 +#define PCRE_UTF8_ERR21 21 + +/* Specific error codes for UTF-16 validity checks */ + +#define PCRE_UTF16_ERR0 0 +#define PCRE_UTF16_ERR1 1 +#define PCRE_UTF16_ERR2 2 +#define PCRE_UTF16_ERR3 3 +#define PCRE_UTF16_ERR4 4 /* Request types for pcre_fullinfo() */ @@ -183,6 +233,9 @@ compile-time only bits for runtime options, or vice versa. */ #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 +#define PCRE_INFO_JIT 16 +#define PCRE_INFO_JITSIZE 17 +#define PCRE_INFO_MAXLOOKBEHIND 18 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -196,8 +249,18 @@ compatible. */ #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 +#define PCRE_CONFIG_JIT 9 +#define PCRE_CONFIG_UTF16 10 +#define PCRE_CONFIG_JITTARGET 11 -/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine +/* Request types for pcre_study(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_STUDY_JIT_COMPILE 0x0001 +#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 +#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 + +/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 @@ -206,12 +269,33 @@ these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 +#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; +struct real_pcre16; /* declaration; the definition is private */ +typedef struct real_pcre16 pcre16; + +struct real_pcre_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre_jit_stack pcre_jit_stack; + +struct real_pcre16_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre16_jit_stack pcre16_jit_stack; + +/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain +a 16 bit wide signed data type. Otherwise it can be a dummy data type since +pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR16 +#define PCRE_UCHAR16 unsigned short +#endif + +#ifndef PCRE_SPTR16 +#define PCRE_SPTR16 const PCRE_UCHAR16 * +#endif + /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ @@ -232,8 +316,22 @@ typedef struct pcre_extra { const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre_extra; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ + unsigned long int match_limit_recursion; /* Max recursive calls to match() */ + PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ +} pcre16_extra; + /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work @@ -254,9 +352,33 @@ typedef struct pcre_callout_block { /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const unsigned char *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre_callout_block; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR16 subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ +} pcre16_callout_block; + /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function @@ -269,47 +391,114 @@ PCRE_EXP_DECL void (*pcre_free)(void *); PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); + +PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_free)(void *); +PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_stack_free)(void *); +PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); + +PCRE_EXP_DECL void *pcre16_malloc(size_t); +PCRE_EXP_DECL void pcre16_free(void *); +PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); +PCRE_EXP_DECL void pcre16_stack_free(void *); +PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); #endif /* VPCOMPAT */ +/* User defined callback which provides a stack just before the match starts. */ + +typedef pcre_jit_stack *(*pcre_jit_callback)(void *); +typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); + /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, + const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, + int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); +PCRE_EXP_DECL int pcre16_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); -PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, - int); +PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); +PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, + char *, int); +PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, + PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); +PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); +PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); +PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, + void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); +PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); +PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); +PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, + PCRE_UCHAR16 **, PCRE_UCHAR16 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); +PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, + PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); -PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); +PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); +PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); +PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); PCRE_EXP_DECL const char *pcre_version(void); +PCRE_EXP_DECL const char *pcre16_version(void); + +/* Utility functions for byte order swaps. */ +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); + +/* JIT compiler related functions. */ + +PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); +PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); +PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); +PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); +PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, + pcre_jit_callback, void *); +PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, + pcre16_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c index b0d81ac94c9..999ff80b5eb 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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -51,12 +51,16 @@ supporting internal functions that are not used by other modules. */ #include "pcre_internal.h" -/* When PCRE_DEBUG is defined, we need the pcre_printint() function, which is -also used by pcretest. PCRE_DEBUG is not defined when building a production -library. */ +/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which +is also used by pcretest. PCRE_DEBUG is not defined when building a production +library. We do not need to select pcre16_printint.c specially, because the +COMPILE_PCREx macro will already be appropriately set. */ #ifdef PCRE_DEBUG -#include "pcre_printint.src" +/* pcre_printint.c should not include any headers */ +#define PCRE_INCLUDED +#include "pcre_printint.c" +#undef PCRE_INCLUDED #endif @@ -86,15 +90,30 @@ so this number is very generous. The same workspace is used during the second, actual compile phase for remembering forward references to groups so that they can be filled in at the end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE -is 4 there is plenty of room. */ +is 4 there is plenty of room for most patterns. However, the memory can get +filled up by repetitions of forward references, for example patterns like +/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so +that the workspace is expanded using malloc() in this situation. The value +below is therefore a minimum, and we put a maximum on it for safety. The +minimum is now also defined in terms of LINK_SIZE so that the use of malloc() +kicks in at the same number of forward references in all cases. */ -#define COMPILE_WORK_SIZE (4096) +#define COMPILE_WORK_SIZE (2048*LINK_SIZE) +#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE) /* The overrun tests check for a slightly smaller size so that they detect the overrun before it actually does run off the end of the data block. */ -#define WORK_SIZE_CHECK (COMPILE_WORK_SIZE - 100) +#define WORK_SIZE_SAFETY_MARGIN (100) +/* Private flags added to firstchar and reqchar. */ + +#define REQ_CASELESS 0x10000000l /* Indicates caselessness */ +#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */ + +/* Repeated character flags. */ + +#define UTF_LENGTH 0x10000000l /* The char contains its length. */ /* Table for handling escaped characters in the range '0'-'z'. Positive returns are simple data values; negative values are for special things like \d and so @@ -229,7 +248,7 @@ static const char posix_names[] = STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 STRING_word0 STRING_xdigit; -static const uschar posix_name_lengths[] = { +static const pcre_uint8 posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; /* Table of class bit maps for each POSIX class. Each class is formed from a @@ -264,47 +283,101 @@ substitutes must be in the order of the names, defined above, and there are both positive and negative cases. NULL means no substitute. */ #ifdef SUPPORT_UCP -static const uschar *substitutes[] = { - (uschar *)"\\P{Nd}", /* \D */ - (uschar *)"\\p{Nd}", /* \d */ - (uschar *)"\\P{Xsp}", /* \S */ /* NOTE: Xsp is Perl space */ - (uschar *)"\\p{Xsp}", /* \s */ - (uschar *)"\\P{Xwd}", /* \W */ - (uschar *)"\\p{Xwd}" /* \w */ +static const pcre_uchar string_PNd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pNd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXsp[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXsp[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXwd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXwd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static const pcre_uchar *substitutes[] = { + string_PNd, /* \D */ + string_pNd, /* \d */ + string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */ + string_pXsp, /* \s */ + string_PXwd, /* \W */ + string_pXwd /* \w */ }; -static const uschar *posix_substitutes[] = { - (uschar *)"\\p{L}", /* alpha */ - (uschar *)"\\p{Ll}", /* lower */ - (uschar *)"\\p{Lu}", /* upper */ - (uschar *)"\\p{Xan}", /* alnum */ - NULL, /* ascii */ - (uschar *)"\\h", /* blank */ - NULL, /* cntrl */ - (uschar *)"\\p{Nd}", /* digit */ - NULL, /* graph */ - NULL, /* print */ - NULL, /* punct */ - (uschar *)"\\p{Xps}", /* space */ /* NOTE: Xps is POSIX space */ - (uschar *)"\\p{Xwd}", /* word */ - NULL, /* xdigit */ +static const pcre_uchar string_pL[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pLl[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pLu[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXan[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_h[] = { + CHAR_BACKSLASH, CHAR_h, '\0' }; +static const pcre_uchar string_pXps[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PL[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PLl[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PLu[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXan[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_H[] = { + CHAR_BACKSLASH, CHAR_H, '\0' }; +static const pcre_uchar string_PXps[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static const pcre_uchar *posix_substitutes[] = { + string_pL, /* alpha */ + string_pLl, /* lower */ + string_pLu, /* upper */ + string_pXan, /* alnum */ + NULL, /* ascii */ + string_h, /* blank */ + NULL, /* cntrl */ + string_pNd, /* digit */ + NULL, /* graph */ + NULL, /* print */ + NULL, /* punct */ + string_pXps, /* space */ /* NOTE: Xps is POSIX space */ + string_pXwd, /* word */ + NULL, /* xdigit */ /* Negated cases */ - (uschar *)"\\P{L}", /* ^alpha */ - (uschar *)"\\P{Ll}", /* ^lower */ - (uschar *)"\\P{Lu}", /* ^upper */ - (uschar *)"\\P{Xan}", /* ^alnum */ - NULL, /* ^ascii */ - (uschar *)"\\H", /* ^blank */ - NULL, /* ^cntrl */ - (uschar *)"\\P{Nd}", /* ^digit */ - NULL, /* ^graph */ - NULL, /* ^print */ - NULL, /* ^punct */ - (uschar *)"\\P{Xps}", /* ^space */ /* NOTE: Xps is POSIX space */ - (uschar *)"\\P{Xwd}", /* ^word */ - NULL /* ^xdigit */ + string_PL, /* ^alpha */ + string_PLl, /* ^lower */ + string_PLu, /* ^upper */ + string_PXan, /* ^alnum */ + NULL, /* ^ascii */ + string_H, /* ^blank */ + NULL, /* ^cntrl */ + string_PNd, /* ^digit */ + NULL, /* ^graph */ + NULL, /* ^print */ + NULL, /* ^punct */ + string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */ + string_PXwd, /* ^word */ + NULL /* ^xdigit */ }; -#define POSIX_SUBSIZE (sizeof(posix_substitutes)/sizeof(uschar *)) +#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *)) #endif #define STRING(a) # a @@ -363,7 +436,7 @@ static const char error_texts[] = /* 30 */ "unknown POSIX class name\0" "POSIX collating elements are not supported\0" - "this version of PCRE is not compiled with PCRE_UTF8 support\0" + "this version of PCRE is compiled without UTF support\0" "spare error\0" /** DEAD **/ "character value in \\x{...} sequence is too large\0" /* 35 */ @@ -386,12 +459,12 @@ static const char error_texts[] = "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" /* 50 */ "repeated subpattern is too long\0" /** DEAD **/ - "octal value is greater than \\377 (not in UTF-8 mode)\0" + "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" "internal error: overran compiling workspace\0" "internal error: previously-checked referenced subpattern not found\0" "DEFINE group contains more than one branch\0" /* 55 */ - "repeating a DEFINE group is not allowed\0" + "repeating a DEFINE group is not allowed\0" /** DEAD **/ "inconsistent NEWLINE options\0" "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" "a numbered reference must not be zero\0" @@ -405,8 +478,18 @@ static const char error_texts[] = /* 65 */ "different names for subpatterns of the same number are not allowed\0" "(*MARK) must have an argument\0" - "this version of PCRE is not compiled with PCRE_UCP support\0" + "this version of PCRE is not compiled with Unicode property support\0" "\\c must be followed by an ASCII character\0" + "\\k is not followed by a braced, angle-bracketed, or quoted name\0" + /* 70 */ + "internal error: unknown opcode in find_fixedlength()\0" + "\\N is not supported in a class\0" + "too many forward references\0" + "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0" + "invalid UTF-16 string\0" + /* 75 */ + "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" + "character value in \\u.... sequence is too large\0" ; /* Table to identify digits and hex digits. This is used when compiling @@ -425,12 +508,18 @@ For convenience, we use the same bit definitions as in chartables: Then we can use ctype_digit and ctype_xdigit in the code. */ +/* Using a simple comparison for decimal numbers rather than a memory read +is much faster, and the resulting code is simpler (the compiler turns it +into a subtraction and unsigned comparison). */ + +#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9) + #ifndef EBCDIC /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in UTF-8 mode. */ -static const unsigned char digitab[] = +static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ @@ -469,7 +558,7 @@ static const unsigned char digitab[] = /* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ -static const unsigned char digitab[] = +static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ @@ -504,7 +593,7 @@ static const unsigned char digitab[] = 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ -static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ +static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ @@ -543,7 +632,7 @@ static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ /* Definition to allow mutual recursion */ static BOOL - compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int, + compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, int *, int *, branch_chain *, compile_data *, int *); @@ -574,6 +663,78 @@ return s; } +/************************************************* +* Expand the workspace * +*************************************************/ + +/* This function is called during the second compiling phase, if the number of +forward references fills the existing workspace, which is originally a block on +the stack. A larger block is obtained from malloc() unless the ultimate limit +has been reached or the increase will be rather small. + +Argument: pointer to the compile data block +Returns: 0 if all went well, else an error number +*/ + +static int +expand_workspace(compile_data *cd) +{ +pcre_uchar *newspace; +int newsize = cd->workspace_size * 2; + +if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX; +if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX || + newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN) + return ERR72; + +newspace = (PUBL(malloc))(IN_UCHARS(newsize)); +if (newspace == NULL) return ERR21; +memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar)); +cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace); +if (cd->workspace_size > COMPILE_WORK_SIZE) + (PUBL(free))((void *)cd->start_workspace); +cd->start_workspace = newspace; +cd->workspace_size = newsize; +return 0; +} + + + +/************************************************* +* Check for counted repeat * +*************************************************/ + +/* This function is called when a '{' is encountered in a place where it might +start a quantifier. It looks ahead to see if it really is a quantifier or not. +It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} +where the ddds are digits. + +Arguments: + p pointer to the first char after '{' + +Returns: TRUE or FALSE +*/ + +static BOOL +is_counted_repeat(const pcre_uchar *p) +{ +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (*p++ != CHAR_COMMA) return FALSE; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; + +return (*p == CHAR_RIGHT_CURLY_BRACKET); +} + + + /************************************************* * Handle escapes * *************************************************/ @@ -599,12 +760,14 @@ Returns: zero or positive => a data character */ static int -check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount, +check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount, int options, BOOL isclass) { -BOOL utf8 = (options & PCRE_UTF8) != 0; -const uschar *ptr = *ptrptr + 1; -int c, i; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +const pcre_uchar *ptr = *ptrptr + 1; +pcre_int32 c; +int i; GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ ptr--; /* Set pointer back to the last byte */ @@ -618,11 +781,13 @@ in a table. A non-zero result is something that can be returned immediately. Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ -else if (c < CHAR_0 || c > CHAR_z) {} /* Not alphanumeric */ +/* Not alphanumeric */ +else if (c < CHAR_0 || c > CHAR_z) {} else if ((i = escapes[c - CHAR_0]) != 0) c = i; #else /* EBCDIC coding */ -else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphanumeric */ +/* Not alphanumeric */ +else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} else if ((i = escapes[c - 0x48]) != 0) c = i; #endif @@ -630,7 +795,7 @@ else if ((i = escapes[c - 0x48]) != 0) c = i; else { - const uschar *oldptr; + const pcre_uchar *oldptr; BOOL braced, negated; switch (c) @@ -640,12 +805,56 @@ else case CHAR_l: case CHAR_L: - case CHAR_u: - case CHAR_U: *errorcodeptr = ERR37; break; - /* \g must be followed by one of a number of specific things: + case CHAR_u: + if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + /* In JavaScript, \u must be followed by four hexadecimal numbers. + Otherwise it is a lowercase u letter. */ + if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 + && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0 + && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0 + && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0) + { + c = 0; + for (i = 0; i < 4; ++i) + { + register int cc = *(++ptr); +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#else /* EBCDIC coding */ + if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); +#endif + } + +#ifdef COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) +#else +#ifdef COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) +#endif +#endif + { + *errorcodeptr = ERR76; + } + else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + } + else + *errorcodeptr = ERR37; + break; + + case CHAR_U: + /* In JavaScript, \U is an uppercase U letter. */ + if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37; + break; + + /* In a character class, \g is just a literal "g". Outside a character + class, \g must be followed by one of a number of specific things: (1) A number, either plain or braced. If positive, it is an absolute backreference. If negative, it is a relative backreference. This is a Perl @@ -662,6 +871,7 @@ else the -ESC_g code (cf \k). */ case CHAR_g: + if (isclass) break; if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) { c = -ESC_g; @@ -672,9 +882,9 @@ else if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { - const uschar *p; + const pcre_uchar *p; for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++) - if (*p != CHAR_MINUS && (digitab[*p] & ctype_digit) == 0) break; + if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET) { c = -ESC_k; @@ -692,12 +902,21 @@ else } else negated = FALSE; + /* The integer range is limited by the machine's int representation. */ c = 0; - while ((digitab[ptr[1]] & ctype_digit) != 0) - c = c * 10 + *(++ptr) - CHAR_0; - - if (c < 0) /* Integer overflow */ + while (IS_DIGIT(ptr[1])) { + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ + { + c = -1; + break; + } + c = c * 10 + *(++ptr) - CHAR_0; + } + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) + ptr++; *errorcodeptr = ERR61; break; } @@ -745,11 +964,21 @@ else if (!isclass) { oldptr = ptr; + /* The integer range is limited by the machine's int representation. */ c -= CHAR_0; - while ((digitab[ptr[1]] & ctype_digit) != 0) - c = c * 10 + *(++ptr) - CHAR_0; - if (c < 0) /* Integer overflow */ + while (IS_DIGIT(ptr[1])) { + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ + { + c = -1; + break; + } + c = c * 10 + *(++ptr) - CHAR_0; + } + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ + { + while (IS_DIGIT(ptr[1])) + ptr++; *errorcodeptr = ERR61; break; } @@ -775,32 +1004,55 @@ else /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least significant 8 bits of octal numbers (I think this is what early Perls used - to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more - than 3 octal digits. */ + to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, + but no more than 3 octal digits. */ case CHAR_0: c -= CHAR_0; while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) c = c * 8 + *(++ptr) - CHAR_0; - if (!utf8 && c > 255) *errorcodeptr = ERR51; +#ifdef COMPILE_PCRE8 + if (!utf && c > 0xff) *errorcodeptr = ERR51; +#endif break; /* \x is complicated. \x{ddd} is a character number which can be greater - than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is - treated as a data character. */ + than 0xff in utf or non-8bit mode, but only if the ddd are hex digits. + If not, { is treated as a data character. */ case CHAR_x: + if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + /* In JavaScript, \x must be followed by two hexadecimal numbers. + Otherwise it is a lowercase x letter. */ + if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 + && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0) + { + c = 0; + for (i = 0; i < 2; ++i) + { + register int cc = *(++ptr); +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#else /* EBCDIC coding */ + if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); +#endif + } + } + break; + } + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { - const uschar *pt = ptr + 2; - int count = 0; + const pcre_uchar *pt = ptr + 2; c = 0; - while ((digitab[*pt] & ctype_xdigit) != 0) + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) { register int cc = *pt++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ - count++; #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ @@ -809,11 +1061,25 @@ else if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif + +#ifdef COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; } +#else +#ifdef COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; } +#endif +#endif + } + + if (c < 0) + { + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; + *errorcodeptr = ERR34; } if (*pt == CHAR_RIGHT_CURLY_BRACKET) { - if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34; + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; ptr = pt; break; } @@ -825,7 +1091,7 @@ else /* Read just a single-byte hex-defined char */ c = 0; - while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0) + while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) { int cc; /* Some compilers don't like */ cc = *(++ptr); /* ++ in initializers */ @@ -883,9 +1149,11 @@ else } /* Perl supports \N{name} for character names, as well as plain \N for "not -newline". PCRE does not support \N{name}. */ +newline". PCRE does not support \N{name}. However, it does support +quantification such as \N{2,3}. */ -if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET) +if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && + !is_counted_repeat(ptr+2)) *errorcodeptr = ERR37; /* If PCRE_UCP is set, we change the values for \d etc. */ @@ -921,11 +1189,11 @@ Returns: type value from ucp_type_table, or -1 for an invalid type */ static int -get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) +get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) { int c, i, bot, top; -const uschar *ptr = *ptrptr; -char name[32]; +const pcre_uchar *ptr = *ptrptr; +pcre_uchar name[32]; c = *(++ptr); if (c == 0) goto ERROR_RETURN; @@ -942,7 +1210,7 @@ if (c == CHAR_LEFT_CURLY_BRACKET) *negptr = TRUE; ptr++; } - for (i = 0; i < (int)sizeof(name) - 1; i++) + for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++) { c = *(++ptr); if (c == 0) goto ERROR_RETURN; @@ -966,16 +1234,16 @@ else /* Search for a recognized property name using binary chop */ bot = 0; -top = _pcre_utt_size; +top = PRIV(utt_size); while (bot < top) { i = (bot + top) >> 1; - c = strcmp(name, _pcre_utt_names + _pcre_utt[i].name_offset); + c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); if (c == 0) { - *dptr = _pcre_utt[i].value; - return _pcre_utt[i].type; + *dptr = PRIV(utt)[i].value; + return PRIV(utt)[i].type; } if (c > 0) bot = i + 1; else top = i; } @@ -994,39 +1262,6 @@ return -1; -/************************************************* -* Check for counted repeat * -*************************************************/ - -/* This function is called when a '{' is encountered in a place where it might -start a quantifier. It looks ahead to see if it really is a quantifier or not. -It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} -where the ddds are digits. - -Arguments: - p pointer to the first char after '{' - -Returns: TRUE or FALSE -*/ - -static BOOL -is_counted_repeat(const uschar *p) -{ -if ((digitab[*p++] & ctype_digit) == 0) return FALSE; -while ((digitab[*p] & ctype_digit) != 0) p++; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if (*p++ != CHAR_COMMA) return FALSE; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if ((digitab[*p++] & ctype_digit) == 0) return FALSE; -while ((digitab[*p] & ctype_digit) != 0) p++; - -return (*p == CHAR_RIGHT_CURLY_BRACKET); -} - - - /************************************************* * Read repeat counts * *************************************************/ @@ -1046,8 +1281,8 @@ Returns: pointer to '}' on success; current ptr on error, with errorcodeptr set non-zero */ -static const uschar * -read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr) +static const pcre_uchar * +read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr) { int min = 0; int max = -1; @@ -1055,7 +1290,7 @@ int max = -1; /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ -while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - CHAR_0; +while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0; if (min < 0 || min > 65535) { *errorcodeptr = ERR5; @@ -1070,7 +1305,7 @@ if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) { max = 0; - while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - CHAR_0; + while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0; if (max < 0 || max > 65535) { *errorcodeptr = ERR5; @@ -1125,17 +1360,17 @@ Arguments: name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf8 TRUE if we are in UTF-8 mode + utf TRUE if we are in UTF-8 / UTF-16 mode count pointer to the current capturing subpattern number (updated) Returns: the number of the named subpattern, or -1 if not found */ static int -find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn, - BOOL xmode, BOOL utf8, int *count) +find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn, + BOOL xmode, BOOL utf, int *count) { -uschar *ptr = *ptrptr; +pcre_uchar *ptr = *ptrptr; int start_count = *count; int hwm_count = start_count; BOOL dup_parens = FALSE; @@ -1202,7 +1437,7 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) { int term; - const uschar *thisname; + const pcre_uchar *thisname; *count += 1; if (name == NULL && *count == lorn) return *count; term = *ptr++; @@ -1210,7 +1445,7 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) thisname = ptr; while (*ptr != term) ptr++; if (name != NULL && lorn == ptr - thisname && - strncmp((const char *)name, (const char *)thisname, lorn) == 0) + STRNCMP_UC_UC(name, thisname, lorn) == 0) return *count; term++; } @@ -1253,7 +1488,7 @@ for (; ptr < cd->end_pattern; ptr++) { if (ptr[2] == CHAR_E) ptr+= 2; - else if (strncmp((const char *)ptr+2, + else if (STRNCMP_UC_C8(ptr + 2, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 4; else @@ -1301,8 +1536,8 @@ for (; ptr < cd->end_pattern; ptr++) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } if (*ptr == 0) goto FAIL_EXIT; @@ -1313,7 +1548,7 @@ for (; ptr < cd->end_pattern; ptr++) if (*ptr == CHAR_LEFT_PARENTHESIS) { - int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, count); + int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); if (rc > 0) return rc; if (*ptr == 0) goto FAIL_EXIT; } @@ -1359,16 +1594,16 @@ Arguments: name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf8 TRUE if we are in UTF-8 mode + utf TRUE if we are in UTF-8 / UTF-16 mode Returns: the number of the found subpattern, or -1 if not found */ static int -find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode, - BOOL utf8) +find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, + BOOL utf) { -uschar *ptr = (uschar *)cd->start_pattern; +pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern; int count = 0; int rc; @@ -1379,7 +1614,7 @@ matching closing parens. That is why we have to have a loop. */ for (;;) { - rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, &count); + rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); if (rc > 0 || *ptr++ == 0) break; } @@ -1395,40 +1630,30 @@ return rc; /* This is called by several functions that scan a compiled expression looking for a fixed first character, or an anchoring op code etc. It skips over things -that do not influence this. For some calls, a change of option is important. -For some calls, it makes sense to skip negative forward and all backward -assertions, and also the \b assertion; for others it does not. +that do not influence this. For some calls, it makes sense to skip negative +forward and all backward assertions, and also the \b assertion; for others it +does not. Arguments: code pointer to the start of the group - options pointer to external options - optbit the option bit whose changing is significant, or - zero if none are skipassert TRUE if certain assertions are to be skipped Returns: pointer to the first significant opcode */ -static const uschar* -first_significant_code(const uschar *code, int *options, int optbit, - BOOL skipassert) +static const pcre_uchar* +first_significant_code(const pcre_uchar *code, BOOL skipassert) { for (;;) { switch ((int)*code) { - case OP_OPT: - if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit)) - *options = (int)code[1]; - code += 2; - break; - case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); - code += _pcre_OP_lengths[*code]; + code += PRIV(OP_lengths)[*code]; break; case OP_WORD_BOUNDARY: @@ -1442,7 +1667,7 @@ for (;;) case OP_RREF: case OP_NRREF: case OP_DEF: - code += _pcre_OP_lengths[*code]; + code += PRIV(OP_lengths)[*code]; break; default: @@ -1472,23 +1697,24 @@ and doing the check at the end; a flag specifies which mode we are running in. Arguments: code points to the start of the pattern (the bracket) - options the compiling options + utf TRUE in UTF-8 / UTF-16 mode atend TRUE if called when the pattern is complete cd the "compile data" structure Returns: the fixed length, or -1 if there is no fixed length, - or -2 if \C was encountered + or -2 if \C was encountered (in UTF-8 mode only) or -3 if an OP_RECURSE item was encountered and atend is FALSE + or -4 if an unknown opcode was encountered (internal error) */ static int -find_fixedlength(uschar *code, int options, BOOL atend, compile_data *cd) +find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd) { int length = -1; register int branchlength = 0; -register uschar *cc = code + 1 + LINK_SIZE; +register pcre_uchar *cc = code + 1 + LINK_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ @@ -1496,30 +1722,39 @@ branch, check the length against that of the other branches. */ for (;;) { int d; - uschar *ce, *cs; + pcre_uchar *ce, *cs; register int op = *cc; + switch (op) { + /* We only need to continue for OP_CBRA (normal capturing bracket) and + OP_BRA (normal non-capturing bracket) because the other variants of these + opcodes are all concerned with unlimited repeated groups, which of course + are not of fixed length. */ + case OP_CBRA: case OP_BRA: case OP_ONCE: + case OP_ONCE_NC: case OP_COND: - d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options, atend, cd); + d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; - /* Reached end of a branch; if it's a ket it is the end of a nested - call. If it's ALT it is an alternation in a nested call. If it is - END it's the end of the outer call. All can be handled by the same code. */ + /* Reached end of a branch; if it's a ket it is the end of a nested call. + If it's ALT it is an alternation in a nested call. An ACCEPT is effectively + an ALT. If it is END it's the end of the outer call. All can be handled by + the same code. Note that we must not include the OP_KETRxxx opcodes here, + because they all imply an unlimited repeat. */ case OP_ALT: case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: case OP_END: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: if (length < 0) length = branchlength; else if (length != branchlength) return -1; if (*cc != OP_ALT) return length; @@ -1533,10 +1768,10 @@ for (;;) case OP_RECURSE: if (!atend) return -3; - cs = ce = (uschar *)cd->start_code + GET(cc, 1); /* Start subpattern */ - do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ - if (cc > cs && cc < ce) return -1; /* Recursion */ - d = find_fixedlength(cs + 2, options, atend, cd); + cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */ + do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ + if (cc > cs && cc < ce) return -1; /* Recursion */ + d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd); if (d < 0) return d; branchlength += d; cc += 1 + LINK_SIZE; @@ -1549,40 +1784,55 @@ for (;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); - /* Fall through */ + cc += PRIV(OP_lengths)[*cc]; + break; /* Skip over things that don't match chars */ - case OP_REVERSE: - case OP_CREF: - case OP_NCREF: - case OP_RREF: - case OP_NRREF: - case OP_DEF: - case OP_OPT: + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += cc[1] + PRIV(OP_lengths)[*cc]; + break; + case OP_CALLOUT: - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: + case OP_CREF: + case OP_DEF: + case OP_DOLL: + case OP_DOLLM: case OP_EOD: case OP_EODN: - case OP_CIRC: - case OP_DOLL: + case OP_FAIL: + case OP_NCREF: + case OP_NRREF: case OP_NOT_WORD_BOUNDARY: + case OP_PRUNE: + case OP_REVERSE: + case OP_RREF: + case OP_SET_SOM: + case OP_SKIP: + case OP_SOD: + case OP_SOM: + case OP_THEN: case OP_WORD_BOUNDARY: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; break; /* Handle literal characters */ case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: branchlength++; cc += 2; -#ifdef SUPPORT_UTF8 - if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0) - cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -1590,18 +1840,20 @@ for (;;) need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: branchlength += GET2(cc,1); - cc += 4; -#ifdef SUPPORT_UTF8 - if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0) - cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); - if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2; - cc += 4; + if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; + cc += 1 + IMM2_SIZE + 1; break; /* Handle single-char matchers */ @@ -1611,6 +1863,10 @@ for (;;) cc += 2; /* Fall through */ + case OP_HSPACE: + case OP_VSPACE: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: @@ -1623,25 +1879,28 @@ for (;;) cc++; break; - /* The single-byte matcher isn't allowed */ + /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; + otherwise \C is coded as OP_ALLANY. */ case OP_ANYBYTE: return -2; /* Check a class for variable quantification */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: - cc += GET(cc, 1) - 33; + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: - cc += 33; + cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { + case OP_CRPLUS: + case OP_CRMINPLUS: case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: @@ -1650,9 +1909,9 @@ for (;;) case OP_CRRANGE: case OP_CRMINRANGE: - if (GET2(cc,1) != GET2(cc,3)) return -1; + if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; branchlength += GET2(cc,1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -1662,8 +1921,91 @@ for (;;) /* Anything else is variable length */ - default: + case OP_ANYNL: + case OP_BRAMINZERO: + case OP_BRAPOS: + case OP_BRAPOSZERO: + case OP_BRAZERO: + case OP_CBRAPOS: + case OP_EXTUNI: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_PLUS: + case OP_PLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_QUERY: + case OP_QUERYI: + case OP_REF: + case OP_REFI: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + case OP_SCOND: + case OP_SKIPZERO: + case OP_STAR: + case OP_STARI: + case OP_TYPEMINPLUS: + case OP_TYPEMINQUERY: + case OP_TYPEMINSTAR: + case OP_TYPEMINUPTO: + case OP_TYPEPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSUPTO: + case OP_TYPEQUERY: + case OP_TYPESTAR: + case OP_TYPEUPTO: + case OP_UPTO: + case OP_UPTOI: return -1; + + /* Catch unrecognized opcodes so that when new ones are added they + are not forgotten, as has happened in the past. */ + + default: + return -4; } } /* Control never gets here */ @@ -1684,18 +2026,19 @@ length. Arguments: code points to start of expression - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode number the required bracket number or negative to find a lookbehind Returns: pointer to the opcode for the bracket, or NULL if not found */ -const uschar * -_pcre_find_bracket(const uschar *code, BOOL utf8, int number) +const pcre_uchar * +PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number) { for (;;) { register int c = *code; + if (c == OP_END) return NULL; /* XCLASS is used for classes that cannot be represented just by a bit @@ -1708,17 +2051,18 @@ for (;;) else if (c == OP_REVERSE) { - if (number < 0) return (uschar *)code; - code += _pcre_OP_lengths[c]; + if (number < 0) return (pcre_uchar *)code; + code += PRIV(OP_lengths)[c]; } /* Handle capturing bracket */ - else if (c == OP_CBRA) + else if (c == OP_CBRA || c == OP_SCBRA || + c == OP_CBRAPOS || c == OP_SCBRAPOS) { int n = GET2(code, 1+LINK_SIZE); - if (n == number) return (uschar *)code; - code += _pcre_OP_lengths[c]; + if (n == number) return (pcre_uchar *)code; + code += PRIV(OP_lengths)[c]; } /* Otherwise, we can get the item's length from the table, except that for @@ -1746,7 +2090,8 @@ for (;;) case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -1756,41 +2101,54 @@ for (;;) break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } /* Add in the fixed length from the table */ - code += _pcre_OP_lengths[c]; + code += PRIV(OP_lengths)[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(c) +#ifdef SUPPORT_UTF + if (utf) switch(c) { case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_EXACT: + case OP_EXACTI: case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_POSQUERY: - if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; + case OP_POSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else - (void)(utf8); /* Keep compiler happy by referencing function argument */ + (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } @@ -1807,13 +2165,13 @@ instance of OP_RECURSE. Arguments: code points to start of expression - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ -static const uschar * -find_recurse(const uschar *code, BOOL utf8) +static const pcre_uchar * +find_recurse(const pcre_uchar *code, BOOL utf) { for (;;) { @@ -1852,7 +2210,8 @@ for (;;) case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -1862,41 +2221,82 @@ for (;;) break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } /* Add in the fixed length from the table */ - code += _pcre_OP_lengths[c]; + code += PRIV(OP_lengths)[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(c) +#ifdef SUPPORT_UTF + if (utf) switch(c) { case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: case OP_PLUS: + case OP_PLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_MINPLUS: + case OP_MINPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: case OP_POSQUERY: - if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else - (void)(utf8); /* Keep compiler happy by referencing function argument */ + (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } @@ -1919,22 +2319,22 @@ bracket whose current branch will already have been scanned. Arguments: code points to start of search endcode points to where to stop - utf8 TRUE if in UTF8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd contains pointers to tables etc. Returns: TRUE if what is matched could be empty */ static BOOL -could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8, - compile_data *cd) +could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, + BOOL utf, compile_data *cd) { register int c; -for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE); +for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); code < endcode; - code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE)) + code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) { - const uschar *ccode; + const pcre_uchar *ccode; c = *code; @@ -1948,27 +2348,34 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE continue; } - /* Groups with zero repeats can of course be empty; skip them. */ - - if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO) - { - code += _pcre_OP_lengths[c]; - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - continue; - } - /* For a recursion/subroutine call, if its end has been reached, which - implies a subroutine call, we can scan it. */ + implies a backward reference subroutine call, we can scan it. If it's a + forward reference subroutine call, we can't. To detect forward reference + we have to scan up the list that is kept in the workspace. This function is + called only when doing the real compile, not during the pre-compile that + measures the size of the compiled pattern. */ if (c == OP_RECURSE) { - BOOL empty_branch = FALSE; - const uschar *scode = cd->start_code + GET(code, 1); + const pcre_uchar *scode; + BOOL empty_branch; + + /* Test for forward reference */ + + for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) + if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE; + + /* Not a forward reference, test for completed backward reference */ + + empty_branch = FALSE; + scode = cd->start_code + GET(code, 1); if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ + + /* Completed backwards reference */ + do { - if (could_be_empty_branch(scode, endcode, utf8, cd)) + if (could_be_empty_branch(scode, endcode, utf, cd)) { empty_branch = TRUE; break; @@ -1976,13 +2383,39 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE scode += GET(scode, 1); } while (*scode == OP_ALT); + if (!empty_branch) return FALSE; /* All branches are non-empty */ continue; } + /* Groups with zero repeats can of course be empty; skip them. */ + + if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO || + c == OP_BRAPOSZERO) + { + code += PRIV(OP_lengths)[c]; + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + + /* A nested group that is already marked as "could be empty" can just be + skipped. */ + + if (c == OP_SBRA || c == OP_SBRAPOS || + c == OP_SCBRA || c == OP_SCBRAPOS) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + /* For other groups, scan the branches. */ - if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND) + if (c == OP_BRA || c == OP_BRAPOS || + c == OP_CBRA || c == OP_CBRAPOS || + c == OP_ONCE || c == OP_ONCE_NC || + c == OP_COND) { BOOL empty_branch; if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ @@ -1998,7 +2431,7 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE empty_branch = FALSE; do { - if (!empty_branch && could_be_empty_branch(code, endcode, utf8, cd)) + if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd)) empty_branch = TRUE; code += GET(code, 1); } @@ -2016,11 +2449,11 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE { /* Check for quantifiers after a class. XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single - high-valued characters. The length in _pcre_OP_lengths[] is zero; the + high-valued characters. The length in PRIV(OP_lengths)[] is zero; the actual length is stored in the compiled code, so we must update "code" here. */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: ccode = code += GET(code, 1); goto CHECK_CLASS_REPEAT; @@ -2028,9 +2461,9 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE case OP_CLASS: case OP_NCLASS: - ccode = code + 33; + ccode = code + PRIV(OP_lengths)[OP_CLASS]; -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 CHECK_CLASS_REPEAT: #endif @@ -2069,8 +2502,9 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE case OP_ALLANY: case OP_ANYBYTE: case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2102,7 +2536,8 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; /* End of branch */ @@ -2110,26 +2545,36 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: case OP_ALT: return TRUE; /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, MINUPTO, and POSUPTO may be followed by a multibyte character */ -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_POSQUERY: - if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f]; + case OP_POSQUERYI: + if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); break; case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_POSUPTO: - if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f]; + case OP_POSUPTOI: + if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); break; #endif @@ -2143,7 +2588,7 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; /* None of the remaining opcodes are required to match a character. */ @@ -2166,24 +2611,26 @@ return TRUE; the current branch of the current pattern to see if it could match the empty string. If it could, we must look outwards for branches at other levels, stopping when we pass beyond the bracket which is the subject of the recursion. +This function is called only during the real compile, not during the +pre-compile. Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts - utf8 TRUE if in UTF-8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd pointers to tables etc Returns: TRUE if what is matched could be empty */ static BOOL -could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr, - BOOL utf8, compile_data *cd) +could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode, + branch_chain *bcptr, BOOL utf, compile_data *cd) { while (bcptr != NULL && bcptr->current_branch >= code) { - if (!could_be_empty_branch(bcptr->current_branch, endcode, utf8, cd)) + if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd)) return FALSE; bcptr = bcptr->outer; } @@ -2216,6 +2663,17 @@ 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, I think. +A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. +It seems that the appearance of a nested POSIX class supersedes an apparent +external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or +a digit. + +In Perl, unescaped square brackets may also appear as part of class names. For +example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for +[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not +seem right at all. PCRE does not allow closing square brackets in POSIX class +names. + Arguments: ptr pointer to the initial [ endptr where to return the end pointer @@ -2224,20 +2682,27 @@ Returns: TRUE or FALSE */ static BOOL -check_posix_syntax(const uschar *ptr, const uschar **endptr) +check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr) { int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ for (++ptr; *ptr != 0; ptr++) { - if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; else + if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + ptr++; + else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; + else { - if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { *endptr = ptr; return TRUE; } + if (*ptr == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, endptr)) + return FALSE; } } return FALSE; @@ -2261,14 +2726,14 @@ Returns: a value representing the name, or -1 if unknown */ static int -check_posix_name(const uschar *ptr, int len) +check_posix_name(const pcre_uchar *ptr, int len) { const char *pn = posix_names; register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && - strncmp((const char *)ptr, pn, len) == 0) return yield; + STRNCMP_UC_C8(ptr, pn, len) == 0) return yield; pn += posix_name_lengths[yield] + 1; yield++; } @@ -2300,7 +2765,7 @@ value in the reference (which is a group number). Arguments: group points to the start of the group adjust the amount by which the group is to be moved - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode cd contains pointers to tables etc. save_hwm the hwm forward reference pointer at the start of the group @@ -2308,15 +2773,15 @@ Returns: nothing */ static void -adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd, - uschar *save_hwm) +adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd, + pcre_uchar *save_hwm) { -uschar *ptr = group; +pcre_uchar *ptr = group; -while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL) +while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) { int offset; - uschar *hc; + pcre_uchar *hc; /* See if this recursion is on the forward reference list. If so, adjust the reference. */ @@ -2361,14 +2826,14 @@ Arguments: Returns: new code pointer */ -static uschar * -auto_callout(uschar *code, const uschar *ptr, compile_data *cd) +static pcre_uchar * +auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd) { *code++ = OP_CALLOUT; *code++ = 255; PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ -return code + 2*LINK_SIZE; +return code + 2 * LINK_SIZE; } @@ -2390,7 +2855,7 @@ Returns: nothing */ static void -complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd) +complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd) { int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2)); PUT(previous_callout, 2 + LINK_SIZE, length); @@ -2473,7 +2938,7 @@ switch(ptype) prop->chartype == ucp_Lt) == negated; case PT_GC: - return (pdata == _pcre_ucp_gentype[prop->chartype]) == negated; + return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; case PT_PC: return (pdata == prop->chartype) == negated; @@ -2484,23 +2949,23 @@ switch(ptype) /* These are specials */ case PT_ALNUM: - return (_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == negated; + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; case PT_SPACE: /* Perl space */ - return (_pcre_ucp_gentype[prop->chartype] == ucp_Z || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == negated; case PT_PXSPACE: /* POSIX space */ - return (_pcre_ucp_gentype[prop->chartype] == ucp_Z || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == negated; case PT_WORD: - return (_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == negated; } return FALSE; @@ -2519,7 +2984,7 @@ sense to automatically possessify the repeated item. Arguments: previous pointer to the repeated opcode - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode ptr next character in pattern options options bits cd contains pointers to tables etc. @@ -2528,10 +2993,10 @@ Returns: TRUE if possessifying is wanted */ static BOOL -check_auto_possessive(const uschar *previous, BOOL utf8, const uschar *ptr, - int options, compile_data *cd) +check_auto_possessive(const pcre_uchar *previous, BOOL utf, + const pcre_uchar *ptr, int options, compile_data *cd) { -int c, next; +pcre_int32 c, next; int op_code = *previous++; /* Skip whitespace and comments in extended mode */ @@ -2540,7 +3005,7 @@ if ((options & PCRE_EXTENDED) != 0) { for (;;) { - while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; @@ -2548,8 +3013,8 @@ if ((options & PCRE_EXTENDED) != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } } @@ -2567,15 +3032,13 @@ if (*ptr == CHAR_BACKSLASH) if (temperrorcode != 0) return FALSE; ptr++; /* Point after the escape sequence */ } - -else if ((cd->ctypes[*ptr] & ctype_meta) == 0) +else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) { -#ifdef SUPPORT_UTF8 - if (utf8) { GETCHARINC(next, ptr); } else +#ifdef SUPPORT_UTF + if (utf) { GETCHARINC(next, ptr); } else #endif next = *ptr++; } - else return FALSE; /* Skip whitespace and comments in extended mode */ @@ -2584,7 +3047,7 @@ if ((options & PCRE_EXTENDED) != 0) { for (;;) { - while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; @@ -2592,8 +3055,8 @@ if ((options & PCRE_EXTENDED) != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } } @@ -2604,7 +3067,7 @@ if ((options & PCRE_EXTENDED) != 0) /* If the next thing is itself optional, we have to give up. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Now compare the next item with the previous opcode. First, handle cases when @@ -2613,26 +3076,26 @@ the next item is a character. */ if (next >= 0) switch(op_code) { case OP_CHAR: -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif return c != next; - /* For CHARNC (caseless character) we must check the other case. If we have + /* For CHARI (caseless character) we must check the other case. If we have Unicode property support, we can use it to test the other case of high-valued characters. */ - case OP_CHARNC: -#ifdef SUPPORT_UTF8 + case OP_CHARI: +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif if (c == next) return FALSE; -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else @@ -2644,50 +3107,60 @@ if (next >= 0) switch(op_code) return (unsigned int)c != othercase; } else -#endif /* SUPPORT_UTF8 */ - return (c != cd->fcc[next]); /* Non-UTF-8 mode */ - - /* For OP_NOT, its data is always a single-byte character. */ +#endif /* SUPPORT_UTF */ + return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ case OP_NOT: - if ((c = *previous) == next) return TRUE; - if ((options & PCRE_CASELESS) == 0) return FALSE; -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + return c == next; + + case OP_NOTI: +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + if (c == next) return TRUE; +#ifdef SUPPORT_UTF + if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); + othercase = UCD_OTHERCASE((unsigned int)next); #else othercase = NOTACHAR; #endif return (unsigned int)c == othercase; } else -#endif /* SUPPORT_UTF8 */ - return (c == cd->fcc[next]); /* Non-UTF-8 mode */ +#endif /* SUPPORT_UTF */ + return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ case OP_DIGIT: - return next > 127 || (cd->ctypes[next] & ctype_digit) == 0; + return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; case OP_NOT_DIGIT: - return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; case OP_WHITESPACE: - return next > 127 || (cd->ctypes[next] & ctype_space) == 0; + return next > 255 || (cd->ctypes[next] & ctype_space) == 0; case OP_NOT_WHITESPACE: - return next <= 127 && (cd->ctypes[next] & ctype_space) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; case OP_WORDCHAR: - return next > 127 || (cd->ctypes[next] & ctype_word) == 0; + return next > 255 || (cd->ctypes[next] & ctype_word) == 0; case OP_NOT_WORDCHAR: - return next <= 127 && (cd->ctypes[next] & ctype_word) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; case OP_HSPACE: case OP_NOT_HSPACE: @@ -2756,8 +3229,8 @@ replaced by OP_PROP codes when PCRE_UCP is set. */ switch(op_code) { case OP_CHAR: - case OP_CHARNC: -#ifdef SUPPORT_UTF8 + case OP_CHARI: +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; @@ -2765,22 +3238,22 @@ switch(op_code) switch(-next) { case ESC_d: - return c > 127 || (cd->ctypes[c] & ctype_digit) == 0; + return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; case ESC_D: - return c <= 127 && (cd->ctypes[c] & ctype_digit) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0; case ESC_s: - return c > 127 || (cd->ctypes[c] & ctype_space) == 0; + return c > 255 || (cd->ctypes[c] & ctype_space) == 0; case ESC_S: - return c <= 127 && (cd->ctypes[c] & ctype_space) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_space) != 0; case ESC_w: - return c > 127 || (cd->ctypes[c] & ctype_word) == 0; + return c > 255 || (cd->ctypes[c] & ctype_word) == 0; case ESC_W: - return c <= 127 && (cd->ctypes[c] & ctype_word) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_word) != 0; case ESC_h: case ESC_H: @@ -2862,7 +3335,7 @@ switch(op_code) to the original \d etc. At this point, ptr will point to a zero byte. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Do the property check. */ @@ -2889,10 +3362,10 @@ switch(op_code) return next == -ESC_d; case OP_WHITESPACE: - return next == -ESC_S || next == -ESC_d || next == -ESC_w || next == -ESC_R; + return next == -ESC_S || next == -ESC_d || next == -ESC_w; case OP_NOT_WHITESPACE: - return next == -ESC_s || next == -ESC_h || next == -ESC_v; + return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_HSPACE: return next == -ESC_S || next == -ESC_H || next == -ESC_d || @@ -2940,9 +3413,10 @@ Arguments: codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorcodeptr points to error code variable - firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) - reqbyteptr set to the last literal character required, else < 0 + firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) + reqcharptr set to the last literal character required, else < 0 bcptr points to current branch chain + cond_depth conditional nesting depth cd contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase @@ -2952,44 +3426,54 @@ Returns: TRUE on success */ static BOOL -compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr, - int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, +compile_branch(int *optionsptr, pcre_uchar **codeptr, + const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr, + pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; -int firstbyte, reqbyte; -int zeroreqbyte, zerofirstbyte; -int req_caseopt, reqvary, tempreqvary; -int options = *optionsptr; +pcre_int32 firstchar, reqchar; +pcre_int32 zeroreqchar, zerofirstchar; +pcre_int32 req_caseopt, reqvary, tempreqvary; +int options = *optionsptr; /* May change dynamically */ int after_manual_callout = 0; int length_prevgroup = 0; register int c; -register uschar *code = *codeptr; -uschar *last_code = code; -uschar *orig_code = code; -uschar *tempcode; +register pcre_uchar *code = *codeptr; +pcre_uchar *last_code = code; +pcre_uchar *orig_code = code; +pcre_uchar *tempcode; BOOL inescq = FALSE; -BOOL groupsetfirstbyte = FALSE; -const uschar *ptr = *ptrptr; -const uschar *tempptr; -const uschar *nestptr = NULL; -uschar *previous = NULL; -uschar *previous_callout = NULL; -uschar *save_hwm = NULL; -uschar classbits[32]; +BOOL groupsetfirstchar = FALSE; +const pcre_uchar *ptr = *ptrptr; +const pcre_uchar *tempptr; +const pcre_uchar *nestptr = NULL; +pcre_uchar *previous = NULL; +pcre_uchar *previous_callout = NULL; +pcre_uchar *save_hwm = NULL; +pcre_uint8 classbits[32]; -#ifdef SUPPORT_UTF8 -BOOL class_utf8; -BOOL utf8 = (options & PCRE_UTF8) != 0; -uschar *class_utf8data; -uschar *class_utf8data_base; -uschar utf8_char[6]; +/* We can fish out the UTF-8 setting once and for all into a BOOL, but we +must not do this for other options (e.g. PCRE_EXTENDED) because they may change +dynamically as we process the pattern. */ + +#ifdef SUPPORT_UTF +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +pcre_uchar utf_chars[6]; #else -BOOL utf8 = FALSE; -uschar *utf8_char = NULL; +BOOL utf = FALSE; +#endif + +/* Helper variables for OP_XCLASS opcode (for characters > 255). */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +BOOL xclass; +pcre_uchar *class_uchardata; +pcre_uchar *class_uchardata_base; #endif #ifdef PCRE_DEBUG @@ -3003,22 +3487,23 @@ greedy_non_default = greedy_default ^ 1; /* Initialize no first byte, no required byte. REQ_UNSET means "no char matching encountered yet". It gets changed to REQ_NONE if we hit something that -matches a non-fixed char first char; reqbyte just remains unset if we never +matches a non-fixed char first char; reqchar just remains unset if we never find one. When we hit a repeat whose minimum is zero, we may have to adjust these values to take the zero repeat into account. This is implemented by setting them to -zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual +zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ -firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET; +firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET; -/* The variable req_caseopt contains either the REQ_CASELESS value or zero, -according to the current setting of the caseless flag. REQ_CASELESS is a bit -value > 255. It is added into the firstbyte or reqbyte variables to record the -case status of the value. This is used only for ASCII characters. */ +/* The variable req_caseopt contains either the REQ_CASELESS value +or zero, according to the current setting of the caseless flag. The +REQ_CASELESS leaves the lower 28 bit empty. It is added into the +firstchar or reqchar variables to record the case status of the +value. This is used only for ASCII characters. */ -req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; +req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0; /* Switch on next character until the end of the branch */ @@ -3030,19 +3515,20 @@ for (;; ptr++) BOOL is_quantifier; BOOL is_recurse; BOOL reset_bracount; - int class_charcount; - int class_lastchar; + int class_has_8bitchar; + int class_single_char; int newoptions; int recno; int refsign; int skipbytes; - int subreqbyte; - int subfirstbyte; + int subreqchar; + int subfirstchar; int terminator; int mclength; - uschar mcbuffer[8]; + int tempbracount; + pcre_uchar mcbuffer[8]; - /* Get next byte in the pattern */ + /* Get next character in the pattern */ c = *ptr; @@ -3064,7 +3550,8 @@ for (;; ptr++) #ifdef PCRE_DEBUG if (code > cd->hwm) cd->hwm = code; /* High water info */ #endif - if (code > cd->start_workspace + WORK_SIZE_CHECK) /* Check for overrun */ + if (code > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { *errorcodeptr = ERR52; goto FAILED; @@ -3087,7 +3574,8 @@ for (;; ptr++) } *lengthptr += (int)(code - last_code); - DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c)); + DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr, + (int)(code - last_code), c, c)); /* If "previous" is set and it is not at the start of the work space, move it back to there, in order to avoid filling up the work space. Otherwise, @@ -3097,7 +3585,7 @@ for (;; ptr++) { if (previous > orig_code) { - memmove(orig_code, previous, code - previous); + memmove(orig_code, previous, IN_UCHARS(code - previous)); code -= previous - orig_code; previous = orig_code; } @@ -3113,7 +3601,8 @@ for (;; ptr++) /* In the real compile phase, just check the workspace used by the forward reference list. */ - else if (cd->hwm > cd->start_workspace + WORK_SIZE_CHECK) + else if (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) { *errorcodeptr = ERR52; goto FAILED; @@ -3161,11 +3650,11 @@ for (;; ptr++) previous_callout = NULL; } - /* In extended mode, skip white space and comments */ + /* In extended mode, skip white space and comments. */ if ((options & PCRE_EXTENDED) != 0) { - if ((cd->ctypes[c] & ctype_space) != 0) continue; + if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue; if (c == CHAR_NUMBER_SIGN) { ptr++; @@ -3173,8 +3662,8 @@ for (;; ptr++) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } if (*ptr != 0) continue; @@ -3198,8 +3687,8 @@ for (;; ptr++) case 0: /* The branch terminates at string end */ case CHAR_VERTICAL_LINE: /* or | or ) */ case CHAR_RIGHT_PARENTHESIS: - *firstbyteptr = firstbyte; - *reqbyteptr = reqbyte; + *firstcharptr = firstchar; + *reqcharptr = reqchar; *codeptr = code; *ptrptr = ptr; if (lengthptr != NULL) @@ -3220,26 +3709,27 @@ for (;; ptr++) the setting of any following char as a first character. */ case CHAR_CIRCUMFLEX_ACCENT: + previous = NULL; if ((options & PCRE_MULTILINE) != 0) { - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + *code++ = OP_CIRCM; } - previous = NULL; - *code++ = OP_CIRC; + else *code++ = OP_CIRC; break; case CHAR_DOLLAR_SIGN: previous = NULL; - *code++ = OP_DOLL; + *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL; break; /* There can never be a first char if '.' is first, whatever happens about - repeats. The value of reqbyte doesn't change either. */ + repeats. The value of reqchar doesn't change either. */ case CHAR_DOT: - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + zeroreqchar = reqchar; previous = code; *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; break; @@ -3294,8 +3784,7 @@ for (;; ptr++) { if (ptr[1] == CHAR_E) ptr++; - else if (strncmp((const char *)ptr+1, - STR_Q STR_BACKSLASH STR_E, 3) == 0) + else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 3; else break; @@ -3314,8 +3803,8 @@ for (;; ptr++) (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) { *code++ = negate_class? OP_ALLANY : OP_FAIL; - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; break; } @@ -3325,24 +3814,25 @@ for (;; ptr++) should_flip_negation = FALSE; - /* Keep a count of chars with values < 256 so that we can optimize the case - of just a single character (as long as it's < 256). However, For higher - valued UTF-8 characters, we don't yet do any optimization. */ + /* For optimization purposes, we track some properties of the class. + class_has_8bitchar will be non-zero, if the class contains at least one + < 256 character. class_single_char will be 1 if the class contains only + a single character. */ - class_charcount = 0; - class_lastchar = -1; + class_has_8bitchar = 0; + class_single_char = 0; /* Initialize the 32-char bit map to all zeros. We build the map in a temporary bit of memory, in case the class contains only 1 character (less than 256), because in that case the compiled code doesn't use the bit map. */ - memset(classbits, 0, 32 * sizeof(uschar)); + memset(classbits, 0, 32 * sizeof(pcre_uint8)); -#ifdef SUPPORT_UTF8 - class_utf8 = FALSE; /* No chars >= 256 */ - class_utf8data = code + LINK_SIZE + 2; /* For UTF-8 items */ - class_utf8data_base = class_utf8data; /* For resetting in pass 1 */ +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + xclass = FALSE; /* No chars >= 256 */ + class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */ + class_uchardata_base = class_uchardata; /* For resetting in pass 1 */ #endif /* Process characters until ] is reached. By writing this as a "do" it @@ -3351,25 +3841,26 @@ for (;; ptr++) if (c != 0) do { - const uschar *oldptr; + const pcre_uchar *oldptr; -#ifdef SUPPORT_UTF8 - if (utf8 && c > 127) +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(c)) { /* Braces are required because the */ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ } +#endif - /* In the pre-compile phase, accumulate the length of any UTF-8 extra +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + /* In the pre-compile phase, accumulate the length of any extra data and reset the pointer. This is so that very large classes that - contain a zillion UTF-8 characters no longer overwrite the work space + contain a zillion > 255 characters no longer overwrite the work space (which is on the stack). */ if (lengthptr != NULL) { - *lengthptr += class_utf8data - class_utf8data_base; - class_utf8data = class_utf8data_base; + *lengthptr += class_uchardata - class_uchardata_base; + class_uchardata = class_uchardata_base; } - #endif /* Inside \Q...\E everything is literal except \E */ @@ -3397,8 +3888,8 @@ for (;; ptr++) { BOOL local_negate = FALSE; int posix_class, taboffset, tabopt; - register const uschar *cbits = cd->cbits; - uschar pbits[32]; + register const pcre_uint8 *cbits = cd->cbits; + pcre_uint8 pbits[32]; if (ptr[1] != CHAR_COLON) { @@ -3453,7 +3944,7 @@ for (;; ptr++) /* Copy in the first table (always present) */ memcpy(pbits, cbits + posix_class_maps[posix_class], - 32 * sizeof(uschar)); + 32 * sizeof(pcre_uint8)); /* If there is a second table, add or remove it as required. */ @@ -3484,16 +3975,20 @@ for (;; ptr++) for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; ptr = tempptr + 1; - class_charcount = 10; /* Set > 1; assumes more than 1 per class */ + /* Every class contains at least one < 256 characters. */ + class_has_8bitchar = 1; + /* Every class contains at least two characters. */ + class_single_char = 2; continue; /* End of POSIX syntax handling */ } /* Backslash may introduce a single character, or it may introduce one of the specials, which just set a flag. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. We - assume that other escapes have more than one character in them, so set - class_charcount bigger than one. Unrecognized escapes fall through and - are either treated as literal characters (by default), or are faulted if + assume that other escapes have more than one character in them, so + speculatively set both class_has_8bitchar and class_single_char bigger + than one. Unrecognized escapes fall through and are either treated + as literal characters (by default), or are faulted if PCRE_EXTRA is set. */ if (c == CHAR_BACKSLASH) @@ -3502,6 +3997,11 @@ for (;; ptr++) if (*errorcodeptr != 0) goto FAILED; if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ + else if (-c == ESC_N) /* \N is not supported in a class */ + { + *errorcodeptr = ERR71; + goto FAILED; + } else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) @@ -3515,8 +4015,11 @@ for (;; ptr++) if (c < 0) { - register const uschar *cbits = cd->cbits; - class_charcount += 2; /* Greater than 1 is what matters */ + register const pcre_uint8 *cbits = cd->cbits; + /* Every class contains at least two < 256 characters. */ + class_has_8bitchar++; + /* Every class contains at least two characters. */ + class_single_char += 2; switch (-c) { @@ -3529,7 +4032,7 @@ for (;; ptr++) case ESC_SU: nestptr = ptr; ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ - class_charcount -= 2; /* Undo! */ + class_has_8bitchar--; /* Undo! */ continue; #endif case ESC_d: @@ -3570,23 +4073,38 @@ for (;; ptr++) SETBIT(classbits, 0x09); /* VT */ SETBIT(classbits, 0x20); /* SPACE */ SETBIT(classbits, 0xa0); /* NSBP */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x1680; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x180e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2000; + *class_uchardata++ = 0x200a; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x202f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x205f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x3000; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata); } #endif continue; @@ -3604,32 +4122,59 @@ for (;; ptr++) } classbits[c] |= x; } - -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x167f; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x1681; + *class_uchardata++ = 0x180d; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x180f; + *class_uchardata++ = 0x1fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x200b; + *class_uchardata++ = 0x202e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2030; + *class_uchardata++ = 0x205e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2060; + *class_uchardata++ = 0x2fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x3001; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; @@ -3640,13 +4185,18 @@ for (;; ptr++) SETBIT(classbits, 0x0c); /* FF */ SETBIT(classbits, 0x0d); /* CR */ SETBIT(classbits, 0x85); /* NEL */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2028; + *class_uchardata++ = 0x2029; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata); } #endif continue; @@ -3668,16 +4218,29 @@ for (;; ptr++) classbits[c] |= x; } -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x2027; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x202a; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; @@ -3690,12 +4253,12 @@ for (;; ptr++) int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; - class_utf8 = TRUE; - *class_utf8data++ = ((-c == ESC_p) != negated)? + xclass = TRUE; + *class_uchardata++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; - *class_utf8data++ = ptype; - *class_utf8data++ = pdata; - class_charcount -= 2; /* Not a < 256 character */ + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + class_has_8bitchar--; /* Undo! */ continue; } #endif @@ -3709,14 +4272,15 @@ for (;; ptr++) *errorcodeptr = ERR7; goto FAILED; } - class_charcount -= 2; /* Undo the default count from above */ - c = *ptr; /* Get the final character and fall through */ + class_has_8bitchar--; /* Undo the speculative increase. */ + class_single_char -= 2; /* Undo the speculative increase. */ + c = *ptr; /* Get the final character and fall through */ break; } } /* Fall through if we have a single character (c >= 0). This may be - greater than 256 in UTF-8 mode. */ + greater than 256. */ } /* End of backslash handling */ @@ -3764,8 +4328,8 @@ for (;; ptr++) goto LONE_SINGLE_CHARACTER; } -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { /* Braces are required because the */ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ } @@ -3809,22 +4373,36 @@ for (;; ptr++) if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; + /* Since we found a character range, single character optimizations + cannot be done anymore. */ + class_single_char = 2; + /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless matching, we have to use an XCLASS with extra data items. Caseless matching for characters > 127 is available only if UCP support is available. */ -#ifdef SUPPORT_UTF8 - if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif defined SUPPORT_UTF + if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif !(defined COMPILE_PCRE8) + if (d > 255) +#endif +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) { - class_utf8 = TRUE; + xclass = TRUE; /* With UCP support, we can find the other case equivalents of the relevant characters. There may be several ranges. Optimize how they fit with the basic range. */ #ifdef SUPPORT_UCP +#ifndef COMPILE_PCRE8 + if (utf && (options & PCRE_CASELESS) != 0) +#else if ((options & PCRE_CASELESS) != 0) +#endif { unsigned int occ, ocd; unsigned int cc = c; @@ -3850,14 +4428,14 @@ for (;; ptr++) if (occ == ocd) { - *class_utf8data++ = XCL_SINGLE; + *class_uchardata++ = XCL_SINGLE; } else { - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(occ, class_utf8data); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(occ, class_uchardata); } - class_utf8data += _pcre_ord2utf8(ocd, class_utf8data); + class_uchardata += PRIV(ord2utf)(ocd, class_uchardata); } } #endif /* SUPPORT_UCP */ @@ -3865,33 +4443,69 @@ for (;; ptr++) /* Now record the original range, possibly modified for UCP caseless overlapping ranges. */ - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(c, class_utf8data); - class_utf8data += _pcre_ord2utf8(d, class_utf8data); + *class_uchardata++ = XCL_RANGE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + if (utf) + { + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); + } + else + { + *class_uchardata++ = c; + *class_uchardata++ = d; + } +#else + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); +#endif +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; + *class_uchardata++ = d; +#endif /* SUPPORT_UTF */ /* With UCP support, we are done. Without UCP support, there is no - caseless matching for UTF-8 characters > 127; we can use the bit map - for the smaller ones. */ + caseless matching for UTF characters > 127; we can use the bit map + for the smaller ones. As for 16 bit characters without UTF, we + can still use */ #ifdef SUPPORT_UCP - continue; /* With next character in the class */ -#else - if ((options & PCRE_CASELESS) == 0 || c > 127) continue; - - /* Adjust upper limit and fall through to set up the map */ - - d = 127; - +#ifndef COMPILE_PCRE8 + if (utf) +#endif + continue; /* With next character in the class */ #endif /* SUPPORT_UCP */ + +#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8) + if (utf) + { + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 127; + } + else + { + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; + } +#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP) + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 127; +#else + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; +#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */ } -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ - /* We use the bit map for all cases when not in UTF-8 mode; else - ranges that lie entirely within 0-127 when there is UCP support; else - for partial ranges without UCP support. */ + /* We use the bit map for 8 bit mode, or when the characters fall + partially or entirely to [0-255] ([0-127] for UCP) ranges. */ - class_charcount += d - c + 1; - class_lastchar = d; + class_has_8bitchar = 1; /* We can save a bit of time by skipping this in the pre-compile. */ @@ -3900,7 +4514,7 @@ for (;; ptr++) classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { - int uc = cd->fcc[c]; /* flip case */ + int uc = cd->fcc[c]; /* flip case */ classbits[uc/8] |= (1 << (uc&7)); } } @@ -3914,41 +4528,110 @@ for (;; ptr++) LONE_SINGLE_CHARACTER: - /* Handle a character that cannot go in the bit map */ + /* Only the value of 1 matters for class_single_char. */ -#ifdef SUPPORT_UTF8 - if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) + if (class_single_char < 2) class_single_char++; + + /* If class_charcount is 1, we saw precisely one character. As long as + there was no use of \p or \P, in other words, no use of any XCLASS + features, we can optimize. + + The optimization throws away the bit map. We turn the item into a + 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative. + In the positive case, it can cause firstchar to be set. Otherwise, there + can be no first char if this item is first, whatever repeat count may + follow. In the case of reqchar, save the previous value for reinstating. */ + + if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(c, class_utf8data); + ptr++; + zeroreqchar = reqchar; + + if (negate_class) + { + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + code += PRIV(ord2utf)(c, code); + else +#endif + *code++ = c; + goto NOT_CHAR; + } + + /* For a single, positive character, get the value into mcbuffer, and + then we can handle this with the normal one-character code. */ + +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + mclength = PRIV(ord2utf)(c, mcbuffer); + else +#endif + { + mcbuffer[0] = c; + mclength = 1; + } + goto ONE_CHAR; + } /* End of 1-char optimization */ + + /* Handle a character that cannot go in the bit map. */ + +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif defined SUPPORT_UTF + if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif !(defined COMPILE_PCRE8) + if (c > 255) +#endif + +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + { + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (!utf) + *class_uchardata++ = c; + else +#endif + class_uchardata += PRIV(ord2utf)(c, class_uchardata); +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; +#endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP +#ifdef COMPILE_PCRE8 if ((options & PCRE_CASELESS) != 0) +#else + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (utf && (options & PCRE_CASELESS) != 0) +#endif { unsigned int othercase; - if ((othercase = UCD_OTHERCASE(c)) != c) + if ((int)(othercase = UCD_OTHERCASE(c)) != c) { - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(othercase, class_utf8data); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(othercase, class_uchardata); } } #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ /* Handle a single-byte character */ { + class_has_8bitchar = 1; classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { - c = cd->fcc[c]; /* flip case */ + c = cd->fcc[c]; /* flip case */ classbits[c/8] |= (1 << (c&7)); } - class_charcount++; - class_lastchar = c; } } @@ -3969,66 +4652,13 @@ for (;; ptr++) goto FAILED; } - /* If class_charcount is 1, we saw precisely one character whose value is - less than 256. As long as there were no characters >= 128 and there was no - use of \p or \P, in other words, no use of any XCLASS features, we can - optimize. + /* If this is the first thing in the branch, there can be no first char + setting, whatever the repeat count. Any reqchar setting must remain + unchanged after any kind of repeat. */ - In UTF-8 mode, we can optimize the negative case only if there were no - characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR - operate on single-bytes only. This is an historical hangover. Maybe one day - we can tidy these opcodes to handle multi-byte characters. - - The optimization throws away the bit map. We turn the item into a - 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note - that OP_NOT does not support multibyte characters. In the positive case, it - can cause firstbyte to be set. Otherwise, there can be no first char if - this item is first, whatever repeat count may follow. In the case of - reqbyte, save the previous value for reinstating. */ - -#ifdef SUPPORT_UTF8 - if (class_charcount == 1 && !class_utf8 && - (!utf8 || !negate_class || class_lastchar < 128)) -#else - if (class_charcount == 1) -#endif - { - zeroreqbyte = reqbyte; - - /* The OP_NOT opcode works on one-byte characters only. */ - - if (negate_class) - { - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - *code++ = OP_NOT; - *code++ = class_lastchar; - break; - } - - /* For a single, positive character, get the value into mcbuffer, and - then we can handle this with the normal one-character code. */ - -#ifdef SUPPORT_UTF8 - if (utf8 && class_lastchar > 127) - mclength = _pcre_ord2utf8(class_lastchar, mcbuffer); - else -#endif - { - mcbuffer[0] = class_lastchar; - mclength = 1; - } - goto ONE_CHAR; - } /* End of 1-char optimization */ - - /* The general case - not the one-char optimization. If this is the first - thing in the branch, there can be no first char setting, whatever the - repeat count. Any reqbyte setting must remain unchanged after any kind of - repeat. */ - - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + zeroreqchar = reqchar; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode, unless there was a negated special @@ -4038,29 +4668,34 @@ for (;; ptr++) be listed) there are no characters < 256, we can omit the bitmap in the actual compiled code. */ -#ifdef SUPPORT_UTF8 - if (class_utf8 && (!should_flip_negation || (options & PCRE_UCP) != 0)) +#ifdef SUPPORT_UTF + if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0)) +#elif !defined COMPILE_PCRE8 + if (xclass && !should_flip_negation) +#endif +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 { - *class_utf8data++ = XCL_END; /* Marks the end of extra data */ + *class_uchardata++ = XCL_END; /* Marks the end of extra data */ *code++ = OP_XCLASS; code += LINK_SIZE; - *code = negate_class? XCL_NOT : 0; + *code = negate_class? XCL_NOT:0; /* If the map is required, move up the extra data to make room for it; otherwise just move the code pointer to the end of the extra data. */ - if (class_charcount > 0) + if (class_has_8bitchar > 0) { *code++ |= XCL_MAP; - memmove(code + 32, code, class_utf8data - code); + memmove(code + (32 / sizeof(pcre_uchar)), code, + IN_UCHARS(class_uchardata - code)); memcpy(code, classbits, 32); - code = class_utf8data + 32; + code = class_uchardata + (32 / sizeof(pcre_uchar)); } - else code = class_utf8data; + else code = class_uchardata; /* Now fill in the complete length of the item */ - PUT(previous, 1, code - previous); + PUT(previous, 1, (int)(code - previous)); break; /* End of class handling */ } #endif @@ -4072,16 +4707,14 @@ for (;; ptr++) negating it if necessary. */ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; - if (negate_class) - { - if (lengthptr == NULL) /* Save time in the pre-compile phase */ - for (c = 0; c < 32; c++) code[c] = ~classbits[c]; - } - else + if (lengthptr == NULL) /* Save time in the pre-compile phase */ { + if (negate_class) + for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; memcpy(code, classbits, 32); } - code += 32; + code += 32 / sizeof(pcre_uchar); + NOT_CHAR: break; @@ -4118,8 +4751,8 @@ for (;; ptr++) if (repeat_min == 0) { - firstbyte = zerofirstbyte; /* Adjust for zero repeat */ - reqbyte = zeroreqbyte; /* Ditto */ + firstchar = zerofirstchar; /* Adjust for zero repeat */ + reqchar = zeroreqchar; /* Ditto */ } /* Remember whether this is a variable length repeat */ @@ -4129,8 +4762,8 @@ for (;; ptr++) op_type = 0; /* Default single-char op codes */ possessive_quantifier = FALSE; /* Default not possessive quantifier */ - /* Save start of previous item, in case we have to move it up to make space - for an inserted OP_ONCE for the additional '+' extension. */ + /* Save start of previous item, in case we have to move it up in order to + insert something before it. */ tempcode = previous; @@ -4153,37 +4786,76 @@ for (;; ptr++) } else repeat_type = greedy_default; - /* If previous was a character match, abolish the item and generate a - repeat item instead. If a char item has a minumum of more than one, ensure - that it is set in reqbyte - it might not be if a sequence such as x{3} is - the first thing in a branch because the x will have gone into firstbyte - instead. */ + /* If previous was a recursion call, wrap it in atomic brackets so that + previous becomes the atomic group. All recursions were so wrapped in the + past, but it no longer happens for non-repeated recursions. In fact, the + repeated ones could be re-implemented independently so as not to need this, + but for the moment we rely on the code for repeating groups. */ - if (*previous == OP_CHAR || *previous == OP_CHARNC) + if (*previous == OP_RECURSE) { - /* Deal with UTF-8 characters that take up more than one byte. It's - easier to write this out separately than try to macrify it. Use c to - hold the length of the character in bytes, plus 0x80 to flag that it's a - length rather than a small character. */ + memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE)); + *previous = OP_ONCE; + PUT(previous, 1, 2 + 2*LINK_SIZE); + previous[2 + 2*LINK_SIZE] = OP_KET; + PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); + code += 2 + 2 * LINK_SIZE; + length_prevgroup = 3 + 3*LINK_SIZE; -#ifdef SUPPORT_UTF8 - if (utf8 && (code[-1] & 0x80) != 0) + /* When actually compiling, we need to check whether this was a forward + reference, and if so, adjust the offset. */ + + if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE) { - uschar *lastchar = code - 1; - while((*lastchar & 0xc0) == 0x80) lastchar--; - c = code - lastchar; /* Length of UTF-8 character */ - memcpy(utf8_char, lastchar, c); /* Save the char */ - c |= 0x80; /* Flag c as a length */ + int offset = GET(cd->hwm, -LINK_SIZE); + if (offset == previous + 1 - cd->start_code) + PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE); + } + } + + /* Now handle repetition for the different types of item. */ + + /* If previous was a character or negated character match, abolish the item + and generate a repeat item instead. If a char item has a minimum of more + than one, ensure that it is set in reqchar - it might not be if a sequence + such as x{3} is the first thing in a branch because the x will have gone + into firstchar instead. */ + + if (*previous == OP_CHAR || *previous == OP_CHARI + || *previous == OP_NOT || *previous == OP_NOTI) + { + switch (*previous) + { + default: /* Make compiler happy. */ + case OP_CHAR: op_type = OP_STAR - OP_STAR; break; + case OP_CHARI: op_type = OP_STARI - OP_STAR; break; + case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break; + case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break; + } + + /* Deal with UTF characters that take up more than one character. It's + easier to write this out separately than try to macrify it. Use c to + hold the length of the character in bytes, plus UTF_LENGTH to flag that + it's a length rather than a small character. */ + +#ifdef SUPPORT_UTF + if (utf && NOT_FIRSTCHAR(code[-1])) + { + pcre_uchar *lastchar = code - 1; + BACKCHAR(lastchar); + c = (int)(code - lastchar); /* Length of UTF-8 character */ + memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */ + c |= UTF_LENGTH; /* Flag c as a length */ } else -#endif - - /* Handle the case of a single byte - either with no UTF8 support, or - with UTF-8 disabled, or for a UTF-8 character < 128. */ +#endif /* SUPPORT_UTF */ + /* Handle the case of a single charater - either with no UTF support, or + with UTF disabled, or for a single character UTF character. */ { c = code[-1]; - if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt; + if (*previous <= OP_CHARI && repeat_min > 1) + reqchar = c | req_caseopt | cd->req_varyopt; } /* If the repetition is unlimited, it pays to see if the next thing on @@ -4193,7 +4865,7 @@ for (;; ptr++) if (!possessive_quantifier && repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) + check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; @@ -4202,26 +4874,6 @@ for (;; ptr++) goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } - /* If previous was a single negated character ([^a] or similar), we use - one of the special opcodes, replacing it. The code is shared with single- - character repeats by setting opt_type to add a suitable offset into - repeat_type. We can also test for auto-possessification. OP_NOT is - currently used only for single-byte chars. */ - - else if (*previous == OP_NOT) - { - op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ - c = previous[1]; - if (!possessive_quantifier && - repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) - { - repeat_type = 0; /* Force greedy */ - possessive_quantifier = TRUE; - } - goto OUTPUT_SINGLE_REPEAT; - } - /* If previous was a character type match (\d or similar), abolish it and create a suitable repeat item. The code is shared with single-character repeats by setting op_type to add a suitable offset into repeat_type. Note @@ -4231,14 +4883,14 @@ for (;; ptr++) else if (*previous < OP_EODN) { - uschar *oldcode; + pcre_uchar *oldcode; int prop_type, prop_value; op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; if (!possessive_quantifier && repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) + check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; @@ -4318,14 +4970,14 @@ for (;; ptr++) we have to insert the character for the previous code. For a repeated Unicode property match, there are two extra bytes that define the required property. In UTF-8 mode, long characters have their length in - c, with the 0x80 bit as a flag. */ + c, with the UTF_LENGTH bit as a flag. */ if (repeat_max < 0) { -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4347,10 +4999,10 @@ for (;; ptr++) else if (repeat_max != repeat_min) { -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4377,10 +5029,10 @@ for (;; ptr++) /* The character or character type itself comes last in all cases. */ -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4404,10 +5056,11 @@ for (;; ptr++) else if (*previous == OP_CLASS || *previous == OP_NCLASS || -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 *previous == OP_XCLASS || #endif - *previous == OP_REF) + *previous == OP_REF || + *previous == OP_REFI) { if (repeat_max == 0) { @@ -4441,35 +5094,35 @@ for (;; ptr++) } /* If previous was a bracket group, we may have to replicate it in certain - cases. */ + cases. Note that at this point we can encounter only the "basic" bracket + opcodes such as BRA and CBRA, as this is the place where they get converted + into the more special varieties such as BRAPOS and SBRA. A test for >= + OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, + ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow + repetition of assertions, but now it does, for Perl compatibility. */ - else if (*previous == OP_BRA || *previous == OP_CBRA || - *previous == OP_ONCE || *previous == OP_COND) + else if (*previous >= OP_ASSERT && *previous <= OP_COND) { register int i; - int ketoffset = 0; int len = (int)(code - previous); - uschar *bralink = NULL; + pcre_uchar *bralink = NULL; + pcre_uchar *brazeroptr = NULL; - /* Repeating a DEFINE group is pointless */ + /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so + we just ignore the repeat. */ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF) - { - *errorcodeptr = ERR55; - goto FAILED; - } + goto END_REPEAT; - /* If the maximum repeat count is unlimited, find the end of the bracket - by scanning through from the start, and compute the offset back to it - from the current code pointer. There may be an OP_OPT setting following - the final KET, so we can't find the end just by going back from the code - pointer. */ + /* There is no sense in actually repeating assertions. The only potential + use of repetition is in cases when the assertion is optional. Therefore, + if the minimum is greater than zero, just ignore the repeat. If the + maximum is not not zero or one, set it to 1. */ - if (repeat_max == -1) + if (*previous < OP_ONCE) /* Assertion */ { - register uschar *ket = previous; - do ket += GET(ket, 1); while (*ket != OP_KET); - ketoffset = (int)(code - ket); + if (repeat_min > 0) goto END_REPEAT; + if (repeat_max < 0 || repeat_max > 1) repeat_max = 1; } /* The case of a zero minimum is special because of the need to stick @@ -4490,10 +5143,11 @@ for (;; ptr++) ** goto END_REPEAT; ** } - However, that fails when a group is referenced as a subroutine from - elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it - so that it is skipped on execution. As we don't have a list of which - groups are referenced, we cannot do this selectively. + However, that fails when a group or a subgroup within it is referenced + as a subroutine from elsewhere in the pattern, so now we stick in + OP_SKIPZERO in front of it so that it is skipped on execution. As we + don't have a list of which groups are referenced, we cannot do this + selectively. If the maximum is 1 or unlimited, we just have to stick in the BRAZERO and do no more at this point. However, we do need to adjust any @@ -4505,14 +5159,15 @@ for (;; ptr++) if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ { *code = OP_END; - adjust_recurse(previous, 1, utf8, cd, save_hwm); - memmove(previous+1, previous, len); + adjust_recurse(previous, 1, utf, cd, save_hwm); + memmove(previous + 1, previous, IN_UCHARS(len)); code++; if (repeat_max == 0) { *previous++ = OP_SKIPZERO; goto END_REPEAT; } + brazeroptr = previous; /* Save for possessive optimizing */ *previous++ = OP_BRAZERO + repeat_type; } @@ -4528,8 +5183,8 @@ for (;; ptr++) { int offset; *code = OP_END; - adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm); - memmove(previous + 2 + LINK_SIZE, previous, len); + adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm); + memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len)); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; @@ -4575,16 +5230,32 @@ for (;; ptr++) *lengthptr += delta; } - /* This is compiling for real */ + /* This is compiling for real. If there is a set first byte for + the group, and we have not yet set a "required byte", set it. Make + sure there is enough workspace for copying forward references before + doing the copy. */ else { - if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte; + if (groupsetfirstchar && reqchar < 0) reqchar = firstchar; + for (i = 1; i < repeat_min; i++) { - uschar *hc; - uschar *this_hwm = cd->hwm; - memcpy(code, previous, len); + pcre_uchar *hc; + pcre_uchar *this_hwm = cd->hwm; + memcpy(code, previous, IN_UCHARS(len)); + + while (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) + { + int save_offset = save_hwm - cd->start_workspace; + int this_offset = this_hwm - cd->start_workspace; + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; + this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; + } + for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len); @@ -4634,8 +5305,8 @@ for (;; ptr++) else for (i = repeat_max - 1; i >= 0; i--) { - uschar *hc; - uschar *this_hwm = cd->hwm; + pcre_uchar *hc; + pcre_uchar *this_hwm = cd->hwm; *code++ = OP_BRAZERO + repeat_type; @@ -4651,7 +5322,22 @@ for (;; ptr++) PUTINC(code, 0, offset); } - memcpy(code, previous, len); + memcpy(code, previous, IN_UCHARS(len)); + + /* Ensure there is enough workspace for forward references before + copying them. */ + + while (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) + { + int save_offset = save_hwm - cd->start_workspace; + int this_offset = this_hwm - cd->start_workspace; + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; + this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; + } + for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1)); @@ -4668,7 +5354,7 @@ for (;; ptr++) { int oldlinkoffset; int offset = (int)(code - bralink + 1); - uschar *bra = code - offset; + pcre_uchar *bra = code - offset; oldlinkoffset = GET(bra, 1); bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; *code++ = OP_KET; @@ -4677,35 +5363,110 @@ for (;; ptr++) } } - /* If the maximum is unlimited, set a repeater in the final copy. We - can't just offset backwards from the current code point, because we - don't know if there's been an options resetting after the ket. The - correct offset was computed above. + /* If the maximum is unlimited, set a repeater in the final copy. For + ONCE brackets, that's all we need to do. However, possessively repeated + ONCE brackets can be converted into non-capturing brackets, as the + behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to + deal with possessive ONCEs specially. - Then, when we are doing the actual compile phase, check to see whether - this group is a non-atomic one that could match an empty string. If so, + Otherwise, when we are doing the actual compile phase, check to see + whether this group is one that could match an empty string. If so, convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so - that runtime checking can be done. [This check is also applied to - atomic groups at runtime, but in a different way.] */ + that runtime checking can be done. [This check is also applied to ONCE + groups at runtime, but in a different way.] + + Then, if the quantifier was possessive and the bracket is not a + conditional, we convert the BRA code to the POS form, and the KET code to + KETRPOS. (It turns out to be convenient at runtime to detect this kind of + subpattern at both the start and at the end.) The use of special opcodes + makes it possible to reduce greatly the stack usage in pcre_exec(). If + the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. + + Then, if the minimum number of matches is 1 or 0, cancel the possessive + flag so that the default action below, of wrapping everything inside + atomic brackets, does not happen. When the minimum is greater than 1, + there will be earlier copies of the group, and so we still have to wrap + the whole thing. */ else { - uschar *ketcode = code - ketoffset; - uschar *bracode = ketcode - GET(ketcode, 1); - *ketcode = OP_KETRMAX + repeat_type; - if (lengthptr == NULL && *bracode != OP_ONCE) + pcre_uchar *ketcode = code - 1 - LINK_SIZE; + pcre_uchar *bracode = ketcode - GET(ketcode, 1); + + /* Convert possessive ONCE brackets to non-capturing */ + + if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) && + possessive_quantifier) *bracode = OP_BRA; + + /* For non-possessive ONCE brackets, all we need to do is to + set the KET. */ + + if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC) + *ketcode = OP_KETRMAX + repeat_type; + + /* Handle non-ONCE brackets and possessive ONCEs (which have been + converted to non-capturing above). */ + + else { - uschar *scode = bracode; - do + /* In the compile phase, check for empty string matching. */ + + if (lengthptr == NULL) { - if (could_be_empty_branch(scode, ketcode, utf8, cd)) + pcre_uchar *scode = bracode; + do { - *bracode += OP_SBRA - OP_BRA; - break; + if (could_be_empty_branch(scode, ketcode, utf, cd)) + { + *bracode += OP_SBRA - OP_BRA; + break; + } + scode += GET(scode, 1); } - scode += GET(scode, 1); + while (*scode == OP_ALT); } - while (*scode == OP_ALT); + + /* Handle possessive quantifiers. */ + + if (possessive_quantifier) + { + /* For COND brackets, we wrap the whole thing in a possessively + repeated non-capturing bracket, because we have not invented POS + versions of the COND opcodes. Because we are moving code along, we + must ensure that any pending recursive references are updated. */ + + if (*bracode == OP_COND || *bracode == OP_SCOND) + { + int nlen = (int)(code - bracode); + *code = OP_END; + adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm); + memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen)); + code += 1 + LINK_SIZE; + nlen += 1 + LINK_SIZE; + *bracode = OP_BRAPOS; + *code++ = OP_KETRPOS; + PUTINC(code, 0, nlen); + PUT(bracode, 1, nlen); + } + + /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ + + else + { + *bracode += 1; /* Switch to xxxPOS opcodes */ + *ketcode = OP_KETRPOS; + } + + /* If the minimum is zero, mark it as possessive, then unset the + possessive flag when the minimum is 0 or 1. */ + + if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; + if (repeat_min < 2) possessive_quantifier = FALSE; + } + + /* Non-possessive quantifier */ + + else *ketcode = OP_KETRMAX + repeat_type; } } } @@ -4726,13 +5487,18 @@ for (;; ptr++) } /* If the character following a repeat is '+', or if certain optimization - tests above succeeded, possessive_quantifier is TRUE. For some of the - simpler opcodes, there is an special alternative opcode for this. For - anything else, we wrap the entire repeated item inside OP_ONCE brackets. - The '+' notation is just syntactic sugar, taken from Sun's Java package, - but the special opcodes can optimize it a bit. The repeated item starts at - tempcode, not at previous, which might be the first part of a string whose - (former) last char we repeated. + tests above succeeded, possessive_quantifier is TRUE. For some opcodes, + there are special alternative opcodes for this case. For anything else, we + wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+' + notation is just syntactic sugar, taken from Sun's Java package, but the + special opcodes can optimize it. + + Some (but not all) possessively repeated subpatterns have already been + completely handled in the code just above. For them, possessive_quantifier + is always FALSE at this stage. + + Note that the repeated item starts at tempcode, not at previous, which + might be the first part of a string whose (former) last char we repeated. Possessifying an 'exact' quantifier has no effect, so we can ignore it. But an 'upto' may follow. We skip over an 'exact' item, and then test the @@ -4743,15 +5509,16 @@ for (;; ptr++) int len; if (*tempcode == OP_TYPEEXACT) - tempcode += _pcre_OP_lengths[*tempcode] + - ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0); + tempcode += PRIV(OP_lengths)[*tempcode] + + ((tempcode[1 + IMM2_SIZE] == OP_PROP + || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT) { - tempcode += _pcre_OP_lengths[*tempcode]; -#ifdef SUPPORT_UTF8 - if (utf8 && tempcode[-1] >= 0xc0) - tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f]; + tempcode += PRIV(OP_lengths)[*tempcode]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(tempcode[-1])) + tempcode += GET_EXTRALEN(tempcode[-1]); #endif } @@ -4763,23 +5530,33 @@ for (;; ptr++) case OP_QUERY: *tempcode = OP_POSQUERY; break; case OP_UPTO: *tempcode = OP_POSUPTO; break; - case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; - case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; - case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; - case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; + case OP_STARI: *tempcode = OP_POSSTARI; break; + case OP_PLUSI: *tempcode = OP_POSPLUSI; break; + case OP_QUERYI: *tempcode = OP_POSQUERYI; break; + case OP_UPTOI: *tempcode = OP_POSUPTOI; break; case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break; case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break; case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break; case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break; + case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break; + case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break; + case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break; + case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break; + + case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; + case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; + case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; + case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; + /* Because we are moving code along, we must ensure that any pending recursive references are updated. */ default: *code = OP_END; - adjust_recurse(tempcode, 1 + LINK_SIZE, utf8, cd, save_hwm); - memmove(tempcode + 1+LINK_SIZE, tempcode, len); + adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm); + memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; @@ -4791,7 +5568,7 @@ for (;; ptr++) } /* In all case we no longer have a previous item. We also set the - "follows varying string" flag for subsequently encountered reqbytes if + "follows varying string" flag for subsequently encountered reqchars if it isn't already set and we have just passed a varying length item. */ END_REPEAT: @@ -4814,24 +5591,34 @@ for (;; ptr++) /* First deal with various "verbs" that can be introduced by '*'. */ - if (*(++ptr) == CHAR_ASTERISK && - ((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':')) + ptr++; + if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' + || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0)))) { int i, namelen; int arglen = 0; const char *vn = verbnames; - const uschar *name = ptr + 1; - const uschar *arg = NULL; + const pcre_uchar *name = ptr + 1; + const pcre_uchar *arg = NULL; previous = NULL; - while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {}; + ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; namelen = (int)(ptr - name); + /* It appears that Perl allows any characters whatsoever, other than + a closing parenthesis, to appear in arguments, so we no longer insist on + letters, digits, and underscores. */ + if (*ptr == CHAR_COLON) { arg = ++ptr; - while ((cd->ctypes[*ptr] & (ctype_letter|ctype_digit)) != 0 - || *ptr == '_') ptr++; + while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; arglen = (int)(ptr - arg); + if (arglen > (int)MAX_MARK) + { + *errorcodeptr = ERR75; + goto FAILED; + } } if (*ptr != CHAR_RIGHT_PARENTHESIS) @@ -4845,24 +5632,34 @@ for (;; ptr++) for (i = 0; i < verbcount; i++) { if (namelen == verbs[i].len && - strncmp((char *)name, vn, namelen) == 0) + STRNCMP_UC_C8(name, vn, namelen) == 0) { - /* Check for open captures before ACCEPT */ + /* Check for open captures before ACCEPT and convert it to + ASSERT_ACCEPT if in an assertion. */ if (verbs[i].op == OP_ACCEPT) { open_capitem *oc; + if (arglen != 0) + { + *errorcodeptr = ERR59; + goto FAILED; + } cd->had_accept = TRUE; for (oc = cd->open_caps; oc != NULL; oc = oc->next) { *code++ = OP_CLOSE; PUT2INC(code, 0, oc->number); } + *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; + + /* Do not set firstchar after *ACCEPT */ + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; } - /* Handle the cases with/without an argument */ + /* Handle other cases with/without an argument */ - if (arglen == 0) + else if (arglen == 0) { if (verbs[i].op < 0) /* Argument is mandatory */ { @@ -4870,11 +5667,7 @@ for (;; ptr++) goto FAILED; } *code = verbs[i].op; - if (*code++ == OP_THEN) - { - PUT(code, 0, code - bcptr->current_branch - 1); - code += LINK_SIZE; - } + if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN; } else @@ -4885,13 +5678,9 @@ for (;; ptr++) goto FAILED; } *code = verbs[i].op_arg; - if (*code++ == OP_THEN_ARG) - { - PUT(code, 0, code - bcptr->current_branch - 1); - code += LINK_SIZE; - } + if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN; *code++ = arglen; - memcpy(code, arg, arglen); + memcpy(code, arg, IN_UCHARS(arglen)); code += arglen; *code++ = 0; } @@ -4914,8 +5703,8 @@ for (;; ptr++) { int i, set, unset, namelen; int *optset; - const uschar *name; - uschar *slot; + const pcre_uchar *name; + pcre_uchar *slot; switch (*(++ptr)) { @@ -4968,10 +5757,10 @@ for (;; ptr++) break; /* Most other conditions use OP_CREF (a couple change to OP_RREF - below), and all need to skip 3 bytes at the start of the group. */ + below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */ code[1+LINK_SIZE] = OP_CREF; - skipbytes = 3; + skipbytes = 1+IMM2_SIZE; refsign = -1; /* Check for a test for recursion in a named group. */ @@ -5004,7 +5793,7 @@ for (;; ptr++) /* We now expect to read a name; any thing else is an error */ - if ((cd->ctypes[ptr[1]] & ctype_word) == 0) + if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0) { ptr += 1; /* To get the right offset */ *errorcodeptr = ERR28; @@ -5015,11 +5804,10 @@ for (;; ptr++) recno = 0; name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) { if (recno >= 0) - recno = ((digitab[*ptr] & ctype_digit) != 0)? - recno * 10 + *ptr - CHAR_0 : -1; + recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1; ptr++; } namelen = (int)(ptr - name); @@ -5067,7 +5855,7 @@ for (;; ptr++) slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { - if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break; slot += cd->name_entry_size; } @@ -5083,7 +5871,7 @@ for (;; ptr++) /* Search the pattern for a forward reference */ else if ((i = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8)) > 0) + (options & PCRE_EXTENDED) != 0, utf)) > 0) { PUT2(code, 2+LINK_SIZE, i); code[1+LINK_SIZE]++; @@ -5109,7 +5897,7 @@ for (;; ptr++) recno = 0; for (i = 1; i < namelen; i++) { - if ((digitab[name[i]] & ctype_digit) == 0) + if (!IS_DIGIT(name[i])) { *errorcodeptr = ERR15; goto FAILED; @@ -5124,7 +5912,7 @@ for (;; ptr++) /* Similarly, check for the (?(DEFINE) "condition", which is always false. */ - else if (namelen == 6 && strncmp((char *)name, STRING_DEFINE, 6) == 0) + else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0) { code[1+LINK_SIZE] = OP_DEF; skipbytes = 1; @@ -5151,6 +5939,7 @@ for (;; ptr++) /* ------------------------------------------------------------ */ case CHAR_EQUALS_SIGN: /* Positive lookahead */ bravalue = OP_ASSERT; + cd->assert_depth += 1; ptr++; break; @@ -5165,6 +5954,7 @@ for (;; ptr++) continue; } bravalue = OP_ASSERT_NOT; + cd->assert_depth += 1; break; @@ -5174,16 +5964,19 @@ for (;; ptr++) { case CHAR_EQUALS_SIGN: /* Positive lookbehind */ bravalue = OP_ASSERTBACK; + cd->assert_depth += 1; ptr += 2; break; case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */ bravalue = OP_ASSERTBACK_NOT; + cd->assert_depth += 1; ptr += 2; break; default: /* Could be name define, else bad */ - if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME; + if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0) + goto DEFINE_NAME; ptr++; /* Correct offset for error */ *errorcodeptr = ERR24; goto FAILED; @@ -5200,13 +5993,14 @@ for (;; ptr++) /* ------------------------------------------------------------ */ case CHAR_C: /* Callout - may be followed by digits; */ - previous_callout = code; /* Save for later completion */ - after_manual_callout = 1; /* Skip one item before completing */ + previous_callout = code; /* Save for later completion */ + after_manual_callout = 1; /* Skip one item before completing */ *code++ = OP_CALLOUT; { int n = 0; - while ((digitab[*(++ptr)] & ctype_digit) != 0) - n = n * 10 + *ptr - CHAR_0; + ptr++; + while(IS_DIGIT(*ptr)) + n = n * 10 + *ptr++ - CHAR_0; if (*ptr != CHAR_RIGHT_PARENTHESIS) { *errorcodeptr = ERR39; @@ -5251,7 +6045,7 @@ for (;; ptr++) CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, just do a syntax check. */ @@ -5268,9 +6062,9 @@ for (;; ptr++) *errorcodeptr = ERR49; goto FAILED; } - if (namelen + 3 > cd->name_entry_size) + if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) { - cd->name_entry_size = namelen + 3; + cd->name_entry_size = namelen + IMM2_SIZE + 1; if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; @@ -5299,10 +6093,10 @@ for (;; ptr++) for (i = 0; i < cd->names_found; i++) { - int crc = memcmp(name, slot+2, namelen); + int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen)); if (crc == 0) { - if (slot[2+namelen] == 0) + if (slot[IMM2_SIZE+namelen] == 0) { if (GET2(slot, 0) != cd->bracount + 1 && (options & PCRE_DUPNAMES) == 0) @@ -5323,7 +6117,7 @@ for (;; ptr++) if (crc < 0) { memmove(slot + cd->name_entry_size, slot, - (cd->names_found - i) * cd->name_entry_size); + IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); break; } @@ -5337,7 +6131,7 @@ for (;; ptr++) if (!dupname) { - uschar *cslot = cd->name_table; + pcre_uchar *cslot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (cslot != slot) @@ -5354,8 +6148,8 @@ for (;; ptr++) } PUT2(slot, 0, cd->bracount + 1); - memcpy(slot + 2, name, namelen); - slot[2+namelen] = 0; + memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen)); + slot[IMM2_SIZE + namelen] = 0; } } @@ -5381,7 +6175,7 @@ for (;; ptr++) NAMED_REF_OR_RECURSE: name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, do a syntax check. We used to just set @@ -5393,7 +6187,7 @@ for (;; ptr++) if (lengthptr != NULL) { - const uschar *temp; + const pcre_uchar *temp; if (namelen == 0) { @@ -5423,7 +6217,7 @@ for (;; ptr++) temp = cd->end_pattern; cd->end_pattern = ptr; recno = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8); + (options & PCRE_EXTENDED) != 0, utf); cd->end_pattern = temp; if (recno < 0) recno = 0; /* Forward ref; set dummy number */ } @@ -5438,8 +6232,8 @@ for (;; ptr++) slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { - if (strncmp((char *)name, (char *)slot+2, namelen) == 0 && - slot[2+namelen] == 0) + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 && + slot[IMM2_SIZE+namelen] == 0) break; slot += cd->name_entry_size; } @@ -5450,7 +6244,7 @@ for (;; ptr++) } else if ((recno = /* Forward back reference */ find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8)) <= 0) + (options & PCRE_EXTENDED) != 0, utf)) <= 0) { *errorcodeptr = ERR15; goto FAILED; @@ -5475,7 +6269,7 @@ for (;; ptr++) case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: { - const uschar *called; + const pcre_uchar *called; terminator = CHAR_RIGHT_PARENTHESIS; /* Come here from the \g<...> and \g'...' code (Oniguruma @@ -5489,7 +6283,7 @@ for (;; ptr++) if ((refsign = *ptr) == CHAR_PLUS) { ptr++; - if ((digitab[*ptr] & ctype_digit) == 0) + if (!IS_DIGIT(*ptr)) { *errorcodeptr = ERR63; goto FAILED; @@ -5497,13 +6291,13 @@ for (;; ptr++) } else if (refsign == CHAR_MINUS) { - if ((digitab[ptr[1]] & ctype_digit) == 0) + if (!IS_DIGIT(ptr[1])) goto OTHER_CHAR_AFTER_QUERY; ptr++; } recno = 0; - while((digitab[*ptr] & ctype_digit) != 0) + while(IS_DIGIT(*ptr)) recno = recno * 10 + *ptr++ - CHAR_0; if (*ptr != terminator) @@ -5554,14 +6348,14 @@ for (;; ptr++) { *code = OP_END; if (recno != 0) - called = _pcre_find_bracket(cd->start_code, utf8, recno); + called = PRIV(find_bracket)(cd->start_code, utf, recno); /* Forward reference */ if (called == NULL) { if (find_parens(cd, NULL, recno, - (options & PCRE_EXTENDED) != 0, utf8) < 0) + (options & PCRE_EXTENDED) != 0, utf) < 0) { *errorcodeptr = ERR15; goto FAILED; @@ -5569,46 +6363,48 @@ for (;; ptr++) /* Fudge the value of "called" so that when it is inserted as an offset below, what it actually inserted is the reference number - of the group. */ + of the group. Then remember the forward reference. */ called = cd->start_code + recno; - PUTINC(cd->hwm, 0, (int)(code + 2 + LINK_SIZE - cd->start_code)); + if (cd->hwm >= cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) + { + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + } + PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code)); } /* If not a forward reference, and the subpattern is still open, this is a recursive call. We check to see if this is a left - recursion that could loop for ever, and diagnose that case. */ + recursion that could loop for ever, and diagnose that case. We + must not, however, do this check if we are in a conditional + subpattern because the condition might be testing for recursion in + a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid. + Forever loops are also detected at runtime, so those that occur in + conditional subpatterns will be picked up then. */ - else if (GET(called, 1) == 0 && - could_be_empty(called, code, bcptr, utf8, cd)) + else if (GET(called, 1) == 0 && cond_depth <= 0 && + could_be_empty(called, code, bcptr, utf, cd)) { *errorcodeptr = ERR40; goto FAILED; } } - /* Insert the recursion/subroutine item, automatically wrapped inside - "once" brackets. Set up a "previous group" length so that a - subsequent quantifier will work. */ - - *code = OP_ONCE; - PUT(code, 1, 2 + 2*LINK_SIZE); - code += 1 + LINK_SIZE; + /* Insert the recursion/subroutine item. It does not have a set first + character (relevant if it is repeated, because it will then be + wrapped with ONCE brackets). */ *code = OP_RECURSE; PUT(code, 1, (int)(called - cd->start_code)); code += 1 + LINK_SIZE; - - *code = OP_KET; - PUT(code, 1, 2 + 2*LINK_SIZE); - code += 1 + LINK_SIZE; - - length_prevgroup = 3 + 3*LINK_SIZE; + groupsetfirstchar = FALSE; } /* Can't determine a first byte now */ - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; continue; @@ -5664,9 +6460,8 @@ for (;; ptr++) is necessary to ensure we correctly detect the start of the pattern in both phases. - If we are not at the pattern start, compile code to change the ims - options if this setting actually changes any of them, and reset the - greedy defaults and the case value for firstbyte and reqbyte. */ + If we are not at the pattern start, reset the greedy defaults and the + case value for firstchar and reqchar. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { @@ -5677,20 +6472,13 @@ for (;; ptr++) } else { - if ((options & PCRE_IMS) != (newoptions & PCRE_IMS)) - { - *code++ = OP_OPT; - *code++ = newoptions & PCRE_IMS; - } greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; - req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; + req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; } /* Change options at this level, and pass them back for use - in subsequent branches. When not at the start of the pattern, this - information is also necessary so that a resetting item can be - compiled at the end of a group (if we are in a group). */ + in subsequent branches. */ *optionsptr = options = newoptions; previous = NULL; /* This item can't be repeated */ @@ -5723,53 +6511,62 @@ for (;; ptr++) NUMBERED_GROUP: cd->bracount += 1; PUT2(code, 1+LINK_SIZE, cd->bracount); - skipbytes = 2; + skipbytes = IMM2_SIZE; } - /* Process nested bracketed regex. Assertions may not be repeated, but - other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a - non-register variable in order to be able to pass its address because some - compilers complain otherwise. Pass in a new setting for the ims options if - they have changed. */ + /* Process nested bracketed regex. Assertions used not to be repeatable, + but this was changed for Perl compatibility, so all kinds can now be + repeated. We copy code into a non-register variable (tempcode) in order to + be able to pass its address because some compilers complain otherwise. */ - previous = (bravalue >= OP_ONCE)? code : NULL; + previous = code; /* For handling repetition */ *code = bravalue; tempcode = code; - tempreqvary = cd->req_varyopt; /* Save value before bracket */ - length_prevgroup = 0; /* Initialize for pre-compile phase */ + tempreqvary = cd->req_varyopt; /* Save value before bracket */ + tempbracount = cd->bracount; /* Save value before bracket */ + length_prevgroup = 0; /* Initialize for pre-compile phase */ if (!compile_regex( - newoptions, /* The complete new option state */ - options & PCRE_IMS, /* The previous ims option state */ - &tempcode, /* Where to put code (updated) */ - &ptr, /* Input pointer (updated) */ - errorcodeptr, /* Where to put an error message */ + newoptions, /* The complete new option state */ + &tempcode, /* Where to put code (updated) */ + &ptr, /* Input pointer (updated) */ + errorcodeptr, /* Where to put an error message */ (bravalue == OP_ASSERTBACK || bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ - reset_bracount, /* True if (?| group */ - skipbytes, /* Skip over bracket number */ - &subfirstbyte, /* For possible first char */ - &subreqbyte, /* For possible last char */ - bcptr, /* Current branch chain */ - cd, /* Tables block */ - (lengthptr == NULL)? NULL : /* Actual compile phase */ - &length_prevgroup /* Pre-compile phase */ + reset_bracount, /* True if (?| group */ + skipbytes, /* Skip over bracket number */ + cond_depth + + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ + &subfirstchar, /* For possible first char */ + &subreqchar, /* For possible last char */ + bcptr, /* Current branch chain */ + cd, /* Tables block */ + (lengthptr == NULL)? NULL : /* Actual compile phase */ + &length_prevgroup /* Pre-compile phase */ )) goto FAILED; - /* At the end of compiling, code is still pointing to the start of the - group, while tempcode has been updated to point past the end of the group - and any option resetting that may follow it. The pattern pointer (ptr) - is on the bracket. */ + /* If this was an atomic group and there are no capturing groups within it, + generate OP_ONCE_NC instead of OP_ONCE. */ - /* If this is a conditional bracket, check that there are no more than + if (bravalue == OP_ONCE && cd->bracount <= tempbracount) + *code = OP_ONCE_NC; + + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) + cd->assert_depth -= 1; + + /* At the end of compiling, code is still pointing to the start of the + group, while tempcode has been updated to point past the end of the group. + The pattern pointer (ptr) is on the bracket. + + If this is a conditional bracket, check that there are no more than two branches in the group, or just one if it's a DEFINE group. We do this in the real compile phase, not in the pre-pass, where the whole group may not be available. */ if (bravalue == OP_COND && lengthptr == NULL) { - uschar *tc = code; + pcre_uchar *tc = code; int condcount = 0; do { @@ -5792,7 +6589,7 @@ for (;; ptr++) } /* A "normal" conditional group. If there is just one branch, we must not - make use of its firstbyte or reqbyte, because this is equivalent to an + make use of its firstchar or reqchar, because this is equivalent to an empty second branch. */ else @@ -5802,7 +6599,7 @@ for (;; ptr++) *errorcodeptr = ERR27; goto FAILED; } - if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE; + if (condcount == 1) subfirstchar = subreqchar = REQ_NONE; } } @@ -5827,7 +6624,7 @@ for (;; ptr++) goto FAILED; } *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; - *code++ = OP_BRA; + code++; /* This already contains bravalue */ PUTINC(code, 0, 1 + LINK_SIZE); *code++ = OP_KET; PUTINC(code, 0, 1 + LINK_SIZE); @@ -5846,55 +6643,55 @@ for (;; ptr++) /* Handle updating of the required and first characters for other types of group. Update for normal brackets of all kinds, and conditions with two branches (see code above). If the bracket is followed by a quantifier with - zero repeat, we have to back off. Hence the definition of zeroreqbyte and - zerofirstbyte outside the main loop so that they can be accessed for the + zero repeat, we have to back off. Hence the definition of zeroreqchar and + zerofirstchar outside the main loop so that they can be accessed for the back off. */ - zeroreqbyte = reqbyte; - zerofirstbyte = firstbyte; - groupsetfirstbyte = FALSE; + zeroreqchar = reqchar; + zerofirstchar = firstchar; + groupsetfirstchar = FALSE; if (bravalue >= OP_ONCE) { - /* If we have not yet set a firstbyte in this branch, take it from the + /* If we have not yet set a firstchar in this branch, take it from the subpattern, remembering that it was set here so that a repeat of more - than one can replicate it as reqbyte if necessary. If the subpattern has - no firstbyte, set "none" for the whole branch. In both cases, a zero - repeat forces firstbyte to "none". */ + than one can replicate it as reqchar if necessary. If the subpattern has + no firstchar, set "none" for the whole branch. In both cases, a zero + repeat forces firstchar to "none". */ - if (firstbyte == REQ_UNSET) + if (firstchar == REQ_UNSET) { - if (subfirstbyte >= 0) + if (subfirstchar >= 0) { - firstbyte = subfirstbyte; - groupsetfirstbyte = TRUE; + firstchar = subfirstchar; + groupsetfirstchar = TRUE; } - else firstbyte = REQ_NONE; - zerofirstbyte = REQ_NONE; + else firstchar = REQ_NONE; + zerofirstchar = REQ_NONE; } - /* If firstbyte was previously set, convert the subpattern's firstbyte - into reqbyte if there wasn't one, using the vary flag that was in + /* If firstchar was previously set, convert the subpattern's firstchar + into reqchar if there wasn't one, using the vary flag that was in existence beforehand. */ - else if (subfirstbyte >= 0 && subreqbyte < 0) - subreqbyte = subfirstbyte | tempreqvary; + else if (subfirstchar >= 0 && subreqchar < 0) + subreqchar = subfirstchar | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ - if (subreqbyte >= 0) reqbyte = subreqbyte; + if (subreqchar >= 0) reqchar = subreqchar; } - /* For a forward assertion, we take the reqbyte, if set. This can be + /* For a forward assertion, we take the reqchar, if set. This can be helpful if the pattern that follows the assertion doesn't set a different - char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte + char. For example, it's useful for /(?=abcde).+/. We can't set firstchar for an assertion, however because it leads to incorrect effect for patterns - such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead - of a firstbyte. This is overcome by a scan at the end if there's no - firstbyte, looking for an asserted first char. */ + such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead + of a firstchar. This is overcome by a scan at the end if there's no + firstchar, looking for an asserted first char. */ - else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte; + else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar; break; /* End of processing '(' */ @@ -5927,13 +6724,13 @@ for (;; ptr++) /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ - if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z) - firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z) + firstchar = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + zerofirstchar = firstchar; + zeroreqchar = reqchar; /* \g or \g'name' is a subroutine call by name and \g or \g'n' is a subroutine call by number (Oniguruma syntax). In fact, the value @@ -5944,7 +6741,7 @@ for (;; ptr++) if (-c == ESC_g) { - const uschar *p; + const pcre_uchar *p; save_hwm = cd->hwm; /* Normally this is set when '(' is read */ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; @@ -5961,10 +6758,11 @@ for (;; ptr++) if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) { - BOOL isnumber = TRUE; + BOOL is_a_number = TRUE; for (p = ptr + 1; *p != 0 && *p != terminator; p++) { - if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE; + if (!MAX_255(*p)) { is_a_number = FALSE; break; } + if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; if ((cd->ctypes[*p] & ctype_word) == 0) break; } if (*p != terminator) @@ -5972,7 +6770,7 @@ for (;; ptr++) *errorcodeptr = ERR57; break; } - if (isnumber) + if (is_a_number) { ptr++; goto HANDLE_NUMERICAL_RECURSION; @@ -5984,7 +6782,7 @@ for (;; ptr++) /* Test a signed number in angle brackets or quotes. */ p = ptr + 2; - while ((digitab[*p] & ctype_digit) != 0) p++; + while (IS_DIGIT(*p)) p++; if (*p != terminator) { *errorcodeptr = ERR57; @@ -5995,11 +6793,16 @@ for (;; ptr++) } /* \k or \k'name' is a back reference by name (Perl syntax). - We also support \k{name} (.NET syntax) */ + We also support \k{name} (.NET syntax). */ - if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN || - ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET)) + if (-c == ESC_k) { + if ((ptr[1] != CHAR_LESS_THAN_SIGN && + ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) + { + *errorcodeptr = ERR69; + break; + } is_recurse = FALSE; terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)? @@ -6007,7 +6810,7 @@ for (;; ptr++) goto NAMED_REF_OR_RECURSE; } - /* Back references are handled specially; must disable firstbyte if + /* Back references are handled specially; must disable firstchar if not set to cope with cases like (?=(\w+))\1: which would otherwise set ':' later. */ @@ -6017,9 +6820,9 @@ for (;; ptr++) recno = -c - ESC_REF; HANDLE_REFERENCE: /* Come here from named backref handling */ - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; previous = code; - *code++ = OP_REF; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, recno); cd->backref_map |= (recno < 32)? (1 << recno) : 1; if (recno > cd->top_backref) cd->top_backref = recno; @@ -6067,10 +6870,13 @@ for (;; ptr++) /* For the rest (including \X when Unicode properties are supported), we can obtain the OP value by negating the escape value in the default situation when PCRE_UCP is not set. When it *is* set, we substitute - Unicode property tests. */ + Unicode property tests. Note that \b and \B do a one-character + lookbehind. */ else { + if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0) + cd->max_lookbehind = 1; #ifdef SUPPORT_UCP if (-c >= ESC_DU && -c <= ESC_wu) { @@ -6079,9 +6885,12 @@ for (;; ptr++) } else #endif + /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE + so that it works in DFA mode and in lookbehinds. */ + { previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; - *code++ = -c; + *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c; } } continue; @@ -6091,9 +6900,9 @@ for (;; ptr++) a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ -#ifdef SUPPORT_UTF8 - if (utf8 && c > 127) - mclength = _pcre_ord2utf8(c, mcbuffer); +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + mclength = PRIV(ord2utf)(c, mcbuffer); else #endif @@ -6114,12 +6923,9 @@ for (;; ptr++) mclength = 1; mcbuffer[0] = c; -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 0xc0) - { - while ((ptr[1] & 0xc0) == 0x80) - mcbuffer[mclength++] = *(++ptr); - } +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(c)) + ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr)); #endif /* At this point we have the character's bytes in mcbuffer, and the length @@ -6127,7 +6933,7 @@ for (;; ptr++) ONE_CHAR: previous = code; - *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; /* Remember if \r or \n were seen */ @@ -6137,34 +6943,34 @@ for (;; ptr++) /* Set the first and required bytes appropriately. If no previous first byte, set it from this character, but revert to none on a zero repeat. - Otherwise, leave the firstbyte value alone, and don't change it on a zero + Otherwise, leave the firstchar value alone, and don't change it on a zero repeat. */ - if (firstbyte == REQ_UNSET) + if (firstchar == REQ_UNSET) { - zerofirstbyte = REQ_NONE; - zeroreqbyte = reqbyte; + zerofirstchar = REQ_NONE; + zeroreqchar = reqchar; - /* If the character is more than one byte long, we can set firstbyte + /* If the character is more than one byte long, we can set firstchar only if it is not to be matched caselessly. */ if (mclength == 1 || req_caseopt == 0) { - firstbyte = mcbuffer[0] | req_caseopt; - if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt; + firstchar = mcbuffer[0] | req_caseopt; + if (mclength != 1) reqchar = code[-1] | cd->req_varyopt; } - else firstbyte = reqbyte = REQ_NONE; + else firstchar = reqchar = REQ_NONE; } - /* firstbyte was previously set; we can set reqbyte only the length is + /* firstchar was previously set; we can set reqchar only if the length is 1 or the matching is caseful. */ else { - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + zerofirstchar = firstchar; + zeroreqchar = reqchar; if (mclength == 1 || req_caseopt == 0) - reqbyte = code[-1] | req_caseopt | cd->req_varyopt; + reqchar = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ @@ -6191,26 +6997,21 @@ return FALSE; /* On entry, ptr is pointing past the bracket character, but on return it points to the closing bracket, or vertical bar, or end of string. The code variable is pointing at the byte into which the BRA operator has been stored. -If the ims options are changed at the start (for a (?ims: group) or during any -branch, we need to insert an OP_OPT item at the start of every following branch -to ensure they get set correctly at run time, and also pass the new options -into every subsequent branch compile. - This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: options option bits, including any changes for this subpattern - oldims previous settings of ims option bits codeptr -> the address of the current code pointer ptrptr -> the address of the current pattern pointer errorcodeptr -> pointer to error code variable lookbehind TRUE if this is a lookbehind assertion reset_bracount TRUE to reset the count for each branch skipbytes skip this many bytes at start (for brackets and OP_COND) - firstbyteptr place to put the first required character, or a negative number - reqbyteptr place to put the last required character, or a negative number + cond_depth depth of nesting for conditional subpatterns + firstcharptr place to put the first required character, or a negative number + reqcharptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. lengthptr NULL during the real compile phase @@ -6220,30 +7021,29 @@ Returns: TRUE on success */ static BOOL -compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr, +compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr, int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, - int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd, - int *lengthptr) + int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr, + branch_chain *bcptr, compile_data *cd, int *lengthptr) { -const uschar *ptr = *ptrptr; -uschar *code = *codeptr; -uschar *last_branch = code; -uschar *start_bracket = code; -uschar *reverse_count = NULL; +const pcre_uchar *ptr = *ptrptr; +pcre_uchar *code = *codeptr; +pcre_uchar *last_branch = code; +pcre_uchar *start_bracket = code; +pcre_uchar *reverse_count = NULL; open_capitem capitem; int capnumber = 0; -int firstbyte, reqbyte; -int branchfirstbyte, branchreqbyte; +pcre_int32 firstchar, reqchar; +pcre_int32 branchfirstchar, branchreqchar; int length; int orig_bracount; int max_bracount; -int old_external_options = cd->external_options; branch_chain bc; bc.outer = bcptr; bc.current_branch = code; -firstbyte = reqbyte = REQ_UNSET; +firstchar = reqchar = REQ_UNSET; /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra bytes that are required at the @@ -6261,7 +7061,9 @@ pre-compile phase to find out whether anything has yet been compiled or not. */ /* If this is a capturing subpattern, add to the chain of open capturing items so that we can detect them if (*ACCEPT) is encountered. This is also used to -detect groups that contain recursive back references to themselves. */ +detect groups that contain recursive back references to themselves. Note that +only OP_CBRA need be tested here; changing this opcode to one of its variants, +e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */ if (*code == OP_CBRA) { @@ -6287,15 +7089,6 @@ for (;;) if (reset_bracount) cd->bracount = orig_bracount; - /* Handle a change of ims options at the start of the branch */ - - if ((options & PCRE_IMS) != oldims) - { - *code++ = OP_OPT; - *code++ = options & PCRE_IMS; - length += 2; - } - /* Set up dummy OP_REVERSE if lookbehind assertion */ if (lookbehind) @@ -6309,22 +7102,14 @@ for (;;) /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ - if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte, - &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length)) + if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar, + &branchreqchar, &bc, cond_depth, cd, + (lengthptr == NULL)? NULL : &length)) { *ptrptr = ptr; return FALSE; } - /* If the external options have changed during this branch, it means that we - are at the top level, and a leading option setting has been encountered. We - need to re-set the original option values to take account of this so that, - during the pre-compile phase, we know to allow for a re-set at the start of - subsequent branches. */ - - if (old_external_options != cd->external_options) - oldims = cd->external_options & PCRE_IMS; - /* Keep the highest bracket count in case (?| was used and some branch has fewer than the rest. */ @@ -6334,43 +7119,43 @@ for (;;) if (lengthptr == NULL) { - /* If this is the first branch, the firstbyte and reqbyte values for the + /* If this is the first branch, the firstchar and reqchar values for the branch become the values for the regex. */ if (*last_branch != OP_ALT) { - firstbyte = branchfirstbyte; - reqbyte = branchreqbyte; + firstchar = branchfirstchar; + reqchar = branchreqchar; } - /* If this is not the first branch, the first char and reqbyte have to + /* If this is not the first branch, the first char and reqchar have to match the values from all the previous branches, except that if the - previous value for reqbyte didn't have REQ_VARY set, it can still match, + previous value for reqchar didn't have REQ_VARY set, it can still match, and we set REQ_VARY for the regex. */ else { - /* If we previously had a firstbyte, but it doesn't match the new branch, - we have to abandon the firstbyte for the regex, but if there was - previously no reqbyte, it takes on the value of the old firstbyte. */ + /* If we previously had a firstchar, but it doesn't match the new branch, + we have to abandon the firstchar for the regex, but if there was + previously no reqchar, it takes on the value of the old firstchar. */ - if (firstbyte >= 0 && firstbyte != branchfirstbyte) + if (firstchar >= 0 && firstchar != branchfirstchar) { - if (reqbyte < 0) reqbyte = firstbyte; - firstbyte = REQ_NONE; + if (reqchar < 0) reqchar = firstchar; + firstchar = REQ_NONE; } - /* If we (now or from before) have no firstbyte, a firstbyte from the - branch becomes a reqbyte if there isn't a branch reqbyte. */ + /* If we (now or from before) have no firstchar, a firstchar from the + branch becomes a reqchar if there isn't a branch reqchar. */ - if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0) - branchreqbyte = branchfirstbyte; + if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0) + branchreqchar = branchfirstchar; - /* Now ensure that the reqbytes match */ + /* Now ensure that the reqchars match */ - if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY)) - reqbyte = REQ_NONE; - else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */ + if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY)) + reqchar = REQ_NONE; + else reqchar |= branchreqchar; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and @@ -6385,7 +7170,8 @@ for (;;) { int fixed_length; *code = OP_END; - fixed_length = find_fixedlength(last_branch, options, FALSE, cd); + fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0, + FALSE, cd); DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length == -3) { @@ -6393,11 +7179,17 @@ for (;;) } else if (fixed_length < 0) { - *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25; + *errorcodeptr = (fixed_length == -2)? ERR36 : + (fixed_length == -4)? ERR70: ERR25; *ptrptr = ptr; return FALSE; } - else { PUT(reverse_count, 0, fixed_length); } + else + { + if (fixed_length > cd->max_lookbehind) + cd->max_lookbehind = fixed_length; + PUT(reverse_count, 0, fixed_length); + } } } @@ -6406,9 +7198,7 @@ for (;;) of offsets, with the field in the BRA item now becoming an offset to the first alternative. If there are no alternatives, it points to the end of the group. The length in the terminating ket is always the length of the whole - bracketed item. If any of the ims options were changed inside the group, - compile a resetting op-code following, except at the very end of the pattern. - Return leaving the pointer at the terminating char. */ + bracketed item. Return leaving the pointer at the terminating char. */ if (*ptr != CHAR_VERTICAL_LINE) { @@ -6440,7 +7230,7 @@ for (;;) if (cd->open_caps->flag) { memmove(start_bracket + 1 + LINK_SIZE, start_bracket, - code - start_bracket); + IN_UCHARS(code - start_bracket)); *start_bracket = OP_ONCE; code += 1 + LINK_SIZE; PUT(start_bracket, 1, (int)(code - start_bracket)); @@ -6452,15 +7242,6 @@ for (;;) cd->open_caps = cd->open_caps->next; } - /* Reset options if needed. */ - - if ((options & PCRE_IMS) != oldims && *ptr == CHAR_RIGHT_PARENTHESIS) - { - *code++ = OP_OPT; - *code++ = oldims; - length += 2; - } - /* Retain the highest bracket number, in case resetting was used. */ cd->bracount = max_bracount; @@ -6469,8 +7250,8 @@ for (;;) *codeptr = code; *ptrptr = ptr; - *firstbyteptr = firstbyte; - *reqbyteptr = reqbyte; + *firstcharptr = firstchar; + *reqcharptr = reqchar; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length) @@ -6520,8 +7301,8 @@ for (;;) /* Try to find out if this is an anchored regular expression. Consider each alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then -it's anchored. However, if this is a multiline pattern, then only OP_SOD -counts, since OP_CIRC can match in the middle. +it's anchored. However, if this is a multiline pattern, then only OP_SOD will +be found, because ^ generates OP_CIRCM in that mode. We can also consider a regex to be anchored if OP_SOM starts all its branches. This is the code for \G, which means "match at start of match position, taking @@ -6542,7 +7323,6 @@ of the more common cases more precisely. Arguments: code points to start of expression (the bracket) - options points to the options setting bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach @@ -6552,35 +7332,38 @@ Returns: TRUE or FALSE */ static BOOL -is_anchored(register const uschar *code, int *options, unsigned int bracket_map, +is_anchored(register const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { - const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], - options, PCRE_MULTILINE, FALSE); + const pcre_uchar *scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* Non-capturing brackets */ - if (op == OP_BRA) + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ - else if (op == OP_CBRA) + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); - if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; + if (!is_anchored(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ - else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC || + op == OP_COND) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and @@ -6595,9 +7378,7 @@ do { /* Check for explicit anchoring */ - else if (op != OP_SOD && op != OP_SOM && - ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC)) - return FALSE; + else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ @@ -6628,12 +7409,12 @@ Returns: TRUE or FALSE */ static BOOL -is_startline(const uschar *code, unsigned int bracket_map, +is_startline(const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { - const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], - NULL, 0, FALSE); + const pcre_uchar *scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* If we are at the start of a conditional assertion group, *both* the @@ -6644,7 +7425,7 @@ do { if (op == OP_COND) { scode += 1 + LINK_SIZE; - if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT]; + if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; switch (*scode) { case OP_CREF: @@ -6660,20 +7441,22 @@ do { scode += 1 + LINK_SIZE; break; } - scode = first_significant_code(scode, NULL, 0, FALSE); + scode = first_significant_code(scode, FALSE); op = *scode; } /* Non-capturing brackets */ - if (op == OP_BRA) + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ - else if (op == OP_CBRA) + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); @@ -6682,7 +7465,7 @@ do { /* Other brackets */ - else if (op == OP_ASSERT || op == OP_ONCE) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } @@ -6697,7 +7480,7 @@ do { /* Check for explicit circumflex */ - else if (op != OP_CIRC) return FALSE; + else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; /* Move on to the next alternative */ @@ -6723,20 +7506,21 @@ we return that char, otherwise -1. Arguments: code points to start of expression (the bracket) - options pointer to the options (used to check casing changes) inassert TRUE if in an assertion Returns: -1 or the fixed first char */ static int -find_firstassertedchar(const uschar *code, int *options, BOOL inassert) +find_firstassertedchar(const pcre_uchar *code, BOOL inassert) { register int c = -1; do { int d; - const uschar *scode = - first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE); + int xl = (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; + const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl, + TRUE); register int op = *scode; switch(op) @@ -6745,30 +7529,44 @@ do { return -1; case OP_BRA: + case OP_BRAPOS: case OP_CBRA: + case OP_SCBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: case OP_ASSERT: case OP_ONCE: + case OP_ONCE_NC: case OP_COND: - if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0) + if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0) return -1; if (c < 0) c = d; else if (c != d) return -1; break; - case OP_EXACT: /* Fall through */ - scode += 2; + case OP_EXACT: + scode += IMM2_SIZE; + /* Fall through */ case OP_CHAR: - case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: if (!inassert) return -1; - if (c < 0) - { - c = scode[1]; - if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS; - } - else if (c != scode[1]) return -1; + if (c < 0) c = scode[1]; + else if (c != scode[1]) return -1; + break; + + case OP_EXACTI: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + if (!inassert) return -1; + if (c < 0) c = scode[1] | REQ_CASELESS; + else if (c != scode[1]) return -1; break; } @@ -6802,28 +7600,45 @@ Returns: pointer to compiled data block, or NULL on error, with errorptr and erroroffset set */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) +#else +PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION +pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr, + int *erroroffset, const unsigned char *tables) +#endif { +#ifdef COMPILE_PCRE8 return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#else +return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#endif } +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) +#else +PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION +pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, + const char **errorptr, int *erroroffset, const unsigned char *tables) +#endif { -real_pcre *re; +REAL_PCRE *re; int length = 1; /* For final END opcode */ -int firstbyte, reqbyte, newline; +pcre_int32 firstchar, reqchar; +int newline; int errorcode = 0; int skipatstart = 0; -BOOL utf8; +BOOL utf; size_t size; -uschar *code; -const uschar *codestart; -const uschar *ptr; +pcre_uchar *code; +const pcre_uchar *codestart; +const pcre_uchar *ptr; compile_data compile_block; compile_data *cd = &compile_block; @@ -6831,13 +7646,14 @@ compile_data *cd = &compile_block; computing the amount of memory that is needed. Compiled items are thrown away as soon as possible, so that a fairly large buffer should be sufficient for this purpose. The same space is used in the second phase for remembering where -to fill in forward references to subpatterns. */ +to fill in forward references to subpatterns. That may overflow, in which case +new memory is obtained from malloc(). */ -uschar cworkspace[COMPILE_WORK_SIZE]; +pcre_uchar cworkspace[COMPILE_WORK_SIZE]; /* Set this early so that early errors get offset 0. */ -ptr = (const uschar *)pattern; +ptr = (const pcre_uchar *)pattern; /* We can't pass back an error message if errorptr is NULL; I guess the best we can do is just return NULL, but we can set a code value if there is a code @@ -6864,7 +7680,7 @@ if (erroroffset == NULL) /* Set up pointers to the individual character tables */ -if (tables == NULL) tables = _pcre_default_tables; +if (tables == NULL) tables = PRIV(default_tables); cd->lcc = tables + lcc_offset; cd->fcc = tables + fcc_offset; cd->cbits = tables + cbits_offset; @@ -6887,27 +7703,33 @@ while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && int newnl = 0; int newbsr = 0; - if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0) +#ifdef COMPILE_PCRE8 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0) { skipatstart += 7; options |= PCRE_UTF8; continue; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0) +#endif +#ifdef COMPILE_PCRE16 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0) + { skipatstart += 8; options |= PCRE_UTF16; continue; } +#endif + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) { skipatstart += 6; options |= PCRE_UCP; continue; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_NO_START_OPT_RIGHTPAR, 13) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; } - if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0) + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_CR; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_LF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_CRLF_RIGHTPAR, 5) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0) { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANY_RIGHTPAR, 4) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0) { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANYCRLF_RIGHTPAR, 8) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0) { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; } if (newnl != 0) @@ -6917,19 +7739,27 @@ while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && else break; } -utf8 = (options & PCRE_UTF8) != 0; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = (options & PCRE_UTF8) != 0; -/* Can't support UTF8 unless PCRE has been compiled to include the code. */ +/* Can't support UTF unless PCRE has been compiled to include the code. The +return of an error code from PRIV(valid_utf)() is a new feature, introduced in +release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is +not used here. */ -#ifdef SUPPORT_UTF8 -if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 && - (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0) +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 && + (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0) { +#ifdef COMPILE_PCRE8 errorcode = ERR44; +#else + errorcode = ERR74; +#endif goto PCRE_EARLY_ERROR_RETURN2; } #else -if (utf8) +if (utf) { errorcode = ERR32; goto PCRE_EARLY_ERROR_RETURN; @@ -6948,13 +7778,11 @@ if ((options & PCRE_UCP) != 0) /* Check validity of \R options. */ -switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) +if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == + (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) { - case 0: - case PCRE_BSR_ANYCRLF: - case PCRE_BSR_UNICODE: - break; - default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; + errorcode = ERR56; + goto PCRE_EARLY_ERROR_RETURN; } /* Handle different types of newline. The three bits give seven cases. The @@ -7007,7 +7835,10 @@ cd->backref_map = 0; /* Reflect pattern for debugging output */ DPRINTF(("------------------------------------------------------------------\n")); -DPRINTF(("%s\n", pattern)); +#ifdef PCRE_DEBUG +print_puchar(stdout, (PCRE_PUCHAR)pattern); +#endif +DPRINTF(("\n")); /* Pretend to compile the pattern while actually just accumulating the length of memory required. This behaviour is triggered by passing a non-NULL final @@ -7020,12 +7851,15 @@ cd->bracount = cd->final_bracount = 0; cd->names_found = 0; cd->name_entry_size = 0; cd->name_table = NULL; -cd->start_workspace = cworkspace; cd->start_code = cworkspace; cd->hwm = cworkspace; -cd->start_pattern = (const uschar *)pattern; -cd->end_pattern = (const uschar *)(pattern + strlen(pattern)); +cd->start_workspace = cworkspace; +cd->workspace_size = COMPILE_WORK_SIZE; +cd->start_pattern = (const pcre_uchar *)pattern; +cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern)); cd->req_varyopt = 0; +cd->assert_depth = 0; +cd->max_lookbehind = 0; cd->external_options = options; cd->external_flags = 0; cd->open_caps = NULL; @@ -7039,13 +7873,12 @@ outside can help speed up starting point checks. */ ptr += skipatstart; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS, - &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, - &length); +(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, + FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, - cd->hwm - cworkspace)); + (int)(cd->hwm - cworkspace))); if (length > MAX_PATTERN_SIZE) { @@ -7058,8 +7891,8 @@ 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. */ -size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3); -re = (real_pcre *)(pcre_malloc)(size); +size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); +re = (REAL_PCRE *)(PUBL(malloc))(size); if (re == NULL) { @@ -7077,14 +7910,13 @@ re->magic_number = MAGIC_NUMBER; re->size = (int)size; re->options = cd->external_options; re->flags = cd->external_flags; -re->dummy1 = 0; -re->first_byte = 0; -re->req_byte = 0; -re->name_table_offset = sizeof(real_pcre); +re->first_char = 0; +re->req_char = 0; +re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar); re->name_entry_size = cd->name_entry_size; re->name_count = cd->names_found; re->ref_count = 0; -re->tables = (tables == _pcre_default_tables)? NULL : tables; +re->tables = (tables == PRIV(default_tables))? NULL : tables; re->nullpad = NULL; /* The starting points of the name/number translation table and of the code are @@ -7095,12 +7927,14 @@ field; this time it's used for remembering forward references to subpatterns. */ cd->final_bracount = cd->bracount; /* Save for checking forward references */ +cd->assert_depth = 0; cd->bracount = 0; +cd->max_lookbehind = 0; cd->names_found = 0; -cd->name_table = (uschar *)re + re->name_table_offset; +cd->name_table = (pcre_uchar *)re + re->name_table_offset; codestart = cd->name_table + re->name_entry_size * re->name_count; cd->start_code = codestart; -cd->hwm = cworkspace; +cd->hwm = (pcre_uchar *)(cd->start_workspace); cd->req_varyopt = 0; cd->had_accept = FALSE; cd->check_lookbehind = FALSE; @@ -7110,16 +7944,17 @@ cd->open_caps = NULL; error, errorcode will be set non-zero, so we don't need to look at the result of the function here. */ -ptr = (const uschar *)pattern + skipatstart; -code = (uschar *)codestart; +ptr = (const pcre_uchar *)pattern + skipatstart; +code = (pcre_uchar *)codestart; *code = OP_BRA; -(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr, - &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL); +(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, + &firstchar, &reqchar, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; -re->flags = cd->external_flags; +re->max_lookbehind = cd->max_lookbehind; +re->flags = cd->external_flags | PCRE_MODE; -if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */ +if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ @@ -7134,20 +7969,34 @@ if debugging, leave the test till after things are printed out. */ if (code - codestart > length) errorcode = ERR23; #endif -/* Fill in any forward references that are required. */ +/* Fill in any forward references that are required. There may be repeated +references; optimize for them, as searching a large regex takes time. */ -while (errorcode == 0 && cd->hwm > cworkspace) +if (cd->hwm > cd->start_workspace) { - int offset, recno; - const uschar *groupptr; - cd->hwm -= LINK_SIZE; - offset = GET(cd->hwm, 0); - recno = GET(codestart, offset); - groupptr = _pcre_find_bracket(codestart, utf8, recno); - if (groupptr == NULL) errorcode = ERR53; - else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart)); + int prev_recno = -1; + const pcre_uchar *groupptr = NULL; + while (errorcode == 0 && cd->hwm > cd->start_workspace) + { + int offset, recno; + cd->hwm -= LINK_SIZE; + offset = GET(cd->hwm, 0); + recno = GET(codestart, offset); + if (recno != prev_recno) + { + groupptr = PRIV(find_bracket)(codestart, utf, recno); + prev_recno = recno; + } + if (groupptr == NULL) errorcode = ERR53; + else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart)); + } } +/* If the workspace had to be expanded, free the new memory. */ + +if (cd->workspace_size > COMPILE_WORK_SIZE) + (PUBL(free))((void *)cd->start_workspace); + /* Give an error if there's back reference to a non-existent capturing subpattern. */ @@ -7163,31 +8012,34 @@ length, and set their lengths. */ if (cd->check_lookbehind) { - uschar *cc = (uschar *)codestart; + pcre_uchar *cc = (pcre_uchar *)codestart; /* Loop, searching for OP_REVERSE items, and process those that do not have their length set. (Actually, it will also re-process any that have a length of zero, but that is a pathological case, and it does no harm.) When we find one, we temporarily terminate the branch it is in while we scan it. */ - for (cc = (uschar *)_pcre_find_bracket(codestart, utf8, -1); + for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1); cc != NULL; - cc = (uschar *)_pcre_find_bracket(cc, utf8, -1)) + cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1)) { if (GET(cc, 1) == 0) { int fixed_length; - uschar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); + pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); int end_op = *be; *be = OP_END; - fixed_length = find_fixedlength(cc, re->options, TRUE, cd); + fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE, + cd); *be = end_op; DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length < 0) { - errorcode = (fixed_length == -2)? ERR36 : ERR25; + errorcode = (fixed_length == -2)? ERR36 : + (fixed_length == -4)? ERR70 : ERR25; break; } + if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length; PUT(cc, 1, fixed_length); } cc += 1 + LINK_SIZE; @@ -7198,9 +8050,9 @@ if (cd->check_lookbehind) if (errorcode != 0) { - (pcre_free)(re); + (PUBL(free))(re); PCRE_EARLY_ERROR_RETURN: - *erroroffset = (int)(ptr - (const uschar *)pattern); + *erroroffset = (int)(ptr - (const pcre_uchar *)pattern); PCRE_EARLY_ERROR_RETURN2: *errorptr = find_error_text(errorcode); if (errorcodeptr != NULL) *errorcodeptr = errorcode; @@ -7219,18 +8071,42 @@ start with ^. and also when all branches start with .* for non-DOTALL matches. if ((re->options & PCRE_ANCHORED) == 0) { - int temp_options = re->options; /* May get changed during these scans */ - if (is_anchored(codestart, &temp_options, 0, cd->backref_map)) + if (is_anchored(codestart, 0, cd->backref_map)) re->options |= PCRE_ANCHORED; else { - if (firstbyte < 0) - firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE); - if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ + if (firstchar < 0) + firstchar = find_firstassertedchar(codestart, FALSE); + if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */ { - int ch = firstbyte & 255; - re->first_byte = ((firstbyte & REQ_CASELESS) != 0 && - cd->fcc[ch] == ch)? ch : firstbyte; +#ifdef COMPILE_PCRE8 + re->first_char = firstchar & 0xff; +#else +#ifdef COMPILE_PCRE16 + re->first_char = firstchar & 0xffff; +#endif +#endif + if ((firstchar & REQ_CASELESS) != 0) + { +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + /* We ignore non-ASCII first chars in 8 bit mode. */ + if (utf) + { + if (re->first_char < 128) + { + if (cd->fcc[re->first_char] != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + else if (UCD_OTHERCASE(re->first_char) != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + else +#endif + if (MAX_255(re->first_char) + && cd->fcc[re->first_char] != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + re->flags |= PCRE_FIRSTSET; } else if (is_startline(codestart, 0, cd->backref_map)) @@ -7242,12 +8118,36 @@ if ((re->options & PCRE_ANCHORED) == 0) variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ -if (reqbyte >= 0 && - ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0)) +if (reqchar >= 0 && + ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0)) { - int ch = reqbyte & 255; - re->req_byte = ((reqbyte & REQ_CASELESS) != 0 && - cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte; +#ifdef COMPILE_PCRE8 + re->req_char = reqchar & 0xff; +#else +#ifdef COMPILE_PCRE16 + re->req_char = reqchar & 0xffff; +#endif +#endif + if ((reqchar & REQ_CASELESS) != 0) + { +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + /* We ignore non-ASCII first chars in 8 bit mode. */ + if (utf) + { + if (re->req_char < 128) + { + if (cd->fcc[re->req_char] != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + else if (UCD_OTHERCASE(re->req_char) != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + else +#endif + if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + re->flags |= PCRE_REQCHSET; } @@ -7262,38 +8162,46 @@ printf("Options=%08x\n", re->options); if ((re->flags & PCRE_FIRSTSET) != 0) { - int ch = re->first_byte & 255; - const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)? - "" : " (caseless)"; - if (isprint(ch)) printf("First char = %c%s\n", ch, caseless); + pcre_uchar ch = re->first_char; + const char *caseless = + ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)"; + if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless); else printf("First char = \\x%02x%s\n", ch, caseless); } if ((re->flags & PCRE_REQCHSET) != 0) { - int ch = re->req_byte & 255; - const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)? - "" : " (caseless)"; - if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless); + pcre_uchar ch = re->req_char; + const char *caseless = + ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)"; + if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless); else printf("Req char = \\x%02x%s\n", ch, caseless); } -pcre_printint(re, stdout, TRUE); +#ifdef COMPILE_PCRE8 +pcre_printint((pcre *)re, stdout, TRUE); +#else +pcre16_printint((pcre *)re, stdout, TRUE); +#endif /* This check is done here in the debugging case so that the code that was compiled can be seen. */ if (code - codestart > length) { - (pcre_free)(re); + (PUBL(free))(re); *errorptr = find_error_text(ERR23); - *erroroffset = ptr - (uschar *)pattern; + *erroroffset = ptr - (pcre_uchar *)pattern; if (errorcodeptr != NULL) *errorcodeptr = ERR23; return NULL; } #endif /* PCRE_DEBUG */ +#ifdef COMPILE_PCRE8 return (pcre *)re; +#else +return (pcre16 *)re; +#endif } /* End of pcre_compile.c */ diff --git a/ext/pcre/pcrelib/pcre_config.c b/ext/pcre/pcrelib/pcre_config.c index 3e7421577a7..34719591f76 100644 --- a/ext/pcre/pcrelib/pcre_config.c +++ b/ext/pcre/pcrelib/pcre_config.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-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -43,6 +43,9 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" +/* Keep the original link size. */ +static int real_link_size = LINK_SIZE; + #include "pcre_internal.h" @@ -60,18 +63,41 @@ Arguments: Returns: 0 if data returned, negative on error */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_config(int what, void *where) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_config(int what, void *where) +#endif { switch (what) { case PCRE_CONFIG_UTF8: -#ifdef SUPPORT_UTF8 +#if defined COMPILE_PCRE16 + *((int *)where) = 0; + return PCRE_ERROR_BADOPTION; +#else +#if defined SUPPORT_UTF *((int *)where) = 1; #else *((int *)where) = 0; #endif break; +#endif + + case PCRE_CONFIG_UTF16: +#if defined COMPILE_PCRE8 + *((int *)where) = 0; + return PCRE_ERROR_BADOPTION; +#else +#if defined SUPPORT_UTF + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; +#endif case PCRE_CONFIG_UNICODE_PROPERTIES: #ifdef SUPPORT_UCP @@ -81,6 +107,22 @@ switch (what) #endif break; + case PCRE_CONFIG_JIT: +#ifdef SUPPORT_JIT + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + + case PCRE_CONFIG_JITTARGET: +#ifdef SUPPORT_JIT + *((const char **)where) = PRIV(jit_get_target)(); +#else + *((const char **)where) = NULL; +#endif + break; + case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; @@ -94,7 +136,7 @@ switch (what) break; case PCRE_CONFIG_LINK_SIZE: - *((int *)where) = LINK_SIZE; + *((int *)where) = real_link_size; break; case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: diff --git a/ext/pcre/pcrelib/pcre_exec.c b/ext/pcre/pcrelib/pcre_exec.c index a007786deaf..4a8f1c268c9 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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ - /* This module contains pcre_exec(), the externally visible function that does pattern matching using an NFA algorithm, trying to mimic Perl as closely as possible. There are also some static supporting functions. */ @@ -55,10 +54,12 @@ possible. There are also some static supporting functions. */ #undef min #undef max -/* Flag bits for the match() function */ +/* Values for setting in md->match_function_type to indicate two special types +of call to match(). We do it this way to save on using another stack variable, +as stack usage is to be discouraged. */ -#define match_condassert 0x01 /* Called to check a condition assertion */ -#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */ +#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */ +#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */ /* Non-error returns from the match() function. Error returns are externally defined PCRE_ERROR_xxx codes, which are all negative. */ @@ -71,18 +72,12 @@ negative to avoid the external error codes. */ #define MATCH_ACCEPT (-999) #define MATCH_COMMIT (-998) -#define MATCH_PRUNE (-997) -#define MATCH_SKIP (-996) -#define MATCH_SKIP_ARG (-995) -#define MATCH_THEN (-994) - -/* This is a convenience macro for code that occurs many times. */ - -#define MRRETURN(ra) \ - { \ - md->mark = markptr; \ - RRETURN(ra); \ - } +#define MATCH_KETRPOS (-997) +#define MATCH_ONCE (-996) +#define MATCH_PRUNE (-995) +#define MATCH_SKIP (-994) +#define MATCH_SKIP_ARG (-993) +#define MATCH_THEN (-992) /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, @@ -115,7 +110,7 @@ Returns: nothing */ static void -pchars(const uschar *p, int length, BOOL is_subject, match_data *md) +pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) { unsigned int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; @@ -130,24 +125,29 @@ while (length-- > 0) * Match a back-reference * *************************************************/ -/* If a back reference hasn't been set, the length that is passed is greater -than the number of characters left in the string, so the match fails. +/* Normally, if a back reference hasn't been set, the length that is passed is +negative, so the match always fails. However, in JavaScript compatibility mode, +the length passed is zero. Note that in caseless UTF-8 mode, the number of +subject bytes matched may be different to the number of reference bytes. Arguments: offset index into the offset vector - eptr points into the subject - length length to be matched + eptr pointer into the subject + length length of reference to be matched (number of bytes) md points to match data block - ims the ims flags + caseless TRUE if caseless -Returns: TRUE if matched +Returns: >= 0 the number of subject bytes matched + -1 no match + -2 partial match; always given if at end subject */ -static BOOL -match_ref(int offset, register USPTR eptr, int length, match_data *md, - unsigned long int ims) +static int +match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, + BOOL caseless) { -USPTR p = md->start_subject + md->offset_vector[offset]; +PCRE_PUCHAR eptr_start = eptr; +register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; #ifdef PCRE_DEBUG if (eptr >= md->end_subject) @@ -162,27 +162,37 @@ pchars(p, length, FALSE, md); printf("\n"); #endif -/* Always fail if not enough characters left */ +/* Always fail if reference not set (and not JavaScript compatible - in that +case the length is passed as zero). */ -if (length > md->end_subject - eptr) return FALSE; +if (length < 0) return -1; /* Separate the caseless case for speed. In UTF-8 mode we can only do this properly if Unicode properties are supported. Otherwise, we can check only ASCII characters. */ -if ((ims & PCRE_CASELESS) != 0) +if (caseless) { -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF #ifdef SUPPORT_UCP - if (md->utf8) + if (md->utf) { - USPTR endptr = eptr + length; - while (eptr < endptr) + /* Match characters up to the end of the reference. NOTE: the number of + bytes matched may differ, because there are some characters whose upper and + lower case versions code as different numbers of bytes. For example, U+023A + (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8); + a sequence of 3 of the former uses 6 bytes, as does a sequence of two of + the latter. It is important, therefore, to check the length along the + reference, not along the subject (earlier code did this wrong). */ + + PCRE_PUCHAR endptr = p + length; + while (p < endptr) { int c, d; + if (eptr >= md->end_subject) return -2; /* Partial match */ GETCHARINC(c, eptr); GETCHARINC(d, p); - if (c != d && c != UCD_OTHERCASE(d)) return FALSE; + if (c != d && c != UCD_OTHERCASE(d)) return -1; } } else @@ -191,18 +201,30 @@ if ((ims & PCRE_CASELESS) != 0) /* The same code works when not in UTF-8 mode and in UTF-8 mode when there is no UCP support. */ - - while (length-- > 0) - { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; } + { + while (length-- > 0) + { + if (eptr >= md->end_subject) return -2; /* Partial match */ + if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; + p++; + eptr++; + } + } } /* In the caseful case, we can just compare the bytes, whether or not we are in UTF-8 mode. */ else - { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } + { + while (length-- > 0) + { + if (eptr >= md->end_subject) return -2; /* Partial match */ + if (*p++ != *eptr++) return -1; + } + } -return TRUE; +return (int)(eptr - eptr_start); } @@ -254,7 +276,7 @@ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, - RM61, RM62 }; + RM61, RM62, RM63, RM64, RM65, RM66 }; /* These versions of the macros use the stack, as normal. There are debugging versions and production versions. Note that the "rw" argument of RMATCH isn't @@ -264,10 +286,10 @@ actually used in this definition. */ #define REGISTER register #ifdef PCRE_DEBUG -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ +#define RMATCH(ra,rb,rc,rd,re,rw) \ { \ printf("match() called in line %d\n", __LINE__); \ - rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \ printf("to line %d\n", __LINE__); \ } #define RRETURN(ra) \ @@ -276,8 +298,8 @@ actually used in this definition. */ return ra; \ } #else -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ - rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1) +#define RMATCH(ra,rb,rc,rd,re,rw) \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) #define RRETURN(ra) return ra #endif @@ -290,19 +312,22 @@ argument of match(), which never changes. */ #define REGISTER -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\ +#define RMATCH(ra,rb,rc,rd,re,rw)\ {\ - heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\ - if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ - frame->Xwhere = rw; \ + heapframe *newframe = frame->Xnextframe;\ + if (newframe == NULL)\ + {\ + newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ + if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ + newframe->Xnextframe = NULL;\ + frame->Xnextframe = newframe;\ + }\ + frame->Xwhere = rw;\ newframe->Xeptr = ra;\ newframe->Xecode = rb;\ newframe->Xmstart = mstart;\ - newframe->Xmarkptr = markptr;\ newframe->Xoffset_top = rc;\ - newframe->Xims = re;\ - newframe->Xeptrb = rf;\ - newframe->Xflags = rg;\ + newframe->Xeptrb = re;\ newframe->Xrdepth = frame->Xrdepth + 1;\ newframe->Xprevframe = frame;\ frame = newframe;\ @@ -316,7 +341,6 @@ argument of match(), which never changes. */ {\ heapframe *oldframe = frame;\ frame = oldframe->Xprevframe;\ - (pcre_stack_free)(oldframe);\ if (frame != NULL)\ {\ rrc = ra;\ @@ -330,30 +354,28 @@ argument of match(), which never changes. */ typedef struct heapframe { struct heapframe *Xprevframe; + struct heapframe *Xnextframe; /* Function arguments that may change */ - USPTR Xeptr; - const uschar *Xecode; - USPTR Xmstart; - USPTR Xmarkptr; + PCRE_PUCHAR Xeptr; + const pcre_uchar *Xecode; + PCRE_PUCHAR Xmstart; int Xoffset_top; - long int Xims; eptrblock *Xeptrb; - int Xflags; unsigned int Xrdepth; /* Function local variables */ - USPTR Xcallpat; -#ifdef SUPPORT_UTF8 - USPTR Xcharptr; + PCRE_PUCHAR Xcallpat; +#ifdef SUPPORT_UTF + PCRE_PUCHAR Xcharptr; #endif - USPTR Xdata; - USPTR Xnext; - USPTR Xpp; - USPTR Xprev; - USPTR Xsaved_eptr; + PCRE_PUCHAR Xdata; + PCRE_PUCHAR Xnext; + PCRE_PUCHAR Xpp; + PCRE_PUCHAR Xprev; + PCRE_PUCHAR Xsaved_eptr; recursion_info Xnew_recursive; @@ -361,17 +383,12 @@ typedef struct heapframe { BOOL Xcondition; BOOL Xprev_is_word; - unsigned long int Xoriginal_ims; - #ifdef SUPPORT_UCP int Xprop_type; int Xprop_value; int Xprop_fail_result; - int Xprop_category; - int Xprop_chartype; - int Xprop_script; int Xoclength; - uschar Xocchars[8]; + pcre_uchar Xocchars[6]; #endif int Xcodelink; @@ -413,7 +430,7 @@ returns a negative (error) response, the outer incarnation must also return the same response. */ /* These macros pack up tests that are used for partial matching, and which -appears several times in the code. We set the "hit end" flag if the pointer is +appear several times in the code. We set the "hit end" flag if the pointer is at the end of the subject and also past the start of the subject (i.e. something has been matched). For hard partial matching, we then return immediately. The second one is used when we already know we are past the end of @@ -424,19 +441,19 @@ the subject. */ eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ - if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \ + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } #define SCHECK_PARTIAL()\ if (md->partial != 0 && eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ - if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \ + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } /* Performance note: It might be tempting to extract commonly used fields from -the md structure (e.g. utf8, end_subject) into individual variables to improve +the md structure (e.g. utf, end_subject) into individual variables to improve performance. Tests using gcc on a SPARC disproved this; in the first case, it made performance worse. @@ -445,16 +462,10 @@ Arguments: ecode pointer to current position in compiled code mstart pointer to the current match start position (can be modified by encountering \K) - markptr pointer to the most recent MARK name, or NULL offset_top current top pointer md pointer to "static" info for the match - ims current /i, /m, and /s options eptrb pointer to chain of blocks containing eptr at start of brackets - for testing for empty matches - flags can contain - match_condassert - this is an assertion condition - match_cbegroup - this is the start of an unlimited repeat - group that can match an empty string rdepth the recursion depth Returns: MATCH_MATCH if matched ) these values are >= 0 @@ -465,9 +476,9 @@ Returns: MATCH_MATCH if matched ) these values are >= 0 */ static int -match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart, - const uschar *markptr, int offset_top, match_data *md, unsigned long int ims, - eptrblock *eptrb, int flags, unsigned int rdepth) +match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode, + PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb, + unsigned int rdepth) { /* These variables do not need to be preserved over recursion in this function, so they can be ordinary variables in all cases. Mark some of them with @@ -476,31 +487,29 @@ so they can be ordinary variables in all cases. Mark some of them with register int rrc; /* Returns from recursive calls */ register int i; /* Used for loops not involving calls to RMATCH() */ register unsigned int c; /* Character values not kept over RMATCH() calls */ -register BOOL utf8; /* Local copy of UTF-8 flag for speed */ +register BOOL utf; /* Local copy of UTF flag for speed */ BOOL minimize, possessive; /* Quantifier options */ +BOOL caseless; int condcode; /* When recursion is not being used, all "local" variables that have to be -preserved over calls to RMATCH() are part of a "frame" which is obtained from -heap storage. Set up the top-level frame here; others are obtained from the -heap whenever RMATCH() does a "recursion". See the macro definitions above. */ +preserved over calls to RMATCH() are part of a "frame". We set up the top-level +frame on the stack here; subsequent instantiations are obtained from the heap +whenever RMATCH() does a "recursion". See the macro definitions above. Putting +the top-level on the stack rather than malloc-ing them all gives a performance +boost in many cases where there is not much "recursion". */ #ifdef NO_RECURSE -heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe)); -if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY); -frame->Xprevframe = NULL; /* Marks the top level */ +heapframe *frame = (heapframe *)md->match_frames_base; /* Copy in the original argument variables */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xmstart = mstart; -frame->Xmarkptr = markptr; frame->Xoffset_top = offset_top; -frame->Xims = ims; frame->Xeptrb = eptrb; -frame->Xflags = flags; frame->Xrdepth = rdepth; /* This is where control jumps back to to effect "recursion" */ @@ -512,16 +521,13 @@ HEAP_RECURSE: #define eptr frame->Xeptr #define ecode frame->Xecode #define mstart frame->Xmstart -#define markptr frame->Xmarkptr #define offset_top frame->Xoffset_top -#define ims frame->Xims #define eptrb frame->Xeptrb -#define flags frame->Xflags #define rdepth frame->Xrdepth /* Ditto for the local variables */ -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF #define charptr frame->Xcharptr #endif #define callpat frame->Xcallpat @@ -538,15 +544,10 @@ HEAP_RECURSE: #define condition frame->Xcondition #define prev_is_word frame->Xprev_is_word -#define original_ims frame->Xoriginal_ims - #ifdef SUPPORT_UCP #define prop_type frame->Xprop_type #define prop_value frame->Xprop_value #define prop_fail_result frame->Xprop_fail_result -#define prop_category frame->Xprop_category -#define prop_chartype frame->Xprop_chartype -#define prop_script frame->Xprop_script #define oclength frame->Xoclength #define occhars frame->Xocchars #endif @@ -576,34 +577,36 @@ i, and fc and c, can be the same variables. */ #define fi i #define fc c +/* Many of the following variables are used only in small blocks of the code. +My normal style of coding would have declared them within each of those blocks. +However, in order to accommodate the version of this code that uses an external +"stack" implemented on the heap, it is easier to declare them all here, so the +declarations can be cut out in a block. The only declarations within blocks +below are for variables that do not have to be preserved over a recursive call +to RMATCH(). */ -#ifdef SUPPORT_UTF8 /* Many of these variables are used only */ -const uschar *charptr; /* in small blocks of the code. My normal */ -#endif /* style of coding would have declared */ -const uschar *callpat; /* them within each of those blocks. */ -const uschar *data; /* However, in order to accommodate the */ -const uschar *next; /* version of this code that uses an */ -USPTR pp; /* external "stack" implemented on the */ -const uschar *prev; /* heap, it is easier to declare them all */ -USPTR saved_eptr; /* here, so the declarations can be cut */ - /* out in a block. The only declarations */ -recursion_info new_recursive; /* within blocks below are for variables */ - /* that do not have to be preserved over */ -BOOL cur_is_word; /* a recursive call to RMATCH(). */ +#ifdef SUPPORT_UTF +const pcre_uchar *charptr; +#endif +const pcre_uchar *callpat; +const pcre_uchar *data; +const pcre_uchar *next; +PCRE_PUCHAR pp; +const pcre_uchar *prev; +PCRE_PUCHAR saved_eptr; + +recursion_info new_recursive; + +BOOL cur_is_word; BOOL condition; BOOL prev_is_word; -unsigned long int original_ims; - #ifdef SUPPORT_UCP int prop_type; int prop_value; int prop_fail_result; -int prop_category; -int prop_chartype; -int prop_script; int oclength; -uschar occhars[8]; +pcre_uchar occhars[6]; #endif int codelink; @@ -619,8 +622,38 @@ int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; + +/* There is a special fudge for calling match() in a way that causes it to +measure the size of its basic stack frame when the stack is being used for +recursion. The second argument (ecode) being NULL triggers this behaviour. It +cannot normally ever be NULL. The return is the negated value of the frame +size. */ + +if (ecode == NULL) + { + if (rdepth == 0) + return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1); + else + { + int len = (char *)&rdepth - (char *)eptr; + return (len > 0)? -len : len; + } + } #endif /* NO_RECURSE */ +/* To save space on the stack and in the heap frame, I have doubled up on some +of the local variables that are used only in localised parts of the code, but +still need to be preserved over recursive calls of match(). These macros define +the alternative names that are used. */ + +#define allow_zero cur_is_word +#define cbegroup condition +#define code_offset codelink +#define condassert condition +#define matched_once prev_is_word +#define foc number +#define save_mark data + /* These statements are here to stop the compiler complaining about unitialized variables. */ @@ -645,10 +678,10 @@ defined). However, RMATCH isn't like a function call because it's quite a complicated macro. It has to be used in one particular way. This shouldn't, however, impact performance when true recursion is being used. */ -#ifdef SUPPORT_UTF8 -utf8 = md->utf8; /* Local copy of the flag */ +#ifdef SUPPORT_UTF +utf = md->utf; /* Local copy of the flag */ #else -utf8 = FALSE; +utf = FALSE; #endif /* First check that we haven't called match() too many times, or that we @@ -657,22 +690,24 @@ haven't exceeded the recursive call limit. */ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT); -original_ims = ims; /* Save for resetting on ')' */ - /* At the start of a group with an unlimited repeat that may match an empty -string, the match_cbegroup flag is set. When this is the case, add the current -subject pointer to the chain of such remembered pointers, to be checked when we -hit the closing ket, in order to break infinite loops that match no characters. -When match() is called in other circumstances, don't add to the chain. The -match_cbegroup flag must NOT be used with tail recursion, because the memory -block that is used is on the stack, so a new one may be required for each -match(). */ +string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is +done this way to save having to use another function argument, which would take +up space on the stack. See also MATCH_CONDASSERT below. -if ((flags & match_cbegroup) != 0) +When MATCH_CBEGROUP is set, add the current subject pointer to the chain of +such remembered pointers, to be checked when we hit the closing ket, in order +to break infinite loops that match no characters. When match() is called in +other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must +NOT be used with tail recursion, because the memory block that is used is on +the stack, so a new one may be required for each match(). */ + +if (md->match_function_type == MATCH_CBEGROUP) { newptrb.epb_saved_eptr = eptr; newptrb.epb_prev = eptrb; eptrb = &newptrb; + md->match_function_type = 0; } /* Now start processing the opcodes. */ @@ -685,9 +720,12 @@ for (;;) switch(op) { case OP_MARK: - markptr = ecode + 2; - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM55); + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM55); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an argument, and we must check whether that argument matches this MARK's @@ -696,98 +734,192 @@ for (;;) position and return MATCH_SKIP. Otherwise, pass back the return code unaltered. */ - if (rrc == MATCH_SKIP_ARG && - strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0) + else if (rrc == MATCH_SKIP_ARG && + STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0) { md->start_match_ptr = eptr; RRETURN(MATCH_SKIP); } - - if (md->mark == NULL) md->mark = markptr; RRETURN(rrc); case OP_FAIL: - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); /* COMMIT overrides PRUNE, SKIP, and THEN */ case OP_COMMIT: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM52); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM52); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && rrc != MATCH_THEN) RRETURN(rrc); - MRRETURN(MATCH_COMMIT); + RRETURN(MATCH_COMMIT); /* PRUNE overrides THEN */ case OP_PRUNE: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM51); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM51); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); - MRRETURN(MATCH_PRUNE); + RRETURN(MATCH_PRUNE); case OP_PRUNE_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM56); + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM56); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); - md->mark = ecode + 2; RRETURN(MATCH_PRUNE); /* SKIP overrides PRUNE and THEN */ case OP_SKIP: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM53); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM53); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); md->start_match_ptr = eptr; /* Pass back current position */ - MRRETURN(MATCH_SKIP); + RRETURN(MATCH_SKIP); + + /* Note that, for Perl compatibility, SKIP with an argument does NOT set + nomatch_mark. There is a flag that disables this opcode when re-matching a + pattern that ended with a SKIP for which there was not a matching MARK. */ case OP_SKIP_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM57); + if (md->ignore_skip_arg) + { + ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; + break; + } + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM57); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); /* Pass back the current skip name by overloading md->start_match_ptr and returning the special MATCH_SKIP_ARG return code. This will either be - caught by a matching MARK, or get to the top, where it is treated the same - as PRUNE. */ + caught by a matching MARK, or get to the top, where it causes a rematch + with the md->ignore_skip_arg flag set. */ md->start_match_ptr = ecode + 2; RRETURN(MATCH_SKIP_ARG); - /* For THEN (and THEN_ARG) we pass back the address of the bracket or - the alt that is at the start of the current branch. This makes it possible - to skip back past alternatives that precede the THEN within the current - branch. */ + /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that + the branch in which it occurs can be determined. Overload the start of + match pointer to do this. */ case OP_THEN: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM54); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM54); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - md->start_match_ptr = ecode - GET(ecode, 1); - MRRETURN(MATCH_THEN); - - case OP_THEN_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE], - offset_top, md, ims, eptrb, flags, RM58); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - md->start_match_ptr = ecode - GET(ecode, 1); - md->mark = ecode + LINK_SIZE + 2; + md->start_match_ptr = ecode; RRETURN(MATCH_THEN); - /* Handle a capturing bracket. If there is space in the offset vector, save - the current subject position in the working slot at the top of the vector. - We mustn't change the current values of the data slot, because they may be - set from a previous iteration of this group, and be referred to by a - reference inside the group. + case OP_THEN_ARG: + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, + md, eptrb, RM58); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->start_match_ptr = ecode; + RRETURN(MATCH_THEN); - If the bracket fails to match, we need to restore this value and also the - values of the final offsets, in case they were set by a previous iteration - of the same bracket. + /* Handle an atomic group that does not contain any capturing parentheses. + This can be handled like an assertion. Prior to 8.13, all atomic groups + were handled this way. In 8.13, the code was changed as below for ONCE, so + that backups pass through the group and thereby reset captured values. + However, this uses a lot more stack, so in 8.20, atomic groups that do not + contain any captures generate OP_ONCE_NC, which can be handled in the old, + less stack intensive way. + + Check the alternative branches in turn - the matching won't pass the KET + for this kind of subpattern. If any one branch matches, we carry on as at + the end of a normal bracket, leaving the subject pointer, but resetting + the start-of-match value in case it was changed by \K. */ + + case OP_ONCE_NC: + prev = ecode; + saved_eptr = eptr; + save_mark = md->mark; + do + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); + if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ + { + mstart = md->start_match_ptr; + break; + } + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode,1); + md->mark = save_mark; + } + while (*ecode == OP_ALT); + + /* If hit the end of the group (which could be repeated), fail */ + + if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); + + /* Continue as from after the group, updating the offsets high water + mark, since extracts may have been taken. */ + + do ecode += GET(ecode, 1); while (*ecode == OP_ALT); + + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + + /* For a non-repeating ket, just continue at this level. This also + happens for a repeating ket if no characters were matched in the group. + This is the forcible breaking of infinite loops as implemented in Perl + 5.005. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + ecode += 1+LINK_SIZE; + break; + } + + /* The repeating kets try the rest of the pattern or restart from the + preceding bracket, in the appropriate order. The second "call" of match() + uses tail recursion, to avoid using another stack frame. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode = prev; + goto TAIL_RECURSE; + } + else /* OP_KETRMAX */ + { + RMATCH(eptr, prev, offset_top, md, eptrb, RM66); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += 1 + LINK_SIZE; + goto TAIL_RECURSE; + } + /* Control never gets here */ + + /* Handle a capturing bracket, other than those that are possessive with an + unlimited repeat. If there is space in the offset vector, save the current + subject position in the working slot at the top of the vector. We mustn't + change the current values of the data slot, because they may be set from a + previous iteration of this group, and be referred to by a reference inside + the group. A failure to match might occur after the group has succeeded, + if something later on doesn't match. For this reason, we need to restore + the working value and also the values of the final offsets, in case they + were set by a previous iteration of the same bracket. If there isn't enough space in the offset vector, treat this as if it were a non-capturing bracket. Don't worry about setting the flag for the error @@ -811,31 +943,237 @@ for (;;) save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; + save_mark = md->mark; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); md->offset_vector[md->offset_end - number] = (int)(eptr - md->start_subject); - flags = (op == OP_SCBRA)? match_cbegroup : 0; - do + for (;;) { - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM1); - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM1); + if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ + + /* If we backed up to a THEN, check whether it is within the current + branch by comparing the address of the THEN that is passed back with + the end of the branch. If it is within the current branch, and the + branch is one of two or more alternatives (it either starts or ends + with OP_ALT), we have reached the limit of THEN's action, so convert + the return code to NOMATCH, which will cause normal backtracking to + happen from now on. Otherwise, THEN is passed back to an outer + alternative. This implements Perl's treatment of parenthesized groups, + where a group not containing | does not affect the current alternative, + that is, (X) is NOT the same as (X|(*F)). */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + /* Anything other than NOMATCH is passed back. */ + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); + md->mark = save_mark; + if (*ecode != OP_ALT) break; } - while (*ecode == OP_ALT); DPRINTF(("bracket %d failed\n", number)); - md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; - if (rrc != MATCH_THEN) md->mark = markptr; + /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ + + RRETURN(rrc); + } + + /* FALL THROUGH ... Insufficient room for saving captured contents. Treat + as a non-capturing bracket. */ + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + DPRINTF(("insufficient capture room: treat as non-capturing\n")); + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + /* Non-capturing or atomic group, except for possessive with unlimited + repeat and ONCE group with no captures. Loop for all the alternatives. + + When we get to the final alternative within the brackets, we used to return + the result of a recursive call to match() whatever happened so it was + possible to reduce stack usage by turning this into a tail recursion, + except in the case of a possibly empty group. However, now that there is + the possiblity of (*THEN) occurring in the final alternative, this + optimization is no longer always possible. + + We can optimize if we know there are no (*THEN)s in the pattern; at present + this is the best that can be done. + + MATCH_ONCE is returned when the end of an atomic group is successfully + reached, but subsequent matching fails. It passes back up the tree (causing + captured values to be reset) until the original atomic group level is + reached. This is tested by comparing md->once_target with the start of the + group. At this point, the return is converted into MATCH_NOMATCH so that + previous backup points can be taken. */ + + case OP_ONCE: + case OP_BRA: + case OP_SBRA: + DPRINTF(("start non-capturing bracket\n")); + + for (;;) + { + if (op >= OP_SBRA || op == OP_ONCE) + md->match_function_type = MATCH_CBEGROUP; + + /* If this is not a possibly empty group, and there are no (*THEN)s in + the pattern, and this is the final alternative, optimize as described + above. */ + + else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) + { + ecode += PRIV(OP_lengths)[*ecode]; + goto TAIL_RECURSE; + } + + /* In all other cases, we have to make another call to match(). */ + + save_mark = md->mark; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, + RM2); + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) + { + if (rrc == MATCH_ONCE) + { + const pcre_uchar *scode = ecode; + if (*scode != OP_ONCE) /* If not at start, find it */ + { + while (*scode == OP_ALT) scode += GET(scode, 1); + scode -= GET(scode, 1); + } + if (md->once_target == scode) rrc = MATCH_NOMATCH; + } + RRETURN(rrc); + } + ecode += GET(ecode, 1); + md->mark = save_mark; + if (*ecode != OP_ALT) break; + } + + RRETURN(MATCH_NOMATCH); + + /* Handle possessive capturing brackets with an unlimited repeat. We come + here from BRAZERO with allow_zero set TRUE. The offset_vector values are + handled similarly to the normal case above. However, the matching is + different. The end of these brackets will always be OP_KETRPOS, which + returns MATCH_KETRPOS without going further in the pattern. By this means + we can handle the group by iteration rather than recursion, thereby + reducing the amount of stack needed. */ + + case OP_CBRAPOS: + case OP_SCBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_CAPTURE: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + +#ifdef PCRE_DEBUG + printf("start possessive bracket %d\n", number); + printf("subject="); + pchars(eptr, 16, TRUE, md); + printf("\n"); +#endif + + if (offset < md->offset_max) + { + matched_once = FALSE; + code_offset = (int)(ecode - md->start_code); + + save_offset1 = md->offset_vector[offset]; + save_offset2 = md->offset_vector[offset+1]; + save_offset3 = md->offset_vector[md->offset_end - number]; + save_capture_last = md->capture_last; + + DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); + + /* Each time round the loop, save the current subject position for use + when the group matches. For MATCH_MATCH, the group has matched, so we + restart it with a new subject starting position, remembering that we had + at least one match. For MATCH_NOMATCH, carry on with the alternatives, as + usual. If we haven't matched any alternatives in any iteration, check to + see if a previous iteration matched. If so, the group has matched; + continue from afterwards. Otherwise it has failed; restore the previous + capture values before returning NOMATCH. */ + + for (;;) + { + md->offset_vector[md->offset_end - number] = + (int)(eptr - md->start_subject); + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM63); + if (rrc == MATCH_KETRPOS) + { + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + ecode = md->start_code + code_offset; + save_capture_last = md->capture_last; + matched_once = TRUE; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->capture_last = save_capture_last; + ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; + } + + if (!matched_once) + { + md->offset_vector[offset] = save_offset1; + md->offset_vector[offset+1] = save_offset2; + md->offset_vector[md->offset_end - number] = save_offset3; + } + + if (allow_zero || matched_once) + { + ecode += 1 + LINK_SIZE; + break; + } + RRETURN(MATCH_NOMATCH); } @@ -850,69 +1188,83 @@ for (;;) /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ - /* Non-capturing bracket. Loop for all the alternatives. When we get to the - final alternative within the brackets, we would return the result of a - recursive call to match() whatever happened. We can reduce stack usage by - turning this into a tail recursion, except in the case when match_cbegroup - is set.*/ + /* Non-capturing possessive bracket with unlimited repeat. We come here + from BRAZERO with allow_zero = TRUE. The code is similar to the above, + without the capturing complication. It is written out separately for speed + and cleanliness. */ + + case OP_BRAPOS: + case OP_SBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_NON_CAPTURE: + matched_once = FALSE; + code_offset = (int)(ecode - md->start_code); - case OP_BRA: - case OP_SBRA: - DPRINTF(("start non-capturing bracket\n")); - flags = (op >= OP_SBRA)? match_cbegroup : 0; for (;;) { - if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */ + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM48); + if (rrc == MATCH_KETRPOS) { - if (flags == 0) /* Not a possibly empty group */ - { - ecode += _pcre_OP_lengths[*ecode]; - DPRINTF(("bracket 0 tail recursion\n")); - goto TAIL_RECURSE; - } - - /* Possibly empty group; can't use tail recursion. */ - - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, - eptrb, flags, RM48); - if (rrc == MATCH_NOMATCH) md->mark = markptr; - RRETURN(rrc); + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + ecode = md->start_code + code_offset; + matched_once = TRUE; + continue; } - /* For non-final alternatives, continue the loop for a NOMATCH result; - otherwise return. */ + /* See comment in the code for capturing groups above about handling + THEN. */ - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, - eptrb, flags, RM2); - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; } + + if (matched_once || allow_zero) + { + ecode += 1 + LINK_SIZE; + break; + } + RRETURN(MATCH_NOMATCH); + /* Control never reaches here. */ /* Conditional group: compilation checked that there are no more than two branches. If the condition is false, skipping the first branch takes us past the end if there is only one branch, but that's OK because that is - exactly what going to the ket would do. As there is only one branch to be - obeyed, we can use tail recursion to avoid using another stack frame. */ + exactly what going to the ket would do. */ case OP_COND: case OP_SCOND: - codelink= GET(ecode, 1); + codelink = GET(ecode, 1); /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. */ if (ecode[LINK_SIZE+1] == OP_CALLOUT) { - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + PUBL(callout_block) cb; + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[LINK_SIZE+2]; cb.offset_vector = md->offset_vector; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; +#else + cb.subject = (PCRE_SPTR16)md->start_subject; +#endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); @@ -921,10 +1273,11 @@ for (;;) cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH); + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } - ecode += _pcre_OP_lengths[OP_CALLOUT]; + ecode += PRIV(OP_lengths)[OP_CALLOUT]; } condcode = ecode[LINK_SIZE+1]; @@ -941,16 +1294,16 @@ for (;;) else { int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ - condition = (recno == RREF_ANY || recno == md->recursive->group_num); + condition = (recno == RREF_ANY || recno == md->recursive->group_num); /* If the test is for recursion into a specific subpattern, and it is false, but the test was set up by name, scan the table to see if the name refers to any other numbers, and test them. The condition is true if any one is set. */ - if (!condition && condcode == OP_NRREF && recno != RREF_ANY) + if (!condition && condcode == OP_NRREF) { - uschar *slotA = md->name_table; + pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { if (GET2(slotA, 0) == recno) break; @@ -963,11 +1316,11 @@ for (;;) if (i < md->name_count) { - uschar *slotB = slotA; + pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; @@ -983,7 +1336,7 @@ for (;;) for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; @@ -996,7 +1349,7 @@ for (;;) /* Chose branch according to the condition */ - ecode += condition? 3 : GET(ecode, 1); + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } } @@ -1013,7 +1366,7 @@ for (;;) if (!condition && condcode == OP_NCREF) { int refno = offset >> 1; - uschar *slotA = md->name_table; + pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { @@ -1027,11 +1380,11 @@ for (;;) if (i < md->name_count) { - uschar *slotB = slotA; + pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && @@ -1049,7 +1402,7 @@ for (;;) for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && @@ -1064,7 +1417,7 @@ for (;;) /* Chose branch according to the condition */ - ecode += condition? 3 : GET(ecode, 1); + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } else if (condcode == OP_DEF) /* DEFINE - always false */ @@ -1074,21 +1427,26 @@ for (;;) } /* The condition is an assertion. Call match() to evaluate it - setting - the final argument match_condassert causes it to stop at the end of an - assertion. */ + md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of + an assertion. */ else { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, - match_condassert, RM3); + md->match_function_type = MATCH_CONDASSERT; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3); if (rrc == MATCH_MATCH) { + if (md->end_offset_top > offset_top) + offset_top = md->end_offset_top; /* Captures may have happened */ condition = TRUE; ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); while (*ecode == OP_ALT) ecode += GET(ecode, 1); } - else if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) + + /* PCRE doesn't allow the effect of (*THEN) to escape beyond an + assertion; it is therefore treated as NOMATCH. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { RRETURN(rrc); /* Need braces because of following else */ } @@ -1099,26 +1457,32 @@ for (;;) } } - /* We are now at the branch that is to be obeyed. As there is only one, - we can use tail recursion to avoid using another stack frame, except when - match_cbegroup is required for an unlimited repeat of a possibly empty - group. If the second alternative doesn't exist, we can just plough on. */ + /* We are now at the branch that is to be obeyed. As there is only one, can + use tail recursion to avoid using another stack frame, except when there is + unlimited repeat of a possibly empty group. In the latter case, a recursive + call to match() is always required, unless the second alternative doesn't + exist, in which case we can just plough on. Note that, for compatibility + with Perl, the | in a conditional group is NOT treated as creating two + alternatives. If a THEN is encountered in the branch, it propagates out to + the enclosing alternative (unless nested in a deeper set of alternatives, + of course). */ if (condition || *ecode == OP_ALT) { - ecode += 1 + LINK_SIZE; - if (op == OP_SCOND) /* Possibly empty group */ + if (op != OP_SCOND) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49); - RRETURN(rrc); - } - else /* Group must match something */ - { - flags = 0; + ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } + + md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); + RRETURN(rrc); } - else /* Condition false & no alternative */ + + /* Condition false & no alternative; continue after the group. */ + + else { ecode += 1 + LINK_SIZE; } @@ -1145,39 +1509,27 @@ for (;;) md->offset_vector[offset+1] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } - ecode += 3; + ecode += 1 + IMM2_SIZE; break; - /* End of the pattern, either real or forced. If we are in a top-level - recursion, we should restore the offsets appropriately and continue from - after the call. */ + /* End of the pattern, either real or forced. */ - case OP_ACCEPT: case OP_END: - if (md->recursive != NULL && md->recursive->group_num == 0) - { - recursion_info *rec = md->recursive; - DPRINTF(("End of pattern in a (?0) recursion\n")); - md->recursive = rec->prevrec; - memmove(md->offset_vector, rec->offset_save, - rec->saved_max * sizeof(int)); - offset_top = rec->save_offset_top; - ims = original_ims; - ecode = rec->after_call; - break; - } + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: - /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is - set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of - the subject. In both cases, backtracking will then try other alternatives, - if any. */ + /* If we have matched an empty string, fail if not in an assertion and not + in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART + is set and we have matched at the start of the subject. In both cases, + backtracking will then try other alternatives, if any. */ - if (eptr == mstart && - (md->notempty || - (md->notempty_atstart && - mstart == md->start_subject + md->start_offset))) - MRRETURN(MATCH_NOMATCH); + if (eptr == mstart && op != OP_ASSERT_ACCEPT && + md->recursive == NULL && + (md->notempty || + (md->notempty_atstart && + mstart == md->start_subject + md->start_offset))) + RRETURN(MATCH_NOMATCH); /* Otherwise, we have a match. */ @@ -1186,47 +1538,60 @@ for (;;) md->start_match_ptr = mstart; /* and the start (\K can modify) */ /* For some reason, the macros don't work properly if an expression is - given as the argument to MRRETURN when the heap is in use. */ + given as the argument to RRETURN when the heap is in use. */ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; - MRRETURN(rrc); - - /* Change option settings */ - - case OP_OPT: - ims = ecode[1]; - ecode += 2; - DPRINTF(("ims set to %02lx\n", ims)); - break; + RRETURN(rrc); /* Assertion brackets. Check the alternative branches in turn - the matching won't pass the KET for an assertion. If any one branch matches, the assertion is true. Lookbehind assertions have an OP_REVERSE item at the start of each branch to move the current point backwards, so the code at - this level is identical to the lookahead case. */ + this level is identical to the lookahead case. When the assertion is part + of a condition, we want to return immediately afterwards. The caller of + this incarnation of the match() function will have set MATCH_CONDASSERT in + md->match_function type, and one of these opcodes will be the first opcode + that is processed. We use a local variable that is preserved over calls to + match() to remember this case. */ case OP_ASSERT: case OP_ASSERTBACK: + save_mark = md->mark; + if (md->match_function_type == MATCH_CONDASSERT) + { + condassert = TRUE; + md->match_function_type = 0; + } + else condassert = FALSE; + do { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, - RM4); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4); if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { mstart = md->start_match_ptr; /* In case \K reset it */ break; } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + md->mark = save_mark; + + /* A COMMIT failure must fail the entire assertion, without trying any + subsequent branches. */ + + if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH); + + /* PCRE does not allow THEN to escape beyond an assertion; it + is treated as NOMATCH. */ + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); - if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH); + + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ - if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + if (condassert) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ @@ -1242,24 +1607,34 @@ for (;;) case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: + save_mark = md->mark; + if (md->match_function_type == MATCH_CONDASSERT) + { + condassert = TRUE; + md->match_function_type = 0; + } + else condassert = FALSE; + do { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, - RM5); - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); + md->mark = save_mark; + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) { do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + + /* PCRE does not allow THEN to escape beyond an assertion; it is treated + as NOMATCH. */ + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); - if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ ecode += 1 + LINK_SIZE; continue; @@ -1270,14 +1645,14 @@ for (;;) back a number of characters, not bytes. */ case OP_REVERSE: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { i = GET(ecode, 1); while (i-- > 0) { eptr--; - if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr); } } @@ -1288,7 +1663,7 @@ for (;;) { eptr -= GET(ecode, 1); - if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); } /* Save the earliest consulted character, then skip to next op code */ @@ -1302,13 +1677,17 @@ for (;;) function is able to force a failure. */ case OP_CALLOUT: - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + PUBL(callout_block) cb; + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; +#else + cb.subject = (PCRE_SPTR16)md->start_subject; +#endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); @@ -1317,7 +1696,8 @@ for (;;) cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH); + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; @@ -1327,38 +1707,48 @@ for (;;) offset data is the offset to the starting bracket from the start of the whole pattern. (This is so that it works from duplicated subpatterns.) - If there are any capturing brackets started but not finished, we have to - save their starting points and reinstate them after the recursion. However, - we don't know how many such there are (offset_top records the completed - total) so we just have to save all the potential data. There may be up to - 65535 such values, which is too large to put on the stack, but using malloc - for small numbers seems expensive. As a compromise, the stack is used when - there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc - is used. A problem is what to do if the malloc fails ... there is no way of - returning to the top level with an error. Save the top REC_STACK_SAVE_MAX - values on the stack, and accept that the rest may be wrong. + The state of the capturing groups is preserved over recursion, and + re-instated afterwards. We don't know how many are started and not yet + finished (offset_top records the completed total) so we just have to save + all the potential data. There may be up to 65535 such values, which is too + large to put on the stack, but using malloc for small numbers seems + expensive. As a compromise, the stack is used when there are no more than + REC_STACK_SAVE_MAX values to store; otherwise malloc is used. There are also other values that have to be saved. We use a chained sequence of blocks that actually live on the stack. Thanks to Robin Houston - for the original version of this logic. */ + for the original version of this logic. It has, however, been hacked around + a lot, so he is not to blame for the current way it works. */ case OP_RECURSE: { + recursion_info *ri; + int recno; + callpat = md->start_code + GET(ecode, 1); - new_recursive.group_num = (callpat == md->start_code)? 0 : + recno = (callpat == md->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); + /* Check for repeating a recursion without advancing the subject pointer. + This should catch convoluted mutual recursions. (Some simple cases are + caught at compile time.) */ + + for (ri = md->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && eptr == ri->subject_position) + RRETURN(PCRE_ERROR_RECURSELOOP); + /* Add to "recursing stack" */ + new_recursive.group_num = recno; + new_recursive.subject_position = eptr; new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; - /* Find where to continue from afterwards */ + /* Where to continue from afterwards */ ecode += 1 + LINK_SIZE; - new_recursive.after_call = ecode; - /* Now save the offset data. */ + /* Now save the offset data */ new_recursive.saved_max = md->offset_end; if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) @@ -1366,43 +1756,54 @@ for (;;) else { new_recursive.offset_save = - (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); + (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int)); if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); } - memcpy(new_recursive.offset_save, md->offset_vector, new_recursive.saved_max * sizeof(int)); - new_recursive.save_offset_top = offset_top; - /* OK, now we can do the recursion. For each top-level alternative we - restore the offset and recursion data. */ + /* OK, now we can do the recursion. After processing each alternative, + restore the offset data. If there were nested recursions, md->recursive + might be changed, so reset it before looping. */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); - flags = (*callpat >= OP_SBRA)? match_cbegroup : 0; + cbegroup = (*callpat >= OP_SBRA); do { - RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top, - md, ims, eptrb, flags, RM6); + if (cbegroup) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, + md, eptrb, RM6); + memcpy(md->offset_vector, new_recursive.offset_save, + new_recursive.saved_max * sizeof(int)); + md->recursive = new_recursive.prevrec; if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { DPRINTF(("Recursion matched\n")); - md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); - MRRETURN(MATCH_MATCH); + (PUBL(free))(new_recursive.offset_save); + + /* Set where we got to in the subject, and reset the start in case + it was changed by \K. This *is* propagated back out of a recursion, + for Perl compatibility. */ + + eptr = md->end_match_ptr; + mstart = md->start_match_ptr; + goto RECURSION_MATCHED; /* Exit loop; end processing */ } - else if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) + + /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it + is treated as NOMATCH. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN && + rrc != MATCH_COMMIT) { DPRINTF(("Recursion gave error %d\n", rrc)); if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); + (PUBL(free))(new_recursive.offset_save); RRETURN(rrc); } md->recursive = &new_recursive; - memcpy(md->offset_vector, new_recursive.offset_save, - new_recursive.saved_max * sizeof(int)); callpat += GET(callpat, 1); } while (*callpat == OP_ALT); @@ -1410,91 +1811,12 @@ for (;;) DPRINTF(("Recursion didn't match\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); - MRRETURN(MATCH_NOMATCH); - } - /* Control never reaches here */ - - /* "Once" brackets are like assertion brackets except that after a match, - the point in the subject string is not moved back. Thus there can never be - a move back into the brackets. Friedl calls these "atomic" subpatterns. - Check the alternative branches in turn - the matching won't pass the KET - for this kind of subpattern. If any one branch matches, we carry on as at - the end of a normal bracket, leaving the subject pointer, but resetting - the start-of-match value in case it was changed by \K. */ - - case OP_ONCE: - prev = ecode; - saved_eptr = eptr; - - do - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7); - if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ - { - mstart = md->start_match_ptr; - break; - } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); - ecode += GET(ecode,1); - } - while (*ecode == OP_ALT); - - /* If hit the end of the group (which could be repeated), fail */ - - if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); - - /* Continue as from after the assertion, updating the offsets high water - mark, since extracts may have been taken. */ - - do ecode += GET(ecode, 1); while (*ecode == OP_ALT); - - offset_top = md->end_offset_top; - eptr = md->end_match_ptr; - - /* For a non-repeating ket, just continue at this level. This also - happens for a repeating ket if no characters were matched in the group. - This is the forcible breaking of infinite loops as implemented in Perl - 5.005. If there is an options reset, it will get obeyed in the normal - course of events. */ - - if (*ecode == OP_KET || eptr == saved_eptr) - { - ecode += 1+LINK_SIZE; - break; + (PUBL(free))(new_recursive.offset_save); + RRETURN(MATCH_NOMATCH); } - /* The repeating kets try the rest of the pattern or restart from the - preceding bracket, in the appropriate order. The second "call" of match() - uses tail recursion, to avoid using another stack frame. We need to reset - any options that changed within the bracket before re-running it, so - check the next opcode. */ - - if (ecode[1+LINK_SIZE] == OP_OPT) - { - ims = (ims & ~PCRE_IMS) | ecode[4]; - DPRINTF(("ims set to %02lx at group repeat\n", ims)); - } - - if (*ecode == OP_KETRMIN) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode = prev; - flags = 0; - goto TAIL_RECURSE; - } - else /* OP_KETRMAX */ - { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += 1 + LINK_SIZE; - flags = 0; - goto TAIL_RECURSE; - } - /* Control never gets here */ + RECURSION_MATCHED: + break; /* An alternation is the end of a branch; scan along to find the end of the bracketed group and go to there. */ @@ -1510,73 +1832,79 @@ for (;;) optional ones preceded by BRAZERO or BRAMINZERO. */ case OP_BRAZERO: - { - next = ecode+1; - RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - do next += GET(next,1); while (*next == OP_ALT); - ecode = next + 1 + LINK_SIZE; - } + next = ecode + 1; + RMATCH(eptr, next, offset_top, md, eptrb, RM10); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + do next += GET(next, 1); while (*next == OP_ALT); + ecode = next + 1 + LINK_SIZE; break; case OP_BRAMINZERO: - { - next = ecode+1; - do next += GET(next, 1); while (*next == OP_ALT); - RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode++; - } + next = ecode + 1; + do next += GET(next, 1); while (*next == OP_ALT); + RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode++; break; case OP_SKIPZERO: - { - next = ecode+1; - do next += GET(next,1); while (*next == OP_ALT); - ecode = next + 1 + LINK_SIZE; - } + next = ecode+1; + do next += GET(next,1); while (*next == OP_ALT); + ecode = next + 1 + LINK_SIZE; break; + /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything + here; just jump to the group, with allow_zero set TRUE. */ + + case OP_BRAPOSZERO: + op = *(++ecode); + allow_zero = TRUE; + if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE; + goto POSSESSIVE_NON_CAPTURE; + /* End of a group, repeated or non-repeating. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: + case OP_KETRPOS: prev = ecode - GET(ecode, 1); /* If this was a group that remembered the subject start, in order to break infinite repeats of empty string matches, retrieve the subject start from the chain. Otherwise, set it NULL. */ - if (*prev >= OP_SBRA) + if (*prev >= OP_SBRA || *prev == OP_ONCE) { saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ eptrb = eptrb->epb_prev; /* Backup to previous group */ } else saved_eptr = NULL; - /* If we are at the end of an assertion group or an atomic group, stop - matching and return MATCH_MATCH, but record the current high water mark for - use by positive assertions. We also need to record the match start in case - it was changed by \K. */ + /* If we are at the end of an assertion group or a non-capturing atomic + group, stop matching and return MATCH_MATCH, but record the current high + water mark for use by positive assertions. We also need to record the match + start in case it was changed by \K. */ - if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || - *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || - *prev == OP_ONCE) + if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) || + *prev == OP_ONCE_NC) { - md->end_match_ptr = eptr; /* For ONCE */ + md->end_match_ptr = eptr; /* For ONCE_NC */ md->end_offset_top = offset_top; md->start_match_ptr = mstart; - MRRETURN(MATCH_MATCH); + RRETURN(MATCH_MATCH); /* Sets md->mark */ } /* For capturing groups we have to check the group number back at the start and if necessary complete handling an extraction by setting the offsets and - bumping the high water mark. Note that whole-pattern recursion is coded as - a recurse into group 0, so it won't be picked up here. Instead, we catch it - when the OP_END is reached. Other recursion is handled here. */ + bumping the high water mark. Whole-pattern recursion is coded as a recurse + into group 0, so it won't be picked up here. Instead, we catch it when the + OP_END is reached. Other recursion is handled here. We just have to record + the current subject position and start match pointer and give a MATCH + return. */ - if (*prev == OP_CBRA || *prev == OP_SCBRA) + if (*prev == OP_CBRA || *prev == OP_SCBRA || + *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS) { number = GET2(prev, 1+LINK_SIZE); offset = number << 1; @@ -1586,64 +1914,99 @@ for (;;) printf("\n"); #endif + /* Handle a recursively called group. */ + + if (md->recursive != NULL && md->recursive->group_num == number) + { + md->end_match_ptr = eptr; + md->start_match_ptr = mstart; + RRETURN(MATCH_MATCH); + } + + /* Deal with capturing */ + md->capture_last = number; if (offset >= md->offset_max) md->offset_overflow = TRUE; else { + /* If offset is greater than offset_top, it means that we are + "skipping" a capturing group, and that group's offsets must be marked + unset. In earlier versions of PCRE, all the offsets were unset at the + start of matching, but this doesn't work because atomic groups and + assertions can cause a value to be set that should later be unset. + Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as + part of the atomic group, but this is not on the final matching path, + so must be unset when 2 is set. (If there is no group 2, there is no + problem, because offset_top will then be 2, indicating no capture.) */ + + if (offset > offset_top) + { + register int *iptr = md->offset_vector + offset_top; + register int *iend = md->offset_vector + offset; + while (iptr < iend) *iptr++ = -1; + } + + /* Now make the extraction */ + md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; md->offset_vector[offset+1] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } - - /* Handle a recursively called group. Restore the offsets - appropriately and continue from after the call. */ - - if (md->recursive != NULL && md->recursive->group_num == number) - { - recursion_info *rec = md->recursive; - DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); - md->recursive = rec->prevrec; - memcpy(md->offset_vector, rec->offset_save, - rec->saved_max * sizeof(int)); - offset_top = rec->save_offset_top; - ecode = rec->after_call; - ims = original_ims; - break; - } } - /* For both capturing and non-capturing groups, reset the value of the ims - flags, in case they got changed during the group. */ - - ims = original_ims; - DPRINTF(("ims reset to %02lx\n", ims)); - - /* For a non-repeating ket, just continue at this level. This also - happens for a repeating ket if no characters were matched in the group. - This is the forcible breaking of infinite loops as implemented in Perl - 5.005. If there is an options reset, it will get obeyed in the normal - course of events. */ + /* For an ordinary non-repeating ket, just continue at this level. This + also happens for a repeating ket if no characters were matched in the + group. This is the forcible breaking of infinite loops as implemented in + Perl 5.005. For a non-repeating atomic group that includes captures, + establish a backup point by processing the rest of the pattern at a lower + level. If this results in a NOMATCH return, pass MATCH_ONCE back to the + original OP_ONCE level, thereby bypassing intermediate backup points, but + resetting any captures that happened along the way. */ if (*ecode == OP_KET || eptr == saved_eptr) { - ecode += 1 + LINK_SIZE; + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + ecode += 1 + LINK_SIZE; /* Carry on at this level */ break; } - /* The repeating kets try the rest of the pattern or restart from the - preceding bracket, in the appropriate order. In the second case, we can use - tail recursion to avoid using another stack frame, unless we have an - unlimited repeat of a group that can match an empty string. */ + /* OP_KETRPOS is a possessive repeating ket. Remember the current position, + and return the MATCH_KETRPOS. This makes it possible to do the repeats one + at a time from the outer level, thus saving stack. */ - flags = (*prev >= OP_SBRA)? match_cbegroup : 0; + if (*ecode == OP_KETRPOS) + { + md->end_match_ptr = eptr; + md->end_offset_top = offset_top; + RRETURN(MATCH_KETRPOS); + } + + /* The normal repeating kets try the rest of the pattern or restart from + the preceding bracket, in the appropriate order. In the second case, we can + use tail recursion to avoid using another stack frame, unless we have an + an atomic group or an unlimited repeat of a group that can match an empty + string. */ if (*ecode == OP_KETRMIN) { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (flags != 0) /* Could match an empty string */ + if (*prev == OP_ONCE) { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50); + RMATCH(eptr, prev, offset_top, md, eptrb, RM8); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + if (*prev >= OP_SBRA) /* Could match an empty string */ + { + RMATCH(eptr, prev, offset_top, md, eptrb, RM50); RRETURN(rrc); } ecode = prev; @@ -1651,39 +2014,47 @@ for (;;) } else /* OP_KETRMAX */ { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); + RMATCH(eptr, prev, offset_top, md, eptrb, RM13); + if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; + RRETURN(MATCH_ONCE); + } ecode += 1 + LINK_SIZE; - flags = 0; goto TAIL_RECURSE; } /* Control never gets here */ - /* Start of subject unless notbol, or after internal newline if multiline */ + /* Not multiline mode: start of subject assertion, unless notbol. */ case OP_CIRC: - if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH); - if ((ims & PCRE_MULTILINE) != 0) - { - if (eptr != md->start_subject && - (eptr == md->end_subject || !WAS_NEWLINE(eptr))) - MRRETURN(MATCH_NOMATCH); - ecode++; - break; - } - /* ... else fall through */ + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); /* Start of subject assertion */ case OP_SOD: - if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Multiline mode: start of subject unless notbol, or after any newline. */ + + case OP_CIRCM: + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject && + (eptr == md->end_subject || !WAS_NEWLINE(eptr))) + RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: - if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1694,34 +2065,47 @@ for (;;) ecode++; break; - /* Assert before internal newline if multiline, or before a terminating - newline unless endonly is set, else end of subject unless noteol is set. */ + /* Multiline mode: assert before any newline, or before end of subject + unless noteol is set. */ + + case OP_DOLLM: + if (eptr < md->end_subject) + { + if (!IS_NEWLINE(eptr)) + { + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } + } + else + { + if (md->noteol) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + } + ecode++; + break; + + /* Not multiline mode: assert before a terminating newline or before end of + subject unless noteol is set. */ case OP_DOLL: - if ((ims & PCRE_MULTILINE) != 0) - { - if (eptr < md->end_subject) - { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); } - else - { - if (md->noteol) MRRETURN(MATCH_NOMATCH); - SCHECK_PARTIAL(); - } - ecode++; - break; - } - else /* Not multiline */ - { - if (md->noteol) MRRETURN(MATCH_NOMATCH); - if (!md->endonly) goto ASSERT_NL_OR_EOS; - } + if (md->noteol) RRETURN(MATCH_NOMATCH); + if (!md->endonly) goto ASSERT_NL_OR_EOS; /* ... else fall through for endonly */ /* End of subject assertion (\z) */ case OP_EOD: - if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); SCHECK_PARTIAL(); ecode++; break; @@ -1732,7 +2116,18 @@ for (;;) ASSERT_NL_OR_EOS: if (eptr < md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) - MRRETURN(MATCH_NOMATCH); + { + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } /* Either at end of string or \n before end. */ @@ -1751,15 +2146,15 @@ for (;;) be "non-word" characters. Remember the earliest consulted character for partial matching. */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { /* Get status of previous character */ if (eptr == md->start_subject) prev_is_word = FALSE; else { - USPTR lastptr = eptr - 1; - while((*lastptr & 0xc0) == 0x80) lastptr--; + PCRE_PUCHAR lastptr = eptr - 1; + BACKCHAR(lastptr); if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; GETCHAR(c, lastptr); #ifdef SUPPORT_UCP @@ -1824,7 +2219,8 @@ for (;;) } else #endif - prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0); + prev_is_word = MAX_255(eptr[-1]) + && ((md->ctypes[eptr[-1]] & ctype_word) != 0); } /* Get status of next character */ @@ -1847,30 +2243,47 @@ for (;;) } else #endif - cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0); + cur_is_word = MAX_255(*eptr) + && ((md->ctypes[*eptr] & ctype_word) != 0); } /* Now see if the situation is what we want */ if ((*ecode++ == OP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; - /* Match a single character type; inline for speed */ + /* Match any single character type except newline; have to take care with + CRLF newlines and partial matching. */ case OP_ANY: - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + /* Fall through */ + /* Match any single character whatsoever. */ + case OP_ALLANY: - if (eptr++ >= md->end_subject) - { + if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + eptr++; +#ifdef SUPPORT_UTF + if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); +#endif ecode++; break; @@ -1878,11 +2291,12 @@ for (;;) any byte, even newline, independent of the setting of PCRE_DOTALL. */ case OP_ANYBYTE: - if (eptr++ >= md->end_subject) - { + if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } + eptr++; ecode++; break; @@ -1890,16 +2304,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_digit) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1907,16 +2321,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_digit) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1924,16 +2338,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_space) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1941,16 +2355,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_space) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1958,16 +2372,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_word) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1975,16 +2389,16 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_word) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1992,14 +2406,19 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: - if (eptr < md->end_subject && *eptr == 0x0a) eptr++; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + } + else if (*eptr == 0x0a) eptr++; break; case 0x000a: @@ -2010,7 +2429,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } ecode++; @@ -2020,7 +2439,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2045,7 +2464,7 @@ for (;;) case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2054,12 +2473,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -2088,7 +2507,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2101,7 +2520,7 @@ for (;;) case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2110,12 +2529,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -2137,7 +2556,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); { @@ -2146,59 +2565,59 @@ for (;;) switch(ecode[1]) { case PT_ANY: - if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH); + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); break; case PT_LAMP: if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_GC: - if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); break; case PT_PC: if ((ecode[2] != prop->chartype) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_SC: if ((ecode[2] != prop->script) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; /* These are specials */ case PT_ALNUM: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); break; case PT_SPACE: /* Perl space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_PXSPACE: /* POSIX space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_WORD: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; /* This should never occur */ @@ -2218,24 +2637,18 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) { - int category = UCD_CATEGORY(c); - if (category == ucp_M) MRRETURN(MATCH_NOMATCH); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf8) c = *eptr; else - { - GETCHARLEN(c, eptr, len); - } - category = UCD_CATEGORY(c); - if (category != ucp_M) break; - eptr += len; - } + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } + CHECK_PARTIAL(); ecode++; break; #endif @@ -2250,129 +2663,147 @@ for (;;) 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: + + (a) In the default, Perl-compatible state, set the length negative; + this ensures that every attempt at a match fails. We can't just fail + here, because of the possibility of quantifiers with zero minima. + + (b) If the JavaScript compatibility flag is set, set the length to zero + so that the back reference matches an empty string. + + Otherwise, set the length to the length of what was matched by the + referenced subpattern. */ + + if (offset >= offset_top || md->offset_vector[offset] < 0) + length = (md->jscript_compat)? 0 : -1; + else + length = md->offset_vector[offset+1] - md->offset_vector[offset]; + + /* Set up for repetition, or handle the non-repeated case */ + + switch (*ecode) { - offset = GET2(ecode, 1) << 1; /* Doubled ref number */ - ecode += 3; + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; - /* If the reference is unset, there are two possibilities: + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; - (a) In the default, Perl-compatible state, set the length to be longer - than the amount of subject left; this ensures that every attempt at a - match fails. We can't just fail here, because of the possibility of - quantifiers with zero minima. - - (b) If the JavaScript compatibility flag is set, set the length to zero - so that the back reference matches an empty string. - - Otherwise, set the length to the length of what was matched by the - referenced subpattern. */ - - if (offset >= offset_top || md->offset_vector[offset] < 0) - length = (md->jscript_compat)? 0 : (int)(md->end_subject - eptr + 1); - else - length = md->offset_vector[offset+1] - md->offset_vector[offset]; - - /* Set up for repetition, or handle the non-repeated case */ - - switch (*ecode) + default: /* No repeat follows */ + if ((length = match_ref(offset, eptr, length, md, caseless)) < 0) { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - c = *ecode++ - OP_CRSTAR; - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - break; + if (length == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += length; + continue; /* With the main loop */ + } - case OP_CRRANGE: - case OP_CRMINRANGE: - minimize = (*ecode == OP_CRMINRANGE); - min = GET2(ecode, 1); - max = GET2(ecode, 3); - if (max == 0) max = INT_MAX; - ecode += 5; - break; + /* Handle repeated back references. If the length of the reference is + zero, just continue with the main loop. If the length is negative, it + means the reference is unset in non-Java-compatible mode. If the minimum is + zero, we can continue at the same level without recursion. For any other + minimum, carrying on will result in NOMATCH. */ - default: /* No repeat follows */ - if (!match_ref(offset, eptr, length, md, ims)) + if (length == 0) continue; + if (length < 0 && min == 0) continue; + + /* First, ensure the minimum number of matches are present. We get back + the length of the reference string explicitly rather than passing the + address of eptr, so that eptr can be a register variable. */ + + for (i = 1; i <= min; i++) + { + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) + { + if (slength == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + eptr += slength; + } + + /* If min = max, continue at the same level without recursion. + They are not both allowed to be zero. */ + + if (min == max) continue; + + /* If minimizing, keep trying and advancing the pointer */ + + if (minimize) + { + for (fi = min;; fi++) + { + int slength; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM14); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { + if (slength == -2) eptr = md->end_subject; /* Partial match */ CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - eptr += length; - continue; /* With the main loop */ + eptr += slength; } + /* Control never gets here */ + } - /* If the length of the reference is zero, just continue with the - main loop. */ + /* If maximizing, find the longest string and work backwards */ - if (length == 0) continue; - - /* First, ensure the minimum number of matches are present. We get back - the length of the reference string explicitly rather than passing the - address of eptr, so that eptr can be a register variable. */ - - for (i = 1; i <= min; i++) + else + { + pp = eptr; + for (i = min; i < max; i++) { - if (!match_ref(offset, eptr, length, md, ims)) + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); - } - eptr += length; - } + /* Can't use CHECK_PARTIAL because we don't want to update eptr in + the soft partial matching case. */ - /* If min = max, continue at the same level without recursion. - They are not both allowed to be zero. */ - - if (min == max) continue; - - /* If minimizing, keep trying and advancing the pointer */ - - if (minimize) - { - for (fi = min;; fi++) - { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); - if (!match_ref(offset, eptr, length, md, ims)) + if (slength == -2 && md->partial != 0 && + md->end_subject > md->start_used_ptr) { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - eptr += length; + break; } - /* Control never gets here */ + eptr += slength; } - /* If maximizing, find the longest string and work backwards */ - - else + while (eptr >= pp) { - pp = eptr; - for (i = min; i < max; i++) - { - if (!match_ref(offset, eptr, length, md, ims)) - { - CHECK_PARTIAL(); - break; - } - eptr += length; - } - while (eptr >= pp) - { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr -= length; - } - MRRETURN(MATCH_NOMATCH); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM15); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr -= length; } + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -2390,8 +2821,11 @@ for (;;) case OP_NCLASS: case OP_CLASS: { + /* The data variable is saved across frames, so the byte map needs to + be stored there. */ +#define BYTE_MAP ((pcre_uint8 *)data) data = ecode + 1; /* Save for matching */ - ecode += 33; /* Advance past the item */ + ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */ switch (*ecode) { @@ -2412,9 +2846,9 @@ for (;;) case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); - max = GET2(ecode, 3); + max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; - ecode += 5; + ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ @@ -2424,41 +2858,45 @@ for (;;) /* First, ensure the minimum number of matches are present. */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { - if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH); + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - { - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } c = *eptr++; - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } @@ -2472,47 +2910,51 @@ for (;;) if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM16); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { - if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH); + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - { - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM17); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } c = *eptr++; - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2524,9 +2966,8 @@ for (;;) { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (i = min; i < max; i++) { @@ -2542,14 +2983,12 @@ for (;;) if (op == OP_CLASS) break; } else - { - if ((data[c/8] & (1 << (c&7))) == 0) break; - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr += len; } for (;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM18); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -2557,7 +2996,7 @@ for (;;) } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -2567,19 +3006,27 @@ for (;;) break; } c = *eptr; - if ((data[c/8] & (1 << (c&7))) == 0) break; +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) break; + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr++; } while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM19); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } +#undef BYTE_MAP } /* Control never gets here */ @@ -2588,7 +3035,7 @@ for (;;) when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 mode, because Unicode properties are supported in non-UTF-8 mode. */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: { data = ecode + 1 + LINK_SIZE; /* Save for matching */ @@ -2613,9 +3060,9 @@ for (;;) case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); - max = GET2(ecode, 3); + max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; - ecode += 5; + ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ @@ -2630,10 +3077,10 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the @@ -2648,16 +3095,16 @@ for (;;) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -2675,18 +3122,24 @@ for (;;) SCHECK_PARTIAL(); break; } +#ifdef SUPPORT_UTF GETCHARLENTEST(c, eptr, len); - if (!_pcre_xclass(c, data)) break; +#else + c = *eptr; +#endif + if (!PRIV(xclass)(c, data, utf)) break; eptr += len; } for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ - if (utf8) BACKCHAR(eptr); +#ifdef SUPPORT_UTF + if (utf) BACKCHAR(eptr); +#endif } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -2696,8 +3149,8 @@ for (;;) /* Match a single character, casefully */ case OP_CHAR: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { length = 1; ecode++; @@ -2705,50 +3158,57 @@ for (;;) if (length > md->end_subject - eptr) { CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH); + while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif - - /* Non-UTF-8 mode */ + /* Not UTF mode */ { if (md->end_subject - eptr < 1) { SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH); + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; - /* Match a single character, caselessly */ + /* Match a single character, caselessly. If we are at the end of the + subject, give up immediately. */ - case OP_CHARNC: -#ifdef SUPPORT_UTF8 - if (utf8) + case OP_CHARI: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + +#ifdef SUPPORT_UTF + if (utf) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); - if (length > md->end_subject - eptr) - { - CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); - } - /* If the pattern character's value is < 128, we have only one byte, and - can use the fast lookup table. */ + we know that its other case must also be one byte long, so we can use the + fast lookup table. We know that there is at least one byte left in the + subject. */ if (fc < 128) { - if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (md->lcc[fc] + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + ecode++; + eptr++; } - /* Otherwise we must pick up the subject character */ + /* Otherwise we must pick up the subject character. Note that we cannot + use the value of "length" to check for sufficient bytes left, because the + other case of the character may have more or fewer bytes. */ else { @@ -2764,21 +3224,18 @@ for (;;) #ifdef SUPPORT_UCP if (dc != UCD_OTHERCASE(fc)) #endif - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } } else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ - /* Non-UTF-8 mode */ + /* Not UTF mode */ { - if (md->end_subject - eptr < 1) - { - SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); - } - if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (TABLE_GET(ecode[1], md->lcc, ecode[1]) + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + eptr++; ecode += 2; } break; @@ -2786,23 +3243,28 @@ for (;;) /* Match a single character repeatedly. */ case OP_EXACT: + case OP_EXACTI: min = max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSUPTO: + case OP_POSUPTOI: possessive = TRUE; /* Fall through */ case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: min = 0; max = GET2(ecode, 1); - minimize = *ecode == OP_MINUPTO; - ecode += 3; + minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; + ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSSTAR: + case OP_POSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -2810,6 +3272,7 @@ for (;;) goto REPEATCHAR; case OP_POSPLUS: + case OP_POSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -2817,6 +3280,7 @@ for (;;) goto REPEATCHAR; case OP_POSQUERY: + case OP_POSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -2824,14 +3288,19 @@ for (;;) goto REPEATCHAR; case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: - c = *ecode++ - OP_STAR; + case OP_MINQUERYI: + c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI); minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; @@ -2839,8 +3308,8 @@ for (;;) /* Common code for all repeated single-character matches. */ REPEATCHAR: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { length = 1; charptr = ecode; @@ -2854,25 +3323,25 @@ for (;;) { #ifdef SUPPORT_UCP unsigned int othercase; - if ((ims & PCRE_CASELESS) != 0 && + if (op >= OP_STARI && /* Caseless */ (othercase = UCD_OTHERCASE(fc)) != fc) - oclength = _pcre_ord2utf8(othercase, occhars); + oclength = PRIV(ord2utf)(othercase, occhars); else oclength = 0; #endif /* SUPPORT_UCP */ for (i = 1; i <= min; i++) { if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } @@ -2882,20 +3351,20 @@ for (;;) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM22); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2907,11 +3376,11 @@ for (;;) for (i = min; i < max; i++) { if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { @@ -2924,9 +3393,9 @@ for (;;) for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM23); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr == pp) { MRRETURN(MATCH_NOMATCH); } + if (eptr == pp) { RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UCP eptr--; BACKCHAR(eptr); @@ -2943,14 +3412,12 @@ for (;;) value of fc will always be < 128. */ } else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ + /* When not in UTF-8 mode, load a single-byte character. */ + fc = *ecode++; - /* When not in UTF-8 mode, load a single-byte character. */ - - fc = *ecode++; - - /* The value of fc at this point is always less than 256, though we may or - may not be in UTF-8 mode. The code is duplicated for the caseless and + /* The value of fc at this point is always one character, though we may + or may not be in UTF mode. The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if @@ -2959,34 +3426,52 @@ for (;;) maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, - max, eptr)); + max, (char *)eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_STARI) /* Caseless */ { - fc = md->lcc[fc]; +#ifdef COMPILE_PCRE8 + /* fc must be < 128 if UTF is enabled. */ + foc = md->fcc[fc]; +#else +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); +#else + if (utf && fc > 127) + foc = fc; +#endif /* SUPPORT_UCP */ + else +#endif /* SUPPORT_UTF */ + foc = TABLE_GET(fc, md->fcc, fc); +#endif /* COMPILE_PCRE8 */ + for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } /* Control never gets here */ } @@ -3000,7 +3485,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if (fc != md->lcc[*eptr]) break; + if (fc != *eptr && foc != *eptr) break; eptr++; } @@ -3008,11 +3493,11 @@ for (;;) while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM25); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3026,9 +3511,9 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; @@ -3037,15 +3522,15 @@ for (;;) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM26); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3066,11 +3551,11 @@ for (;;) while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM27); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3079,24 +3564,47 @@ for (;;) checking can be multibyte. */ case OP_NOT: + case OP_NOTI: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - ecode++; - GETCHARINCTEST(c, eptr); - if ((ims & PCRE_CASELESS) != 0) +#ifdef SUPPORT_UTF + if (utf) { -#ifdef SUPPORT_UTF8 - if (c < 256) -#endif - c = md->lcc[c]; - if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH); + register unsigned int ch, och; + + ecode++; + GETCHARINC(ch, ecode); + GETCHARINC(c, eptr); + + if (op == OP_NOT) + { + if (ch == c) RRETURN(MATCH_NOMATCH); + } + else + { +#ifdef SUPPORT_UCP + if (ch > 127) + och = UCD_OTHERCASE(ch); +#else + if (ch > 127) + och = ch; +#endif /* SUPPORT_UCP */ + else + och = TABLE_GET(ch, md->fcc, ch); + if (ch == c || och == c) RRETURN(MATCH_NOMATCH); + } } else +#endif { - if (*ecode++ == c) MRRETURN(MATCH_NOMATCH); + register unsigned int ch = ecode[1]; + c = *eptr++; + if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) + RRETURN(MATCH_NOMATCH); + ecode += 2; } break; @@ -3108,19 +3616,23 @@ for (;;) about... */ case OP_NOTEXACT: + case OP_NOTEXACTI: min = max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: min = 0; max = GET2(ecode, 1); - minimize = *ecode == OP_NOTMINUPTO; - ecode += 3; + minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -3128,6 +3640,7 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -3135,6 +3648,7 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -3142,19 +3656,26 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: possessive = TRUE; min = 0; max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTSTAR: + case OP_NOTSTARI: case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_NOTMINQUERY: - c = *ecode++ - OP_NOTSTAR; + case OP_NOTMINQUERYI: + c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR); minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ @@ -3163,7 +3684,7 @@ for (;;) /* Common code for all repeated single-byte matches. */ REPEATNOTCHAR: - fc = *ecode++; + GETCHARINCTEST(fc, ecode); /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the @@ -3174,15 +3695,24 @@ for (;;) characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, - max, eptr)); + max, (char *)eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_NOTSTARI) /* Caseless */ { - fc = md->lcc[fc]; +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); +#else + if (utf && fc > 127) + foc = fc; +#endif /* SUPPORT_UCP */ + else +#endif /* SUPPORT_UTF */ + foc = TABLE_GET(fc, md->fcc, fc); -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = 1; i <= min; i++) @@ -3190,26 +3720,25 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (d < 256) d = md->lcc[d]; - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif - - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } } @@ -3217,41 +3746,40 @@ for (;;) if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM28); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (d < 256) d = md->lcc[d]; - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM29); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } } /* Control never gets here */ @@ -3263,9 +3791,8 @@ for (;;) { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = min; i < max; i++) @@ -3277,14 +3804,13 @@ for (;;) break; } GETCHARLEN(d, eptr, len); - if (d < 256) d = md->lcc[d]; - if (fc == d) break; + if (fc == d || (unsigned int)foc == d) break; eptr += len; } - if (possessive) continue; - for(;;) + if (possessive) continue; + for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -3292,7 +3818,7 @@ for (;;) } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -3301,19 +3827,19 @@ for (;;) SCHECK_PARTIAL(); break; } - if (fc == md->lcc[*eptr]) break; + if (fc == *eptr || foc == *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM31); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3322,9 +3848,8 @@ for (;;) else { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = 1; i <= min; i++) @@ -3332,24 +3857,24 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } @@ -3357,40 +3882,39 @@ for (;;) if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM32); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM33); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3402,9 +3926,8 @@ for (;;) { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = min; i < max; i++) @@ -3422,7 +3945,7 @@ for (;;) if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM34); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -3430,7 +3953,7 @@ for (;;) } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -3445,13 +3968,13 @@ for (;;) if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM35); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3463,7 +3986,7 @@ for (;;) case OP_TYPEEXACT: min = max = GET2(ecode, 1); minimize = TRUE; - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEUPTO: @@ -3471,7 +3994,7 @@ for (;;) min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_TYPEMINUPTO; - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEPOSSTAR: @@ -3499,7 +4022,7 @@ for (;;) possessive = TRUE; min = 0; max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPESTAR: @@ -3545,13 +4068,13 @@ for (;;) switch(prop_type) { case PT_ANY: - if (prop_fail_result) MRRETURN(MATCH_NOMATCH); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); } @@ -3560,17 +4083,18 @@ for (;;) case PT_LAMP: for (i = 1; i <= min; i++) { + int chartype; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3580,12 +4104,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3595,12 +4118,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3610,28 +4132,27 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; case PT_ALNUM: for (i = 1; i <= min; i++) { + int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3641,14 +4162,13 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3658,31 +4178,30 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case PT_WORD: for (i = 1; i <= min; i++) { + int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N || - c == CHAR_UNDERSCORE) + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3703,20 +4222,18 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; - if (!utf8) c = *eptr; - else { GETCHARLEN(c, eptr, len); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } } @@ -3725,8 +4242,8 @@ for (;;) /* Handle all other cases when the coding is UTF-8 */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(ctype) +#ifdef SUPPORT_UTF + if (utf) switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) @@ -3734,11 +4251,20 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3748,15 +4274,15 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_ANYBYTE: - if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH); + if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH); eptr += min; break; @@ -3766,12 +4292,13 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -3784,7 +4311,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -3796,7 +4323,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3821,7 +4348,7 @@ for (;;) case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3832,12 +4359,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -3868,7 +4395,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3881,7 +4408,7 @@ for (;;) case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3892,12 +4419,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -3916,11 +4443,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3930,10 +4457,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3944,11 +4472,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) - MRRETURN(MATCH_NOMATCH); - while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3958,10 +4487,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3972,11 +4502,12 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); - while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3986,10 +4517,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3999,7 +4531,7 @@ for (;;) } /* End switch(ctype) */ else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* Code for the non-UTF-8 case for minimum matching of operators other than OP_PROP and OP_NOTPROP. */ @@ -4012,9 +4544,18 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); eptr++; } break; @@ -4023,7 +4564,7 @@ for (;;) if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4032,7 +4573,7 @@ for (;;) if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4043,21 +4584,27 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; + case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -4069,7 +4616,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4077,7 +4624,25 @@ for (;;) case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif + RRETURN(MATCH_NOMATCH); } } break; @@ -4088,14 +4653,32 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif break; } } @@ -4107,7 +4690,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4117,7 +4700,11 @@ for (;;) case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif + RRETURN(MATCH_NOMATCH); } } break; @@ -4128,16 +4715,20 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif break; } } @@ -4149,9 +4740,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4161,9 +4754,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4173,9 +4768,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4185,9 +4782,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4197,10 +4796,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4210,10 +4810,11 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4240,170 +4841,167 @@ for (;;) case PT_ANY: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM36); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (prop_fail_result) MRRETURN(MATCH_NOMATCH); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_LAMP: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37); + int chartype; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM37); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_GC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM38); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM39); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM40); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_ALNUM: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59); + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM59); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SPACE: /* Perl space */ for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM60); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PXSPACE: /* POSIX space */ for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM61); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_WORD: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62); + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM62); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || - prop_category == ucp_N || + category = UCD_CATEGORY(c); + if ((category == ucp_L || + category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -4421,52 +5019,59 @@ for (;;) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM41); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; - if (!utf8) c = *eptr; - else { GETCHARLEN(c, eptr, len); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } } - else #endif /* SUPPORT_UCP */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM42); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(ctype) { - case OP_ANY: /* This is the non-NL case */ + case OP_ANY: /* This is the non-NL case */ + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + break; + case OP_ALLANY: case OP_ANYBYTE: break; @@ -4474,7 +5079,7 @@ for (;;) case OP_ANYNL: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -4486,7 +5091,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4514,14 +5119,14 @@ for (;;) case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -4556,14 +5161,14 @@ for (;;) case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -4577,32 +5182,32 @@ for (;;) case OP_NOT_DIGIT: if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (c < 256 && (md->ctypes[c] & ctype_space) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: - if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) - MRRETURN(MATCH_NOMATCH); + if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (c < 256 && (md->ctypes[c] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; default: @@ -4612,24 +5217,35 @@ for (;;) } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM43); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); c = *eptr++; switch(ctype) { - case OP_ANY: /* This is the non-NL case */ + case OP_ANY: /* This is the non-NL case */ + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + break; + case OP_ALLANY: case OP_ANYBYTE: break; @@ -4637,7 +5253,7 @@ for (;;) case OP_ANYNL: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -4648,7 +5264,11 @@ for (;;) case 0x000b: case 0x000c: case 0x0085: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4660,17 +5280,53 @@ for (;;) case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif + RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif break; } break; @@ -4684,45 +5340,53 @@ for (;;) case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif + RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif break; } break; case OP_NOT_DIGIT: - if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: - if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: - if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: - if ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: - if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: - if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: @@ -4764,6 +5428,7 @@ for (;;) case PT_LAMP: for (i = min; i < max; i++) { + int chartype; int len = 1; if (eptr >= md->end_subject) { @@ -4771,10 +5436,10 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) break; eptr+= len; } @@ -4790,9 +5455,7 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - break; + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4807,9 +5470,7 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - break; + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4824,9 +5485,7 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - break; + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4834,6 +5493,7 @@ for (;;) case PT_ALNUM: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4841,9 +5501,8 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) break; eptr+= len; } @@ -4859,8 +5518,7 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; @@ -4878,8 +5536,7 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; @@ -4890,6 +5547,7 @@ for (;;) case PT_WORD: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4897,8 +5555,8 @@ for (;;) break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N || + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) break; eptr+= len; @@ -4914,10 +5572,10 @@ for (;;) if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ - if (utf8) BACKCHAR(eptr); + if (utf) BACKCHAR(eptr); } } @@ -4928,25 +5586,23 @@ for (;;) { for (i = min; i < max; i++) { + int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } - GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) == ucp_M) break; + eptr += len; while (eptr < md->end_subject) { - int len = 1; - if (!utf8) c = *eptr; else - { - GETCHARLEN(c, eptr, len); - } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } /* eptr is now past the end of the maximum run */ @@ -4955,19 +5611,17 @@ for (;;) for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM45); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ for (;;) /* Move back over one extended */ { - int len = 1; - if (!utf8) c = *eptr; else + if (!utf) c = *eptr; else { BACKCHAR(eptr); - GETCHARLEN(c, eptr, len); + GETCHAR(c, eptr); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (UCD_CATEGORY(c) != ucp_M) break; eptr--; } } @@ -4976,10 +5630,8 @@ for (;;) else #endif /* SUPPORT_UCP */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { switch(ctype) { @@ -4994,8 +5646,17 @@ for (;;) break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } @@ -5011,8 +5672,17 @@ for (;;) break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } break; @@ -5028,10 +5698,14 @@ for (;;) break; } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } - else eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + else + { + eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + SCHECK_PARTIAL(); + } break; /* The byte case is the same as non-UTF8 */ @@ -5239,21 +5913,26 @@ for (;;) RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run */ + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character, unless we are matching \R and the last thing matched was + \r\n, in which case, back up two bytes. */ if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM46); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } else -#endif /* SUPPORT_UTF8 */ - - /* Not UTF-8 mode */ +#endif /* SUPPORT_UTF */ + /* Not UTF mode */ { switch(ctype) { @@ -5266,6 +5945,15 @@ for (;;) break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; } break; @@ -5297,10 +5985,12 @@ for (;;) } else { - if (c != 0x000a && - (md->bsr_anycrlf || - (c != 0x000b && c != 0x000c && c != 0x0085))) - break; + if (c != 0x000a && (md->bsr_anycrlf || + (c != 0x000b && c != 0x000c && c != 0x0085 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 +#endif + ))) break; eptr++; } } @@ -5315,7 +6005,12 @@ for (;;) break; } c = *eptr; - if (c == 0x09 || c == 0x20 || c == 0xa0) break; + if (c == 0x09 || c == 0x20 || c == 0xa0 +#ifdef COMPILE_PCRE16 + || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A) + || c == 0x202f || c == 0x205f || c == 0x3000 +#endif + ) break; eptr++; } break; @@ -5329,7 +6024,12 @@ for (;;) break; } c = *eptr; - if (c != 0x09 && c != 0x20 && c != 0xa0) break; + if (c != 0x09 && c != 0x20 && c != 0xa0 +#ifdef COMPILE_PCRE16 + && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A) + && c != 0x202f && c != 0x205f && c != 0x3000 +#endif + ) break; eptr++; } break; @@ -5343,8 +6043,11 @@ for (;;) break; } c = *eptr; - if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85) - break; + if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85 +#ifdef COMPILE_PCRE16 + || c == 0x2028 || c == 0x2029 +#endif + ) break; eptr++; } break; @@ -5358,8 +6061,11 @@ for (;;) break; } c = *eptr; - if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85) - break; + if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 +#endif + ) break; eptr++; } break; @@ -5372,7 +6078,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_digit) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break; eptr++; } break; @@ -5385,7 +6091,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_digit) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break; eptr++; } break; @@ -5398,7 +6104,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_space) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break; eptr++; } break; @@ -5411,7 +6117,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_space) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break; eptr++; } break; @@ -5424,7 +6130,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_word) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break; eptr++; } break; @@ -5437,7 +6143,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_word) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break; eptr++; } break; @@ -5446,20 +6152,26 @@ for (;;) RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run */ + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character (byte), unless we are matching \R and the last thing matched + was \r\n, in which case, back up two bytes. */ if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47); - eptr--; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } /* Get here if we can't make it match with any permitted repetitions */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -5492,17 +6204,25 @@ switch (frame->Xwhere) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) - LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) -#ifdef SUPPORT_UTF8 - LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30) + LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) + LBL(65) LBL(66) +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + LBL(21) +#endif +#ifdef SUPPORT_UTF + LBL(16) LBL(18) LBL(20) + LBL(22) LBL(23) LBL(28) LBL(30) LBL(32) LBL(34) LBL(42) LBL(46) #ifdef SUPPORT_UCP LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) LBL(59) LBL(60) LBL(61) LBL(62) #endif /* SUPPORT_UCP */ -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ default: DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); + +printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere); + return PCRE_ERROR_INTERNAL; } #undef LBL @@ -5521,7 +6241,6 @@ Undefine all the macros that were defined above to handle this. */ #undef ecode #undef mstart #undef offset_top -#undef ims #undef eptrb #undef flags @@ -5539,8 +6258,6 @@ Undefine all the macros that were defined above to handle this. */ #undef condition #undef prev_is_word -#undef original_ims - #undef ctype #undef length #undef max @@ -5567,6 +6284,31 @@ Undefine all the macros that were defined above to handle this. */ ***************************************************************************/ +#ifdef NO_RECURSE +/************************************************* +* Release allocated heap frames * +*************************************************/ + +/* This function releases all the allocated frames. The base frame is on the +machine stack, and so must not be freed. + +Argument: the address of the base frame +Returns: nothing +*/ + +static void +release_match_heapframes (heapframe *frame_base) +{ +heapframe *nextframe = frame_base->Xnextframe; +while (nextframe != NULL) + { + heapframe *oldframe = nextframe; + nextframe = nextframe->Xnextframe; + (PUBL(stack_free))(oldframe); + } +} +#endif + /************************************************* * Execute a Regular Expression * @@ -5592,52 +6334,150 @@ Returns: > 0 => success; value is the number of elements filled in < -1 => some kind of unexpected problem */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, int offsetcount) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, + PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, + int offsetcount) +#endif { -int rc, resetcount, ocount; -int first_byte = -1; -int req_byte = -1; -int req_byte2 = -1; +int rc, ocount, arg_offset_max; int newline; -unsigned long int ims; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; BOOL firstline; -BOOL first_byte_caseless = FALSE; -BOOL req_byte_caseless = FALSE; -BOOL utf8; +BOOL utf; +BOOL has_first_char = FALSE; +BOOL has_req_char = FALSE; +pcre_uchar first_char = 0; +pcre_uchar first_char2 = 0; +pcre_uchar req_char = 0; +pcre_uchar req_char2 = 0; match_data match_block; match_data *md = &match_block; -const uschar *tables; -const uschar *start_bits = NULL; -USPTR start_match = (USPTR)subject + start_offset; -USPTR end_subject; -USPTR start_partial = NULL; -USPTR req_byte_ptr = start_match - 1; +const pcre_uint8 *tables; +const pcre_uint8 *start_bits = NULL; +PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset; +PCRE_PUCHAR end_subject; +PCRE_PUCHAR start_partial = NULL; +PCRE_PUCHAR req_char_ptr = start_match - 1; -pcre_study_data internal_study; const pcre_study_data *study; +const REAL_PCRE *re = (const REAL_PCRE *)argument_re; -real_pcre internal_re; -const real_pcre *external_re = (const real_pcre *)argument_re; -const real_pcre *re = external_re; +#ifdef NO_RECURSE +heapframe frame_zero; +frame_zero.Xprevframe = NULL; /* Marks the top level */ +frame_zero.Xnextframe = NULL; /* None are allocated yet */ +md->match_frames_base = &frame_zero; +#endif + +/* Check for the special magic call that measures the size of the stack used +per recursive call of match(). Without the funny casting for sizeof, a Windows +compiler gave this error: "unary minus operator applied to unsigned type, +result still unsigned". Hopefully the cast fixes that. */ + +if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && + start_offset == -999) +#ifdef NO_RECURSE + return -((int)sizeof(heapframe)); +#else + return match(NULL, NULL, NULL, 0, NULL, NULL, 0); +#endif /* Plausibility checks */ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; -if (re == NULL || subject == NULL || - (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; +if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) + return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; -/* This information is for finding all the numbers associated with a given -name, for condition testing. */ +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ -md->name_table = (uschar *)re + re->name_table_offset; +if (re->magic_number != MAGIC_NUMBER) + return re->magic_number == REVERSED_MAGIC_NUMBER? + PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + +/* These two settings are used in the code for checking a UTF-8 string that +follows immediately afterwards. Other values in the md block are used only +during "normal" pcre_exec() processing, not when the JIT support is in use, +so they are set up later. */ + +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = md->utf = (re->options & PCRE_UTF8) != 0; +md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : + ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; + +/* Check a UTF-8 string if required. Pass back the character offset and error +code for an invalid string if a results vector is available. */ + +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) + { + int erroroffset; + int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset); + if (errorcode != 0) + { + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } +#ifdef COMPILE_PCRE16 + return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? + PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; +#else + return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; +#endif + } + + /* Check that a start_offset points to the start of a UTF character. */ + if (start_offset > 0 && start_offset < length && + NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) + return PCRE_ERROR_BADUTF8_OFFSET; + } +#endif + +/* If the pattern was successfully studied with JIT support, run the JIT +executable instead of the rest of this function. Most options must be set at +compile time for the JIT code to be usable. Fallback to the normal code path if +an unsupported flag is set. */ + +#ifdef SUPPORT_JIT +if (extra_data != NULL + && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | + PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT + && extra_data->executable_jit != NULL + && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | + PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | + PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) + { + rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, + start_offset, options, offsets, offsetcount); + + /* PCRE_ERROR_NULL means that the selected normal or partial matching + mode is not compiled. In this case we simply fallback to interpreter. */ + + if (rc != PCRE_ERROR_NULL) return rc; + } +#endif + +/* Carry on with non-JIT matching. This information is for finding all the +numbers associated with a given name, for condition testing. */ + +md->name_table = (pcre_uchar *)re + re->name_table_offset; md->name_count = re->name_count; md->name_entry_size = re->name_entry_size; @@ -5651,7 +6491,7 @@ md->callout_data = NULL; /* The table pointer is always in native byte order. */ -tables = external_re->tables; +tables = re->tables; if (extra_data != NULL) { @@ -5671,19 +6511,7 @@ if (extra_data != NULL) is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ -if (tables == NULL) tables = _pcre_default_tables; - -/* Check that the first field in the block is the magic number. If it is not, -test for a regex that was compiled on a host of opposite endianness. If this is -the case, flipped values are put in internal_re and internal_study if there was -study data too. */ - -if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, study, &internal_study); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - if (study != NULL) study = &internal_study; - } +if (tables == NULL) tables = PRIV(default_tables); /* Set up other data */ @@ -5693,31 +6521,35 @@ firstline = (re->options & PCRE_FIRSTLINE) != 0; /* The code starts after the real_pcre block and the capture name table. */ -md->start_code = (const uschar *)external_re + re->name_table_offset + +md->start_code = (const pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; -md->start_subject = (USPTR)subject; +md->start_subject = (PCRE_PUCHAR)subject; md->start_offset = start_offset; md->end_subject = md->start_subject + length; end_subject = md->end_subject; md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; -utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0; md->use_ucp = (re->options & PCRE_UCP) != 0; md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; +md->ignore_skip_arg = FALSE; + +/* Some options are unpacked into BOOL variables in the hope that testing +them will be faster than individual option bits. */ md->notbol = (options & PCRE_NOTBOL) != 0; md->noteol = (options & PCRE_NOTEOL) != 0; md->notempty = (options & PCRE_NOTEMPTY) != 0; md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; -md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : - ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; + md->hitend = FALSE; -md->mark = NULL; /* In case never set */ +md->mark = md->nomatch_mark = NULL; /* In case never set */ md->recursive = NULL; /* No recursion at top level */ +md->hasthen = (re->flags & PCRE_HASTHEN) != 0; md->lcc = tables + lcc_offset; +md->fcc = tables + fcc_offset; md->ctypes = tables + ctypes_offset; /* Handle different \R options. */ @@ -5793,41 +6625,18 @@ defined (though never set). So there's no harm in leaving this code. */ if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0) return PCRE_ERROR_BADPARTIAL; -/* Check a UTF-8 string if required. Unfortunately there's no way of passing -back the character offset. */ - -#ifdef SUPPORT_UTF8 -if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) - { - int tb; - if ((tb = _pcre_valid_utf8((USPTR)subject, length)) >= 0) - return (tb == length && md->partial > 1)? - PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; - if (start_offset > 0 && start_offset < length) - { - tb = ((USPTR)subject)[start_offset] & 0xc0; - if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET; - } - } -#endif - -/* The ims options can vary during the matching as a result of the presence -of (?ims) items in the pattern. They are kept in a local variable so that -restoring at the exit of a group is easy. */ - -ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); - /* If the expression has got more back references than the offsets supplied can hold, we get a temporary chunk of working store to use during the matching. Otherwise, we can use the vector supplied, rounding down its size to a multiple of 3. */ ocount = offsetcount - (offsetcount % 3); +arg_offset_max = (2*ocount)/3; if (re->top_backref > 0 && re->top_backref >= ocount/3) { ocount = re->top_backref * 3 + 3; - md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); + md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int)); if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY; using_temporary_offsets = TRUE; DPRINTF(("Got memory to hold back references\n")); @@ -5839,25 +6648,22 @@ md->offset_max = (2*ocount)/3; md->offset_overflow = FALSE; md->capture_last = -1; -/* Compute the minimum number of offsets that we need to reset each time. Doing -this makes a huge difference to execution time when there aren't many brackets -in the pattern. */ - -resetcount = 2 + re->top_bracket * 2; -if (resetcount > offsetcount) resetcount = ocount; - /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we -initialize them to avoid reading uninitialized locations. */ +initialize them to avoid reading uninitialized locations. Also, unset the +offsets for the matched string. This is really just for tidiness with callouts, +in case they inspect these fields. */ if (md->offset_vector != NULL) { register int *iptr = md->offset_vector + ocount; - register int *iend = iptr - resetcount/2 + 1; + register int *iend = iptr - re->top_bracket; + if (iend < md->offset_vector + 2) iend = md->offset_vector + 2; while (--iptr >= iend) *iptr = -1; + md->offset_vector[0] = md->offset_vector[1] = -1; } -/* Set up the first character to match, if available. The first_byte value is +/* Set up the first character to match, if available. The first_char value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was @@ -5867,9 +6673,16 @@ if (!anchored) { if ((re->flags & PCRE_FIRSTSET) != 0) { - first_byte = re->first_byte & 255; - if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) - first_byte = md->lcc[first_byte]; + has_first_char = TRUE; + first_char = first_char2 = (pcre_uchar)(re->first_char); + if ((re->flags & PCRE_FCH_CASELESS) != 0) + { + first_char2 = TABLE_GET(first_char, md->fcc, first_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && first_char > 127) + first_char2 = UCD_OTHERCASE(first_char); +#endif + } } else if (!startline && study != NULL && @@ -5882,9 +6695,16 @@ character" set. */ if ((re->flags & PCRE_REQCHSET) != 0) { - req_byte = re->req_byte & 255; - req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; - req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ + has_req_char = TRUE; + req_char = req_char2 = (pcre_uchar)(re->req_char); + if ((re->flags & PCRE_RCH_CASELESS) != 0) + { + req_char2 = TABLE_GET(req_char, md->fcc, req_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && req_char > 127) + req_char2 = UCD_OTHERCASE(req_char); +#endif + } } @@ -5895,17 +6715,8 @@ the loop runs just once. */ for(;;) { - USPTR save_end_subject = end_subject; - USPTR new_start_match; - - /* Reset the maximum number of extractions we might see. */ - - if (md->offset_vector != NULL) - { - register int *iptr = md->offset_vector; - register int *iend = iptr + resetcount; - while (iptr < iend) *iptr++ = -1; - } + PCRE_PUCHAR save_end_subject = end_subject; + PCRE_PUCHAR new_start_match; /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the first @@ -5915,14 +6726,14 @@ for(;;) if (firstline) { - USPTR t = start_match; -#ifdef SUPPORT_UTF8 - if (utf8) + PCRE_PUCHAR t = start_match; +#ifdef SUPPORT_UTF + if (utf) { while (t < md->end_subject && !IS_NEWLINE(t)) { t++; - while (t < end_subject && (*t & 0xc0) == 0x80) t++; + ACROSSCHAR(t < end_subject, *t, t++); } } else @@ -5939,15 +6750,16 @@ for(;;) if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { - /* Advance to a unique first byte if there is one. */ + /* Advance to a unique first char if there is one. */ - if (first_byte >= 0) + if (has_first_char) { - if (first_byte_caseless) - while (start_match < end_subject && md->lcc[*start_match] != first_byte) + if (first_char != first_char2) + while (start_match < end_subject && + *start_match != first_char && *start_match != first_char2) start_match++; else - while (start_match < end_subject && *start_match != first_byte) + while (start_match < end_subject && *start_match != first_char) start_match++; } @@ -5957,14 +6769,14 @@ for(;;) { if (start_match > md->start_subject + start_offset) { -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { while (start_match < end_subject && !WAS_NEWLINE(start_match)) { start_match++; - while(start_match < end_subject && (*start_match & 0xc0) == 0x80) - start_match++; + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); } } else @@ -5991,13 +6803,18 @@ for(;;) while (start_match < end_subject) { register unsigned int c = *start_match; +#ifndef COMPILE_PCRE8 + if (c > 255) c = 255; +#endif if ((start_bits[c/8] & (1 << (c&7))) == 0) { start_match++; -#ifdef SUPPORT_UTF8 - if (utf8) - while(start_match < end_subject && (*start_match & 0xc0) == 0x80) - start_match++; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + /* In non 8-bit mode, the iteration will stop for + characters > 255 at the beginning or not stop at all. */ + if (utf) + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); #endif } else break; @@ -6012,7 +6829,7 @@ for(;;) /* The following two optimizations are disabled for partial matching or if disabling is explicitly requested. */ - if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial) + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial) { /* If the pattern was studied, a minimum subject length may be set. This is a lower bound; no actual string of that length may actually match the @@ -6026,8 +6843,8 @@ for(;;) break; } - /* If req_byte is set, we know that that character must appear in the - subject for the match to succeed. If the first character is set, req_byte + /* If req_char is set, we know that that character must appear in the + subject for the match to succeed. If the first character is set, req_char must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code @@ -6040,28 +6857,28 @@ for(;;) 32-megabyte string... so we don't do this when the string is sufficiently long. */ - if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX) + if (has_req_char && end_subject - start_match < REQ_BYTE_MAX) { - register USPTR p = start_match + ((first_byte >= 0)? 1 : 0); + register PCRE_PUCHAR p = start_match + (has_first_char? 1:0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ - if (p > req_byte_ptr) + if (p > req_char_ptr) { - if (req_byte_caseless) + if (req_char != req_char2) { while (p < end_subject) { register int pp = *p++; - if (pp == req_byte || pp == req_byte2) { p--; break; } + if (pp == req_char || pp == req_char2) { p--; break; } } } else { while (p < end_subject) { - if (*p++ == req_byte) { p--; break; } + if (*p++ == req_char) { p--; break; } } } @@ -6078,7 +6895,7 @@ for(;;) found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ - req_byte_ptr = p; + req_char_ptr = p; } } } @@ -6095,12 +6912,25 @@ for(;;) md->start_match_ptr = start_match; md->start_used_ptr = start_match; md->match_call_count = 0; - rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL, - 0, 0); + md->match_function_type = 0; + md->end_offset_top = 0; + rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0); if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr; switch(rc) { + /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched + the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP + entirely. The only way we can do that is to re-do the match at the same + point, with a flag to force SKIP with an argument to be ignored. Just + treating this case as NOMATCH does not work because it does not check other + alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */ + + case MATCH_SKIP_ARG: + new_start_match = start_match; + md->ignore_skip_arg = TRUE; + break; + /* SKIP passes back the next starting point explicitly, but if it is the same as the match we have just done, treat it as NOMATCH. */ @@ -6112,23 +6942,18 @@ for(;;) } /* Fall through */ - /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched - the SKIP's arg was not found. We also treat this as NOMATCH. */ - - case MATCH_SKIP_ARG: - /* Fall through */ - /* NOMATCH and PRUNE advance by one character. THEN at this level acts - exactly like PRUNE. */ + exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */ case MATCH_NOMATCH: case MATCH_PRUNE: case MATCH_THEN: + md->ignore_skip_arg = FALSE; new_start_match = start_match + 1; -#ifdef SUPPORT_UTF8 - if (utf8) - while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80) - new_start_match++; +#ifdef SUPPORT_UTF + if (utf) + ACROSSCHAR(new_start_match < end_subject, *new_start_match, + new_start_match++); #endif break; @@ -6166,9 +6991,13 @@ for(;;) /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF - or ANY or ANYCRLF, advance the match position by one more character. */ + or ANY or ANYCRLF, advance the match position by one more character. In + normal matching start_match will aways be greater than the first position at + this stage, but a failed *SKIP can cause a return at the same point, which is + why the first test exists. */ - if (start_match[-1] == CHAR_CR && + if (start_match > (PCRE_PUCHAR)subject + start_offset && + start_match[-1] == CHAR_CR && start_match < end_subject && *start_match == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && @@ -6206,21 +7035,41 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) { if (using_temporary_offsets) { - if (offsetcount >= 4) + if (arg_offset_max >= 4) { memcpy(offsets + 2, md->offset_vector + 2, - (offsetcount - 2) * sizeof(int)); + (arg_offset_max - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } - if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE; + if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; DPRINTF(("Freeing temporary memory\n")); - (pcre_free)(md->offset_vector); + (PUBL(free))(md->offset_vector); } - /* Set the return code to the number of captured strings, or 0 if there are + /* Set the return code to the number of captured strings, or 0 if there were too many to fit into the vector. */ - rc = md->offset_overflow? 0 : md->end_offset_top/2; + rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)? + 0 : md->end_offset_top/2; + + /* If there is space in the offset vector, set any unused pairs at the end of + the pattern to -1 for backwards compatibility. It is documented that this + happens. In earlier versions, the whole set of potential capturing offsets + was set to -1 each time round the loop, but this is handled differently now. + "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only + those at the end that need unsetting here. We can't just unset them all at + the start of the whole thing because they may get set in one branch that is + not the final matching branch. */ + + if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL) + { + register int *iptr, *iend; + int resetcount = 2 + re->top_bracket * 2; + if (resetcount > offsetcount) resetcount = offsetcount; + iptr = offsets + md->end_offset_top; + iend = offsets + resetcount; + while (iptr < iend) *iptr++ = -1; + } /* If there is space, set up the whole thing as substring 0. The value of md->start_match_ptr might be modified if \K was encountered on the success @@ -6232,8 +7081,15 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) offsets[1] = (int)(md->end_match_ptr - md->start_subject); } + /* Return MARK data if requested */ + + if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) + *(extra_data->mark) = (pcre_uchar *)md->mark; DPRINTF((">>>> returning %d\n", rc)); - goto RETURN_MARK; +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif + return rc; } /* Control gets here if there has been an error, or if the overall match @@ -6242,7 +7098,7 @@ attempt has failed at all permitted starting positions. */ if (using_temporary_offsets) { DPRINTF(("Freeing temporary memory\n")); - (pcre_free)(md->offset_vector); + (PUBL(free))(md->offset_vector); } /* For anything other than nomatch or partial match, just return the code. */ @@ -6250,6 +7106,9 @@ if (using_temporary_offsets) if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) { DPRINTF((">>>> error: returning %d\n", rc)); +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif return rc; } @@ -6261,8 +7120,8 @@ if (start_partial != NULL) md->mark = NULL; if (offsetcount > 1) { - offsets[0] = (int)(start_partial - (USPTR)subject); - offsets[1] = (int)(end_subject - (USPTR)subject); + offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); + offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); } rc = PCRE_ERROR_PARTIAL; } @@ -6277,10 +7136,11 @@ else /* Return the MARK data if it has been requested. */ -RETURN_MARK: - if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) - *(extra_data->mark) = (unsigned char *)(md->mark); + *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif return rc; } diff --git a/ext/pcre/pcrelib/pcre_fullinfo.c b/ext/pcre/pcrelib/pcre_fullinfo.c index 6725ad7ba55..2fe785a1364 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-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -63,13 +63,17 @@ Arguments: Returns: 0 if data returned, negative on error */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, - void *where) +pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, + int what, void *where) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, + int what, void *where) +#endif { -real_pcre internal_re; -pcre_study_data internal_study; -const real_pcre *re = (const real_pcre *)argument_re; +const REAL_PCRE *re = (const REAL_PCRE *)argument_re; const pcre_study_data *study = NULL; if (re == NULL || where == NULL) return PCRE_ERROR_NULL; @@ -77,12 +81,18 @@ if (re == NULL || where == NULL) return PCRE_ERROR_NULL; if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ + if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, study, &internal_study); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - if (study != NULL) study = &internal_study; - } + return re->magic_number == REVERSED_MAGIC_NUMBER? + PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; + +/* Check that this pattern was compiled in the correct bit mode */ + +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; switch (what) { @@ -98,6 +108,18 @@ switch (what) *((size_t *)where) = (study == NULL)? 0 : study->size; break; + case PCRE_INFO_JITSIZE: +#ifdef SUPPORT_JIT + *((size_t *)where) = + (extra_data != NULL && + (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra_data->executable_jit != NULL)? + PRIV(jit_get_size)(extra_data->executable_jit) : 0; +#else + *((size_t *)where) = 0; +#endif + break; + case PCRE_INFO_CAPTURECOUNT: *((int *)where) = re->top_bracket; break; @@ -108,7 +130,7 @@ switch (what) case PCRE_INFO_FIRSTBYTE: *((int *)where) = - ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte : + ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char : ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; break; @@ -116,7 +138,7 @@ switch (what) block, not the internal copy (with flipped integer fields). */ case PCRE_INFO_FIRSTTABLE: - *((const uschar **)where) = + *((const pcre_uint8 **)where) = (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)? ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; break; @@ -124,12 +146,18 @@ switch (what) case PCRE_INFO_MINLENGTH: *((int *)where) = (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? - study->minlength : -1; + (int)(study->minlength) : -1; + break; + + case PCRE_INFO_JIT: + *((int *)where) = extra_data != NULL && + (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra_data->executable_jit != NULL; break; case PCRE_INFO_LASTLITERAL: *((int *)where) = - ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1; + ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1; break; case PCRE_INFO_NAMEENTRYSIZE: @@ -141,11 +169,11 @@ switch (what) break; case PCRE_INFO_NAMETABLE: - *((const uschar **)where) = (const uschar *)re + re->name_table_offset; + *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset; break; case PCRE_INFO_DEFAULT_TABLES: - *((const uschar **)where) = (const uschar *)(_pcre_default_tables); + *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables)); break; /* From release 8.00 this will always return TRUE because NOPARTIAL is @@ -163,6 +191,10 @@ switch (what) *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0; break; + case PCRE_INFO_MAXLOOKBEHIND: + *((int *)where) = re->max_lookbehind; + break; + default: return PCRE_ERROR_BADOPTION; } diff --git a/ext/pcre/pcrelib/pcre_get.c b/ext/pcre/pcrelib/pcre_get.c index 92b38088202..61147efe8ac 100644 --- a/ext/pcre/pcrelib/pcre_get.c +++ b/ext/pcre/pcrelib/pcre_get.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -63,14 +63,20 @@ Returns: the number of the named parentheses, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringnumber(const pcre *code, const char *stringname) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname) +#endif { int rc; int entrysize; int top, bot; -uschar *nametable; +pcre_uchar *nametable; +#ifdef COMPILE_PCRE8 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; @@ -79,14 +85,26 @@ if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif bot = 0; while (top > bot) { int mid = (top + bot) / 2; - uschar *entry = nametable + entrysize*mid; - int c = strcmp(stringname, (char *)(entry + 2)); - if (c == 0) return (entry[0] << 8) + entry[1]; + pcre_uchar *entry = nametable + entrysize*mid; + int c = STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(entry + IMM2_SIZE)); + if (c == 0) return GET2(entry, 0); if (c > 0) bot = mid + 1; else top = mid; } @@ -112,15 +130,22 @@ Returns: the length of each entry, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringtable_entries(const pcre *code, const char *stringname, char **firstptr, char **lastptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname, + PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr) +#endif { int rc; int entrysize; int top, bot; -uschar *nametable, *lastentry; +pcre_uchar *nametable, *lastentry; +#ifdef COMPILE_PCRE8 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; @@ -129,30 +154,49 @@ if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif lastentry = nametable + entrysize * (top - 1); bot = 0; while (top > bot) { int mid = (top + bot) / 2; - uschar *entry = nametable + entrysize*mid; - int c = strcmp(stringname, (char *)(entry + 2)); + pcre_uchar *entry = nametable + entrysize*mid; + int c = STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(entry + IMM2_SIZE)); if (c == 0) { - uschar *first = entry; - uschar *last = entry; + pcre_uchar *first = entry; + pcre_uchar *last = entry; while (first > nametable) { - if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break; + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break; first -= entrysize; } while (last < lastentry) { - if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break; + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break; last += entrysize; } +#ifdef COMPILE_PCRE8 *firstptr = (char *)first; *lastptr = (char *)last; +#else + *firstptr = (PCRE_UCHAR16 *)first; + *lastptr = (PCRE_UCHAR16 *)last; +#endif return entrysize; } if (c > 0) bot = mid + 1; else top = mid; @@ -180,23 +224,39 @@ Returns: the number of the first that is set, or a negative number on error */ +#ifdef COMPILE_PCRE8 static int get_first_set(const pcre *code, const char *stringname, int *ovector) +#else +static int +get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) +#endif { -const real_pcre *re = (const real_pcre *)code; +const REAL_PCRE *re = (const REAL_PCRE *)code; int entrysize; +pcre_uchar *entry; +#ifdef COMPILE_PCRE8 char *first, *last; -uschar *entry; +#else +PCRE_UCHAR16 *first, *last; +#endif + +#ifdef COMPILE_PCRE8 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre_get_stringnumber(code, stringname); entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); +#else +if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) + return pcre16_get_stringnumber(code, stringname); +entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last); +#endif if (entrysize <= 0) return entrysize; -for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize) +for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) { - int n = (entry[0] << 8) + entry[1]; + int n = GET2(entry, 0); if (ovector[n*2] >= 0) return n; } -return (first[0] << 8) + first[1]; +return GET2(entry, 0); } @@ -229,9 +289,15 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_UCHAR16 *buffer, int size) +#endif { int yield; if (stringnumber < 0 || stringnumber >= stringcount) @@ -239,7 +305,7 @@ if (stringnumber < 0 || stringnumber >= stringcount) stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; if (size < yield + 1) return PCRE_ERROR_NOMEMORY; -memcpy(buffer, subject + ovector[stringnumber], yield); +memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield)); buffer[yield] = 0; return yield; } @@ -274,13 +340,25 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, - int stringcount, const char *stringname, char *buffer, int size) +pcre_copy_named_substring(const pcre *code, const char *subject, + int *ovector, int stringcount, const char *stringname, + char *buffer, int size) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int size) +#endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; +#ifdef COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); +#else +return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size); +#endif } @@ -306,29 +384,39 @@ Returns: if successful: 0 PCRE_ERROR_NOMEMORY (-6) failed to get store */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, + PCRE_SPTR16 **listptr) +#endif { int i; -int size = sizeof(char *); +int size = sizeof(pcre_uchar *); int double_count = stringcount * 2; -char **stringlist; -char *p; +pcre_uchar **stringlist; +pcre_uchar *p; for (i = 0; i < double_count; i += 2) - size += sizeof(char *) + ovector[i+1] - ovector[i] + 1; + size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); -stringlist = (char **)(pcre_malloc)(size); +stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; +#ifdef COMPILE_PCRE8 *listptr = (const char **)stringlist; -p = (char *)(stringlist + stringcount + 1); +#else +*listptr = (PCRE_SPTR16 *)stringlist; +#endif +p = (pcre_uchar *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { int len = ovector[i+1] - ovector[i]; - memcpy(p, subject + ovector[i], len); + memcpy(p, subject + ovector[i], IN_UCHARS(len)); *stringlist++ = p; p += len; *p++ = 0; @@ -345,16 +433,22 @@ return 0; *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C -programs that can call its functions, but not free() or (pcre_free)() directly. +programs that can call its functions, but not free() or (PUBL(free))() +directly. Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring_list(const char **pointer) +#else +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring_list(PCRE_SPTR16 *pointer) +#endif { -(pcre_free)((void *)pointer); +(PUBL(free))((void *)pointer); } @@ -384,21 +478,31 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) substring not present */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_SPTR16 *stringptr) +#endif { int yield; -char *substring; +pcre_uchar *substring; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; -substring = (char *)(pcre_malloc)(yield + 1); +substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1)); if (substring == NULL) return PCRE_ERROR_NOMEMORY; -memcpy(substring, subject + ovector[stringnumber], yield); +memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield)); substring[yield] = 0; -*stringptr = substring; +#ifdef COMPILE_PCRE8 +*stringptr = (const char *)substring; +#else +*stringptr = (PCRE_SPTR16)substring; +#endif return yield; } @@ -431,13 +535,25 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, - int stringcount, const char *stringname, const char **stringptr) +pcre_get_named_substring(const pcre *code, const char *subject, + int *ovector, int stringcount, const char *stringname, + const char **stringptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr) +#endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; +#ifdef COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); +#else +return pcre16_get_substring(subject, ovector, stringcount, n, stringptr); +#endif } @@ -448,16 +564,22 @@ return pcre_get_substring(subject, ovector, stringcount, n, stringptr); *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C -programs that can call its functions, but not free() or (pcre_free)() directly. +programs that can call its functions, but not free() or (PUBL(free))() +directly. Argument: the result of a previous pcre_get_substring() Returns: nothing */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring(const char *pointer) +#else +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring(PCRE_SPTR16 pointer) +#endif { -(pcre_free)((void *)pointer); +(PUBL(free))((void *)pointer); } /* End of pcre_get.c */ diff --git a/ext/pcre/pcrelib/pcre_globals.c b/ext/pcre/pcrelib/pcre_globals.c index c633e5132e5..3dde1f6e7d0 100644 --- a/ext/pcre/pcrelib/pcre_globals.c +++ b/ext/pcre/pcrelib/pcre_globals.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -65,18 +65,18 @@ static void LocalPcreFree(void* aPtr) { free(aPtr); } -PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = LocalPcreMalloc; -PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = LocalPcreFree; -PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = LocalPcreMalloc; -PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = LocalPcreFree; -PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; +PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc; +PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree; +PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc; +PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree; +PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #elif !defined VPCOMPAT -PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc; -PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free; -PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc; -PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free; -PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; +PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free; +PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free; +PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #endif /* End of pcre_globals.c */ diff --git a/ext/pcre/pcrelib/pcre_info.c b/ext/pcre/pcrelib/pcre_info.c deleted file mode 100644 index e6d435b166b..00000000000 --- a/ext/pcre/pcrelib/pcre_info.c +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains the external function pcre_info(), which gives some -information about a compiled pattern. However, use of this function is now -deprecated, as it has been superseded by pcre_fullinfo(). */ - - -#include "config.h" - -#include "pcre_internal.h" - - -/************************************************* -* (Obsolete) Return info about compiled pattern * -*************************************************/ - -/* This is the original "info" function. It picks potentially useful data out -of the private structure, but its interface was too rigid. It remains for -backwards compatibility. The public options are passed back in an int - though -the re->options field has been expanded to a long int, all the public options -at the low end of it, and so even on 16-bit systems this will still be OK. -Therefore, I haven't changed the API for pcre_info(). - -Arguments: - argument_re points to compiled code - optptr where to pass back the options - first_byte where to pass back the first character, - or -1 if multiline and all branches start ^, - or -2 otherwise - -Returns: number of capturing subpatterns - or negative values on error -*/ - -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_info(const pcre *argument_re, int *optptr, int *first_byte) -{ -real_pcre internal_re; -const real_pcre *re = (const real_pcre *)argument_re; -if (re == NULL) return PCRE_ERROR_NULL; -if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, NULL, NULL); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - } -if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_COMPILE_OPTIONS); -if (first_byte != NULL) - *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte : - ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; -return re->top_bracket; -} - -/* End of pcre_info.c */ diff --git a/ext/pcre/pcrelib/pcre_internal.h b/ext/pcre/pcrelib/pcre_internal.h index 6ec0b7a5412..ed16269b374 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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -40,7 +40,8 @@ POSSIBILITY OF SUCH DAMAGE. /* This header contains definitions that are shared between the different modules, but which are not relevant to the exported API. This includes some -functions whose names all begin with "_pcre_". */ +functions whose names all begin with "_pcre_" or "_pcre16_" depending on +the PRIV macro. */ #ifndef PCRE_INTERNAL_H #define PCRE_INTERNAL_H @@ -51,20 +52,39 @@ functions whose names all begin with "_pcre_". */ #define PCRE_DEBUG #endif -/* We do not support both EBCDIC and UTF-8 at the same time. The "configure" -script prevents both being selected, but not everybody uses "configure". */ - -#if defined EBCDIC && defined SUPPORT_UTF8 -#error The use of both EBCDIC and SUPPORT_UTF8 is not supported. +/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */ +#ifndef COMPILE_PCRE16 +#define COMPILE_PCRE8 #endif -/* If SUPPORT_UCP is defined, SUPPORT_UTF8 must also be defined. The +/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The "configure" script ensures this, but not everybody uses "configure". */ -#if defined SUPPORT_UCP && !defined SUPPORT_UTF8 +#if defined SUPPORT_UCP && !(defined SUPPORT_UTF) +#define SUPPORT_UTF 1 +#endif + +/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility +reasons with existing code. */ + +#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF) +#define SUPPORT_UTF 1 +#endif + +/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code. +Until then we define it if SUPPORT_UTF is defined. */ + +#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8) #define SUPPORT_UTF8 1 #endif +/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure" +script prevents both being selected, but not everybody uses "configure". */ + +#if defined EBCDIC && defined SUPPORT_UTF +#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported. +#endif + /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef inline, and there are *still* stupid compilers about that don't like indented pre-processor statements, or at least there were when I first wrote this. After @@ -158,12 +178,14 @@ set, we ensure here that it has no effect. */ #define PCRE_CALL_CONVENTION #endif -/* We need to have types that specify unsigned 16-bit and 32-bit integers. We +/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We cannot determine these outside the compilation (e.g. by running a program as part of "configure") because PCRE is often cross-compiled for use on other systems. Instead we make use of the maximum sizes that are available at preprocessor time in standard C environments. */ +typedef unsigned char pcre_uint8; + #if USHRT_MAX == 65535 typedef unsigned short pcre_uint16; typedef short pcre_int16; @@ -208,12 +230,47 @@ by "configure". */ /* All character handling must be done as unsigned characters. Otherwise there are problems with top-bit-set characters and functions such as isspace(). -However, we leave the interface to the outside world as char *, because that -should make things easier for callers. We define a short type for unsigned char -to save lots of typing. I tried "uchar", but it causes problems on Digital -Unix, where it is defined in sys/types, so use "uschar" instead. */ +However, we leave the interface to the outside world as char * or short *, +because that should make things easier for callers. This character type is +called pcre_uchar. -typedef unsigned char uschar; +The IN_UCHARS macro multiply its argument with the byte size of the current +pcre_uchar type. Useful for memcpy and such operations, whose require the +byte size of their input/output buffers. + +The MAX_255 macro checks whether its pcre_uchar input is less than 256. + +The TABLE_GET macro is designed for accessing elements of tables whose contain +exactly 256 items. When the character is able to contain more than 256 +items, some check is needed before accessing these tables. +*/ + +#ifdef COMPILE_PCRE8 + +typedef unsigned char pcre_uchar; +#define IN_UCHARS(x) (x) +#define MAX_255(c) 1 +#define TABLE_GET(c, table, default) ((table)[c]) + +#else + +#ifdef COMPILE_PCRE16 +#if USHRT_MAX != 65535 +/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in +pcre.h(.in) and disable (comment out) this message. */ +#error Warning: PCRE_UCHAR16 is not a 16 bit data type. +#endif + +typedef pcre_uint16 pcre_uchar; +#define IN_UCHARS(x) ((x) << 1) +#define MAX_255(c) ((c) <= 255u) +#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* This is an unsigned int value that no character can ever have. UTF-8 characters only go up to 0x7fffffff (though Unicode doesn't go beyond @@ -236,8 +293,8 @@ start/end of string field names are. */ #define IS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) < NLBLOCK->PSEND && \ - _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\ - utf8)) \ + PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ + &(NLBLOCK->nllen), utf)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ (p)[0] == NLBLOCK->nl[0] && \ @@ -250,8 +307,8 @@ start/end of string field names are. */ #define WAS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) > NLBLOCK->PSSTART && \ - _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ - &(NLBLOCK->nllen), utf8)) \ + PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ + &(NLBLOCK->nllen), utf)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \ @@ -269,15 +326,11 @@ used for the external interface and appears in pcre.h, which is why its name must begin with PCRE_. */ #ifdef CUSTOM_SUBJECT_PTR -#define PCRE_SPTR CUSTOM_SUBJECT_PTR -#define USPTR CUSTOM_SUBJECT_PTR +#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR #else -#define PCRE_SPTR const char * -#define USPTR const unsigned char * +#define PCRE_PUCHAR const pcre_uchar * #endif - - /* Include the public PCRE header and the definitions of UCP character property values. */ @@ -345,6 +398,8 @@ The macros are controlled by the value of LINK_SIZE. This defaults to 2 in the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ +#ifdef COMPILE_PCRE8 + #if LINK_SIZE == 2 #define PUT(a,n,d) \ @@ -381,13 +436,54 @@ is automated on Unix systems via the "configure" command. */ #define GET(a,n) \ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) -#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ - +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) #else #error LINK_SIZE must be either 2, 3, or 4 #endif +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 + +#if LINK_SIZE == 2 + +#undef LINK_SIZE +#define LINK_SIZE 1 + +#define PUT(a,n,d) \ + (a[n] = (d)) + +#define GET(a,n) \ + (a[n]) + +#define MAX_PATTERN_SIZE (1 << 16) + +#elif LINK_SIZE == 3 || LINK_SIZE == 4 + +#undef LINK_SIZE +#define LINK_SIZE 2 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) & 65535) + +#define GET(a,n) \ + (((a)[n] << 16) | (a)[(n)+1]) + +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) + +#else +#error LINK_SIZE must be either 2, 3, or 4 +#endif + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* Convenience macro defined in terms of the others */ @@ -398,6 +494,10 @@ is automated on Unix systems via the "configure" command. */ offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ +#ifdef COMPILE_PCRE8 + +#define IMM2_SIZE 2 + #define PUT2(a,n,d) \ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 @@ -405,17 +505,44 @@ capturing parenthesis numbers in back references. */ #define GET2(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) -#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2 +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 -/* When UTF-8 encoding is being used, a character is no longer just a single -byte. The macros for character handling generate simple sequences when used in -byte-mode, and more complicated ones for UTF-8 characters. GETCHARLENTEST is -not used when UTF-8 is not supported, so it is not defined, and BACKCHAR should -never be called in byte mode. To make sure they can never even appear when -UTF-8 support is omitted, we don't even define them. */ +#define IMM2_SIZE 1 -#ifndef SUPPORT_UTF8 +#define PUT2(a,n,d) \ + a[n] = d + +#define GET2(a,n) \ + a[n] + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ + +#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE + +/* The maximum length of a MARK name is currently one data unit; it may be +changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */ + +#define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1) + +/* When UTF encoding is being used, a character is no longer just a single +character. The macros for character handling generate simple sequences when +used in character-mode, and more complicated ones for UTF characters. +GETCHARLENTEST and other macros are not used when UTF is not supported, +so they are not defined. To make sure they can never even appear when +UTF support is omitted, we don't even define them. */ + +#ifndef SUPPORT_UTF + +/* #define MAX_VALUE_FOR_SINGLE_CHAR */ +/* #define HAS_EXTRALEN(c) */ +/* #define GET_EXTRALEN(c) */ +/* #define NOT_FIRSTCHAR(c) */ #define GETCHAR(c, eptr) c = *eptr; #define GETCHARTEST(c, eptr) c = *eptr; #define GETCHARINC(c, eptr) c = *eptr++; @@ -423,14 +550,36 @@ UTF-8 support is omitted, we don't even define them. */ #define GETCHARLEN(c, eptr, len) c = *eptr; /* #define GETCHARLENTEST(c, eptr, len) */ /* #define BACKCHAR(eptr) */ +/* #define FORWARDCHAR(eptr) */ +/* #define ACROSSCHAR(condition, eptr, action) */ -#else /* SUPPORT_UTF8 */ +#else /* SUPPORT_UTF */ + +#ifdef COMPILE_PCRE8 /* These macros were originally written in the form of loops that used data -from the tables whose names start with _pcre_utf8_table. They were rewritten by +from the tables whose names start with PRIV(utf8_table). They were rewritten by a user so as not to use loops, because in some environments this gives a significant performance advantage, and it seems never to do any harm. */ +/* Tells the biggest code point which can be encoded as a single character. */ + +#define MAX_VALUE_FOR_SINGLE_CHAR 127 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) ((c) >= 0xc0) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) + +/* Returns TRUE, if the given character is not the first character +of a UTF sequence. */ + +#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80) + /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer. */ @@ -465,7 +614,7 @@ pointer. */ #define GETCHARTEST(c, eptr) \ c = *eptr; \ - if (utf8 && c >= 0xc0) GETUTF8(c, eptr); + if (utf && c >= 0xc0) GETUTF8(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, advancing the pointer. */ @@ -513,7 +662,7 @@ This is called when we don't know if we are in UTF-8 mode. */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ - if (utf8 && c >= 0xc0) GETUTF8INC(c, eptr); + if (utf && c >= 0xc0) GETUTF8INC(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer, incrementing the length. */ @@ -565,7 +714,7 @@ do not know if we are in UTF-8 mode. */ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ - if (utf8 && c >= 0xc0) GETUTF8LEN(c, eptr, len); + if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro @@ -573,7 +722,116 @@ because almost all calls are already within a block of UTF-8 only code. */ #define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- -#endif /* SUPPORT_UTF8 */ +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + while((condition) && ((eptr) & 0xc0) == 0x80) action + +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 + +/* Tells the biggest code point which can be encoded as a single character. */ + +#define MAX_VALUE_FOR_SINGLE_CHAR 65535 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) 1 + +/* Returns TRUE, if the given character is not the first character +of a UTF sequence. */ + +#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00) + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer. */ + +#define GETUTF16(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, not advancing the pointer. This is called when +we know we are in UTF-16 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, advancing +the pointer. */ + +#define GETUTF16INC(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, advancing the pointer. This is called when we +know we are in UTF-16 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Get the next character, testing for UTF-16 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-16 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *eptr++; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer, incrementing the length. */ + +#define GETUTF16LEN(c, eptr, len) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } + +/* Get the next UTF-16 character, not advancing the pointer, incrementing +length if there is a low surrogate. This is called when we know we are in +UTF-16 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the +pointer, incrementing length if there is a low surrogate. This is called when +we do not know if we are in UTF-16 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-16 mode - we don't put a test within the +macro because almost all calls are already within a block of UTF-16 only +code. */ + +#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- + +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action + +#endif + +#endif /* COMPILE_PCRE8 */ + +#endif /* SUPPORT_UTF */ /* In case there is no definition of offsetof() provided - though any proper @@ -584,27 +842,32 @@ Standard C system should have one. */ #endif -/* These are the public options that can change during matching. */ - -#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) - /* Private flags containing information about the compiled regex. They used to live at the top end of the options word, but that got almost full, so now they are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the restrictions on partial matching have been lifted. It remains for backwards compatibility. */ -#define PCRE_NOPARTIAL 0x0001 /* can't use partial with this regex */ -#define PCRE_FIRSTSET 0x0002 /* first_byte is set */ -#define PCRE_REQCHSET 0x0004 /* req_byte is set */ -#define PCRE_STARTLINE 0x0008 /* start after \n for multiline */ -#define PCRE_JCHANGED 0x0010 /* j option used in regex */ -#define PCRE_HASCRORLF 0x0020 /* explicit \r or \n in pattern */ +#ifdef COMPILE_PCRE8 +#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */ +#endif +#ifdef COMPILE_PCRE16 +#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */ +#endif +#define PCRE_FIRSTSET 0x0010 /* first_char is set */ +#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ +#define PCRE_REQCHSET 0x0040 /* req_byte is set */ +#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */ +#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */ +#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */ +#define PCRE_JCHANGED 0x0400 /* j option used in regex */ +#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ +#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ -/* Options for the "extra" block produced by pcre_study(). */ +/* Flags for the "extra" block produced by pcre_study(). */ -#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ -#define PCRE_STUDY_MINLEN 0x02 /* a minimum length field exists */ +#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */ +#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */ /* Masks for identifying the public options that are permitted at compile time, run time, or study time, respectively. */ @@ -630,13 +893,19 @@ time, run time, or study time, respectively. */ PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ PCRE_NO_START_OPTIMIZE) -#define PUBLIC_STUDY_OPTIONS 0 /* None defined */ +#define PUBLIC_STUDY_OPTIONS \ + (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \ + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) -/* Magic number to provide a small check against being handed junk. Also used -to detect whether a pattern was compiled on a host of different endianness. */ +/* Magic number to provide a small check against being handed junk. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ +/* This variable is used to detect a loaded regular expression +in different endianness. */ + +#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */ + /* Negative values for the firstchar and reqchar variables */ #define REQ_UNSET (-2) @@ -647,12 +916,6 @@ req_byte match. */ #define REQ_BYTE_MAX 1000 -/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a -variable-length repeat, or a anything other than literal characters. */ - -#define REQ_CASELESS 0x0100 /* indicates caselessness */ -#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */ - /* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in environments where these macros are defined elsewhere. Unfortunately, there is no way to do the same for the typedef. */ @@ -681,7 +944,7 @@ for) in a minority area (EBCDIC platforms), this is not sensible. Any application that did need both could compile two versions of the library, using macros to give the functions distinct names. */ -#ifndef SUPPORT_UTF8 +#ifndef SUPPORT_UTF /* UTF-8 support is not enabled; use the platform-dependent character literals so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */ @@ -941,11 +1204,16 @@ so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */ #define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" #define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" #define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" -#define STRING_UTF8_RIGHTPAR "UTF8)" +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR "UTF8)" +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR "UTF16)" +#endif #define STRING_UCP_RIGHTPAR "UCP)" #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" -#else /* SUPPORT_UTF8 */ +#else /* SUPPORT_UTF */ /* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode @@ -1196,11 +1464,16 @@ only. */ #define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS -#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#endif #define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* Escape items that are just an encoding of a particular data value. */ @@ -1240,7 +1513,7 @@ only. */ #define PT_WORD 8 /* Word - L plus N plus underscore */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that -contain UTF-8 characters with values greater than 255. */ +contain characters with values greater than 255. */ #define XCL_NOT 0x01 /* Flag: this is a negative class */ #define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ @@ -1256,8 +1529,8 @@ value such as \n. They must have non-zero values, as check_escape() returns their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL mode rather than an escape sequence. It is also -used for [^] in JavaScript compatibility mode. In non-DOTALL mode, "." behaves -like \N. +used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In +non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. when PCRE_UCP is set, when replacement of \d etc by \p sequences is required. @@ -1301,6 +1574,7 @@ enum { OP_WHITESPACE, /* 9 \s */ OP_NOT_WORDCHAR, /* 10 \W */ OP_WORDCHAR, /* 11 \w */ + OP_ANY, /* 12 Match any character except newline */ OP_ALLANY, /* 13 Match any character */ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ @@ -1315,141 +1589,205 @@ enum { OP_EODN, /* 23 End of data or \n at end of data: \Z. */ OP_EOD, /* 24 End of data: \z */ - OP_OPT, /* 25 Set runtime options */ - OP_CIRC, /* 26 Start of line - varies with multiline switch */ - OP_DOLL, /* 27 End of line - varies with multiline switch */ - OP_CHAR, /* 28 Match one character, casefully */ - OP_CHARNC, /* 29 Match one character, caselessly */ - OP_NOT, /* 30 Match one character, not the following one */ + OP_CIRC, /* 25 Start of line - not multiline */ + OP_CIRCM, /* 26 Start of line - multiline */ + OP_DOLL, /* 27 End of line - not multiline */ + OP_DOLLM, /* 28 End of line - multiline */ + OP_CHAR, /* 29 Match one character, casefully */ + OP_CHARI, /* 30 Match one character, caselessly */ + OP_NOT, /* 31 Match one character, not the given one, casefully */ + OP_NOTI, /* 32 Match one character, not the given one, caselessly */ - OP_STAR, /* 31 The maximizing and minimizing versions of */ - OP_MINSTAR, /* 32 these six opcodes must come in pairs, with */ - OP_PLUS, /* 33 the minimizing one second. */ - OP_MINPLUS, /* 34 This first set applies to single characters.*/ - OP_QUERY, /* 35 */ - OP_MINQUERY, /* 36 */ + /* 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. */ - OP_UPTO, /* 37 From 0 to n matches */ - OP_MINUPTO, /* 38 */ - OP_EXACT, /* 39 Exactly n matches */ + /**** Single characters, caseful, must precede the caseless ones ****/ - OP_POSSTAR, /* 40 Possessified star */ - OP_POSPLUS, /* 41 Possessified plus */ - OP_POSQUERY, /* 42 Posesssified query */ - OP_POSUPTO, /* 43 Possessified upto */ + OP_STAR, /* 33 The maximizing and minimizing versions of */ + OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ + OP_PLUS, /* 35 the minimizing one second. */ + OP_MINPLUS, /* 36 */ + OP_QUERY, /* 37 */ + OP_MINQUERY, /* 38 */ - OP_NOTSTAR, /* 44 The maximizing and minimizing versions of */ - OP_NOTMINSTAR, /* 45 these six opcodes must come in pairs, with */ - OP_NOTPLUS, /* 46 the minimizing one second. They must be in */ - OP_NOTMINPLUS, /* 47 exactly the same order as those above. */ - OP_NOTQUERY, /* 48 This set applies to "not" single characters. */ - OP_NOTMINQUERY, /* 49 */ + OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/ + OP_MINUPTO, /* 40 */ + OP_EXACT, /* 41 Exactly n matches */ - OP_NOTUPTO, /* 50 From 0 to n matches */ - OP_NOTMINUPTO, /* 51 */ - OP_NOTEXACT, /* 52 Exactly n matches */ + OP_POSSTAR, /* 42 Possessified star, caseful */ + OP_POSPLUS, /* 43 Possessified plus, caseful */ + OP_POSQUERY, /* 44 Posesssified query, caseful */ + OP_POSUPTO, /* 45 Possessified upto, caseful */ - OP_NOTPOSSTAR, /* 53 Possessified versions */ - OP_NOTPOSPLUS, /* 54 */ - OP_NOTPOSQUERY, /* 55 */ - OP_NOTPOSUPTO, /* 56 */ + /**** Single characters, caseless, must follow the caseful ones */ - OP_TYPESTAR, /* 57 The maximizing and minimizing versions of */ - OP_TYPEMINSTAR, /* 58 these six opcodes must come in pairs, with */ - OP_TYPEPLUS, /* 59 the minimizing one second. These codes must */ - OP_TYPEMINPLUS, /* 60 be in exactly the same order as those above. */ - OP_TYPEQUERY, /* 61 This set applies to character types such as \d */ - OP_TYPEMINQUERY, /* 62 */ + OP_STARI, /* 46 */ + OP_MINSTARI, /* 47 */ + OP_PLUSI, /* 48 */ + OP_MINPLUSI, /* 49 */ + OP_QUERYI, /* 50 */ + OP_MINQUERYI, /* 51 */ - OP_TYPEUPTO, /* 63 From 0 to n matches */ - OP_TYPEMINUPTO, /* 64 */ - OP_TYPEEXACT, /* 65 Exactly n matches */ + OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */ + OP_MINUPTOI, /* 53 */ + OP_EXACTI, /* 54 */ - OP_TYPEPOSSTAR, /* 66 Possessified versions */ - OP_TYPEPOSPLUS, /* 67 */ - OP_TYPEPOSQUERY, /* 68 */ - OP_TYPEPOSUPTO, /* 69 */ + OP_POSSTARI, /* 55 Possessified star, caseless */ + OP_POSPLUSI, /* 56 Possessified plus, caseless */ + OP_POSQUERYI, /* 57 Posesssified query, caseless */ + OP_POSUPTOI, /* 58 Possessified upto, caseless */ - OP_CRSTAR, /* 70 The maximizing and minimizing versions of */ - OP_CRMINSTAR, /* 71 all these opcodes must come in pairs, with */ - OP_CRPLUS, /* 72 the minimizing one second. These codes must */ - OP_CRMINPLUS, /* 73 be in exactly the same order as those above. */ - OP_CRQUERY, /* 74 These are for character classes and back refs */ - OP_CRMINQUERY, /* 75 */ - OP_CRRANGE, /* 76 These are different to the three sets above. */ - OP_CRMINRANGE, /* 77 */ + /**** The negated ones must follow the non-negated ones, and match them ****/ + /**** Negated single character, caseful; must precede the caseless ones ****/ - OP_CLASS, /* 78 Match a character class, chars < 256 only */ - OP_NCLASS, /* 79 Same, but the bitmap was created from a negative - class - the difference is relevant only when a UTF-8 - character > 255 is encountered. */ + OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ + OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ + OP_NOTPLUS, /* 61 the minimizing one second. They must be in */ + OP_NOTMINPLUS, /* 62 exactly the same order as those above. */ + OP_NOTQUERY, /* 63 */ + OP_NOTMINQUERY, /* 64 */ - OP_XCLASS, /* 80 Extended class for handling UTF-8 chars within the - class. This does both positive and negative. */ + OP_NOTUPTO, /* 65 From 0 to n matches, caseful */ + OP_NOTMINUPTO, /* 66 */ + OP_NOTEXACT, /* 67 Exactly n matches */ - OP_REF, /* 81 Match a back reference */ - OP_RECURSE, /* 82 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 83 Call out to external function if provided */ + OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */ + OP_NOTPOSPLUS, /* 69 */ + OP_NOTPOSQUERY, /* 70 */ + OP_NOTPOSUPTO, /* 71 */ - OP_ALT, /* 84 Start of alternation */ - OP_KET, /* 85 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 86 These two must remain together and in this */ - OP_KETRMIN, /* 87 order. They are for groups the repeat for ever. */ + /**** Negated single character, caseless; must follow the caseful ones ****/ - /* The assertions must come before BRA, CBRA, ONCE, and COND.*/ + OP_NOTSTARI, /* 72 */ + OP_NOTMINSTARI, /* 73 */ + OP_NOTPLUSI, /* 74 */ + OP_NOTMINPLUSI, /* 75 */ + OP_NOTQUERYI, /* 76 */ + OP_NOTMINQUERYI, /* 77 */ - OP_ASSERT, /* 88 Positive lookahead */ - OP_ASSERT_NOT, /* 89 Negative lookahead */ - OP_ASSERTBACK, /* 90 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 91 Negative lookbehind */ - OP_REVERSE, /* 92 Move pointer back - used in lookbehind assertions */ + OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */ + OP_NOTMINUPTOI, /* 79 */ + OP_NOTEXACTI, /* 80 Exactly n matches */ - /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first, - as there's a test for >= ONCE for a subpattern that isn't an assertion. */ + OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */ + OP_NOTPOSPLUSI, /* 82 */ + OP_NOTPOSQUERYI, /* 83 */ + OP_NOTPOSUPTOI, /* 84 */ - OP_ONCE, /* 93 Atomic group */ - OP_BRA, /* 94 Start of non-capturing bracket */ - OP_CBRA, /* 95 Start of capturing bracket */ - OP_COND, /* 96 Conditional group */ + /**** Character types ****/ - /* These three must follow the previous three, in the same order. There's a + OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ + OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ + OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */ + OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */ + OP_TYPEQUERY, /* 89 */ + OP_TYPEMINQUERY, /* 90 */ + + OP_TYPEUPTO, /* 91 From 0 to n matches */ + OP_TYPEMINUPTO, /* 92 */ + OP_TYPEEXACT, /* 93 Exactly n matches */ + + OP_TYPEPOSSTAR, /* 94 Possessified versions */ + OP_TYPEPOSPLUS, /* 95 */ + OP_TYPEPOSQUERY, /* 96 */ + OP_TYPEPOSUPTO, /* 97 */ + + /* These are used for character classes and back references; only the + first six are the same as the sets above. */ + + OP_CRSTAR, /* 98 The maximizing and minimizing versions of */ + OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */ + OP_CRPLUS, /* 100 the minimizing one second. These codes must */ + OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */ + OP_CRQUERY, /* 102 */ + OP_CRMINQUERY, /* 103 */ + + OP_CRRANGE, /* 104 These are different to the three sets above. */ + OP_CRMINRANGE, /* 105 */ + + /* End of quantifier opcodes */ + + OP_CLASS, /* 106 Match a character class, chars < 256 only */ + OP_NCLASS, /* 107 Same, but the bitmap was created from a negative + class - the difference is relevant only when a + character > 255 is encountered. */ + OP_XCLASS, /* 108 Extended class for handling > 255 chars within the + class. This does both positive and negative. */ + OP_REF, /* 109 Match a back reference, casefully */ + OP_REFI, /* 110 Match a back reference, caselessly */ + OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 112 Call out to external function if provided */ + + OP_ALT, /* 113 Start of alternation */ + OP_KET, /* 114 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 115 These two must remain together and in this */ + OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 117 Possessive unlimited repeat. */ + + /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four + asserts must remain in order. */ + + OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */ + OP_ASSERT, /* 119 Positive lookahead */ + OP_ASSERT_NOT, /* 120 Negative lookahead */ + OP_ASSERTBACK, /* 121 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */ + + /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately + after the assertions, with ONCE first, as there's a test for >= ONCE for a + subpattern that isn't an assertion. The POS versions must immediately follow + the non-POS versions in each case. */ + + OP_ONCE, /* 123 Atomic group, contains captures */ + OP_ONCE_NC, /* 124 Atomic group containing no captures */ + OP_BRA, /* 125 Start of non-capturing bracket */ + OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 127 Start of capturing bracket */ + OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 129 Conditional group */ + + /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 97 Start of non-capturing bracket, check empty */ - OP_SCBRA, /* 98 Start of capturing bracket, check empty */ - OP_SCOND, /* 99 Conditional group, check empty */ + OP_SBRA, /* 130 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 132 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 134 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 100 Used to hold a capture number as condition */ - OP_NCREF, /* 101 Same, but generaged by a name reference*/ - OP_RREF, /* 102 Used to hold a recursion number as condition */ - OP_NRREF, /* 103 Same, but generaged by a name reference*/ - OP_DEF, /* 104 The DEFINE condition */ + OP_CREF, /* 135 Used to hold a capture number as condition */ + OP_NCREF, /* 136 Same, but generated by a name reference*/ + OP_RREF, /* 137 Used to hold a recursion number as condition */ + OP_NRREF, /* 138 Same, but generated by a name reference*/ + OP_DEF, /* 139 The DEFINE condition */ - OP_BRAZERO, /* 105 These two must remain together and in this */ - OP_BRAMINZERO, /* 106 order. */ + OP_BRAZERO, /* 140 These two must remain together and in this */ + OP_BRAMINZERO, /* 141 order. */ + OP_BRAPOSZERO, /* 142 */ /* These are backtracking control verbs */ - OP_MARK, /* 107 always has an argument */ - OP_PRUNE, /* 108 */ - OP_PRUNE_ARG, /* 109 same, but with argument */ - OP_SKIP, /* 110 */ - OP_SKIP_ARG, /* 111 same, but with argument */ - OP_THEN, /* 112 */ - OP_THEN_ARG, /* 113 same, but with argument */ - OP_COMMIT, /* 114 */ + OP_MARK, /* 143 always has an argument */ + OP_PRUNE, /* 144 */ + OP_PRUNE_ARG, /* 145 same, but with argument */ + OP_SKIP, /* 146 */ + OP_SKIP_ARG, /* 147 same, but with argument */ + OP_THEN, /* 148 */ + OP_THEN_ARG, /* 149 same, but with argument */ + OP_COMMIT, /* 150 */ /* These are forced failure and success verbs */ - OP_FAIL, /* 115 */ - OP_ACCEPT, /* 116 */ - OP_CLOSE, /* 117 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 151 */ + OP_ACCEPT, /* 152 */ + OP_ASSERT_ACCEPT, /* 153 Used inside assertions */ + OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 118 */ + OP_SKIPZERO, /* 155 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1464,29 +1802,45 @@ called "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 -for debugging. The macro is referenced only in pcre_printint.c. */ +for debugging, and some of them are only partial names. The macro is referenced +only in pcre_printint.c, which fills out the full names in many cases (and in +some cases doesn't actually use these names at all). */ #define OP_NAME_LIST \ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ "extuni", "\\Z", "\\z", \ - "Opt", "^", "$", "char", "charnc", "not", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "^", "^", "$", "$", "char", "chari", "not", "noti", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ - "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \ - "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \ - "AssertB", "AssertB not", "Reverse", \ - "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond", \ + "class", "nclass", "xclass", "Ref", "Refi", \ + "Recurse", "Callout", \ + "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ + "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ + "Once", "Once_NC", \ + "Bra", "BraPos", "CBra", "CBraPos", \ + "Cond", \ + "SBra", "SBraPos", "SCBra", "SCBraPos", \ + "SCond", \ "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \ - "Brazero", "Braminzero", \ + "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ - "*THEN", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT", \ + "*THEN", "*THEN", "*COMMIT", "*FAIL", \ + "*ACCEPT", "*ASSERT_ACCEPT", \ "Close", "Skip zero" @@ -1507,56 +1861,75 @@ 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, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \ + 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \ 2, /* Char - the minimum length */ \ - 2, /* Charnc - the minimum length */ \ + 2, /* Chari - the minimum length */ \ 2, /* not */ \ - /* Positive single-char repeats ** These are */ \ - 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ - 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \ - 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \ + 2, /* noti */ \ + /* Positive single-char repeats ** These are */ \ + 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \ + 2+IMM2_SIZE, /* exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \ + 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \ + 2+IMM2_SIZE, /* exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \ /* Negative single-char repeats - only for chars < 256 */ \ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ - 4, 4, 4, /* NOT upto, minupto, exact */ \ - 2, 2, 2, 4, /* Possessive *, +, ?, upto */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \ + 2+IMM2_SIZE, /* NOT exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \ + 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \ + 2+IMM2_SIZE, /* NOT exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ - 4, 4, 4, /* Type upto, minupto, exact */ \ - 2, 2, 2, 4, /* Possessive *+, ++, ?+, upto+ */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \ + 2+IMM2_SIZE, /* Type exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ - 5, 5, /* CRRANGE, CRMINRANGE */ \ - 33, /* CLASS */ \ - 33, /* NCLASS */ \ + 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ + 1+(32/sizeof(pcre_uchar)), /* CLASS */ \ + 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ - 3, /* REF */ \ + 1+IMM2_SIZE, /* REF */ \ + 1+IMM2_SIZE, /* REFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ 1+LINK_SIZE, /* Ket */ \ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ + 1+LINK_SIZE, /* KetRpos */ \ + 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ - 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* ONCE */ \ + 1+LINK_SIZE, /* ONCE_NC */ \ 1+LINK_SIZE, /* BRA */ \ - 3+LINK_SIZE, /* CBRA */ \ + 1+LINK_SIZE, /* BRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ 1+LINK_SIZE, /* COND */ \ 1+LINK_SIZE, /* SBRA */ \ - 3+LINK_SIZE, /* SCBRA */ \ + 1+LINK_SIZE, /* SBRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ 1+LINK_SIZE, /* SCOND */ \ - 3, 3, /* CREF, NCREF */ \ - 3, 3, /* RREF, NRREF */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \ 1, /* DEF */ \ - 1, 1, /* BRAZERO, BRAMINZERO */ \ + 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ 1, 3, /* SKIP, SKIP_ARG */ \ - 1+LINK_SIZE, 3+LINK_SIZE, /* THEN, THEN_ARG */ \ - 1, 1, 1, 3, 1 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ - + 1, 3, /* THEN, THEN_ARG */ \ + 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ + 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */ /* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion" condition. */ @@ -1573,8 +1946,12 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, - ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, - ERRCOUNT }; + ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, + ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERRCOUNT }; + +/* JIT compiling modes. The function list is indexed by them. */ +enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE, + JIT_NUMBER_OF_COMPILE_MODES }; /* The real format of the start of the pcre block; the index of names and the code vector run on as long as necessary after the end. We store an explicit @@ -1593,24 +1970,29 @@ fields are present. Currently PCRE always sets the dummy fields to zero. NOTE NOTE NOTE */ -typedef struct real_pcre { +#ifdef COMPILE_PCRE8 +#define REAL_PCRE real_pcre +#else +#define REAL_PCRE real_pcre16 +#endif + +typedef struct REAL_PCRE { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ pcre_uint16 flags; /* Private flags */ - pcre_uint16 dummy1; /* For future use */ - pcre_uint16 top_bracket; - pcre_uint16 top_backref; - pcre_uint16 first_byte; - pcre_uint16 req_byte; + pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ + pcre_uint16 top_bracket; /* Highest numbered group */ + pcre_uint16 top_backref; /* Highest numbered back reference */ + pcre_uint16 first_char; /* Starting character */ + pcre_uint16 req_char; /* This character must be seen */ pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ - - const unsigned char *tables; /* Pointer to tables or NULL for std */ - const unsigned char *nullpad; /* NULL padding */ -} real_pcre; + const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ + const pcre_uint8 *nullpad; /* NULL padding */ +} REAL_PCRE; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ @@ -1618,7 +2000,7 @@ remark (see NOTE above) about extending this structure applies. */ typedef struct pcre_study_data { pcre_uint32 size; /* Total that was malloced */ pcre_uint32 flags; /* Private flags */ - uschar start_bits[32]; /* Starting char bits */ + pcre_uint8 start_bits[32]; /* Starting char bits */ pcre_uint32 minlength; /* Minimum subject length */ } pcre_study_data; @@ -1637,60 +2019,71 @@ typedef struct open_capitem { doing the compiling, so that they are thread-safe. */ typedef struct compile_data { - const uschar *lcc; /* Points to lower casing table */ - const uschar *fcc; /* Points to case-flipping table */ - const uschar *cbits; /* Points to character type table */ - const uschar *ctypes; /* Points to table of type maps */ - const uschar *start_workspace;/* The start of working space */ - const uschar *start_code; /* The start of the compiled code */ - const uschar *start_pattern; /* The start of the pattern */ - const uschar *end_pattern; /* The end of the pattern */ - open_capitem *open_caps; /* Chain of open capture items */ - uschar *hwm; /* High watermark of workspace */ - uschar *name_table; /* The name/number table */ - int names_found; /* Number of entries so far */ - int name_entry_size; /* Size of each entry */ - int bracount; /* Count of capturing parens as we compile */ - int final_bracount; /* Saved value after first pass */ - int top_backref; /* Maximum back reference */ - unsigned int backref_map; /* Bitmap of low back refs */ - int external_options; /* External (initial) options */ - int external_flags; /* External flag bits to be set */ - int req_varyopt; /* "After variable item" flag for reqbyte */ - BOOL had_accept; /* (*ACCEPT) encountered */ - BOOL check_lookbehind; /* Lookbehinds need later checking */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - uschar nl[4]; /* Newline string when fixed length */ + const pcre_uint8 *lcc; /* Points to lower casing table */ + const pcre_uint8 *fcc; /* Points to case-flipping table */ + const pcre_uint8 *cbits; /* Points to character type table */ + const pcre_uint8 *ctypes; /* Points to table of type maps */ + const pcre_uchar *start_workspace;/* The start of working space */ + const pcre_uchar *start_code; /* The start of the compiled code */ + const pcre_uchar *start_pattern; /* The start of the pattern */ + const pcre_uchar *end_pattern; /* The end of the pattern */ + open_capitem *open_caps; /* Chain of open capture items */ + pcre_uchar *hwm; /* High watermark of workspace */ + pcre_uchar *name_table; /* The name/number table */ + int names_found; /* Number of entries so far */ + int name_entry_size; /* Size of each entry */ + int workspace_size; /* Size of workspace */ + int bracount; /* Count of capturing parens as we compile */ + int final_bracount; /* Saved value after first pass */ + int max_lookbehind; /* Maximum lookbehind (characters) */ + int top_backref; /* Maximum back reference */ + unsigned int backref_map; /* Bitmap of low back refs */ + int assert_depth; /* Depth of nested assertions */ + int external_options; /* External (initial) options */ + int external_flags; /* External flag bits to be set */ + int req_varyopt; /* "After variable item" flag for reqbyte */ + BOOL had_accept; /* (*ACCEPT) encountered */ + BOOL check_lookbehind; /* Lookbehinds need later checking */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + pcre_uchar nl[4]; /* Newline string when fixed length */ } compile_data; /* Structure for maintaining a chain of pointers to the currently incomplete -branches, for testing for left recursion. */ +branches, for testing for left recursion while compiling. */ typedef struct branch_chain { struct branch_chain *outer; - uschar *current_branch; + pcre_uchar *current_branch; } branch_chain; /* Structure for items in a linked list that represents an explicit recursive -call within the pattern. */ +call within the pattern; used by pcre_exec(). */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ - int group_num; /* Number of group that was called */ - const uschar *after_call; /* "Return value": points after the call in the expr */ - int *offset_save; /* Pointer to start of saved offsets */ - int saved_max; /* Number of saved offsets */ - int save_offset_top; /* Current value of offset_top */ + int group_num; /* Number of group that was called */ + int *offset_save; /* Pointer to start of saved offsets */ + int saved_max; /* Number of saved offsets */ + PCRE_PUCHAR subject_position; /* Position at start of recursion */ } recursion_info; +/* A similar structure for pcre_dfa_exec(). */ + +typedef struct dfa_recursion_info { + struct dfa_recursion_info *prevrec; + int group_num; + PCRE_PUCHAR subject_position; +} dfa_recursion_info; + /* Structure for building a chain of data for holding the values of the subject pointer at the start of each subpattern, so as to detect when an empty string -has been matched by a subpattern - to break infinite loops. */ +has been matched by a subpattern - to break infinite loops; used by +pcre_exec(). */ typedef struct eptrblock { struct eptrblock *epb_prev; - USPTR epb_saved_eptr; + PCRE_PUCHAR epb_saved_eptr; } eptrblock; @@ -1701,61 +2094,71 @@ typedef struct match_data { unsigned long int match_call_count; /* As it says */ unsigned long int match_limit; /* As it says */ unsigned long int match_limit_recursion; /* As it says */ - int *offset_vector; /* Offset vector */ - int offset_end; /* One past the end */ - int offset_max; /* The maximum usable for return data */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - int name_count; /* Number of names in name table */ - int name_entry_size; /* Size of entry in names table */ - uschar *name_table; /* Table of names */ - uschar nl[4]; /* Newline string when fixed */ - const uschar *lcc; /* Points to lower casing table */ - const uschar *ctypes; /* Points to table of type maps */ - BOOL offset_overflow; /* Set if too many extractions */ - BOOL notbol; /* NOTBOL flag */ - BOOL noteol; /* NOTEOL flag */ - BOOL utf8; /* UTF8 flag */ - BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */ - BOOL use_ucp; /* PCRE_UCP flag */ - BOOL endonly; /* Dollar not before final \n */ - BOOL notempty; /* Empty string match not wanted */ - BOOL notempty_atstart; /* Empty string match at start not wanted */ - BOOL hitend; /* Hit the end of the subject at some point */ - BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ - const uschar *start_code; /* For use when recursing */ - USPTR start_subject; /* Start of the subject string */ - USPTR end_subject; /* End of the subject string */ - USPTR start_match_ptr; /* Start of matched string */ - USPTR end_match_ptr; /* Subject position at end match */ - USPTR start_used_ptr; /* Earliest consulted character */ - int partial; /* PARTIAL options */ - int end_offset_top; /* Highwater mark at end of match */ - int capture_last; /* Most recent capture number */ - int start_offset; /* The start offset value */ - eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ - int eptrn; /* Next free eptrblock */ - recursion_info *recursive; /* Linked list of recursion data */ - void *callout_data; /* To pass back to callouts */ - const uschar *mark; /* Mark pointer to pass back */ + int *offset_vector; /* Offset vector */ + int offset_end; /* One past the end */ + int offset_max; /* The maximum usable for return data */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + int name_count; /* Number of names in name table */ + int name_entry_size; /* Size of entry in names table */ + pcre_uchar *name_table; /* Table of names */ + pcre_uchar nl[4]; /* Newline string when fixed */ + const pcre_uint8 *lcc; /* Points to lower casing table */ + const pcre_uint8 *fcc; /* Points to case-flipping table */ + const pcre_uint8 *ctypes; /* Points to table of type maps */ + BOOL offset_overflow; /* Set if too many extractions */ + BOOL notbol; /* NOTBOL flag */ + BOOL noteol; /* NOTEOL flag */ + BOOL utf; /* UTF-8 / UTF-16 flag */ + BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */ + BOOL use_ucp; /* PCRE_UCP flag */ + BOOL endonly; /* Dollar not before final \n */ + BOOL notempty; /* Empty string match not wanted */ + BOOL notempty_atstart; /* Empty string match at start not wanted */ + BOOL hitend; /* Hit the end of the subject at some point */ + BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ + BOOL hasthen; /* Pattern contains (*THEN) */ + BOOL ignore_skip_arg; /* For re-run when SKIP name not found */ + const pcre_uchar *start_code; /* For use when recursing */ + PCRE_PUCHAR start_subject; /* Start of the subject string */ + PCRE_PUCHAR end_subject; /* End of the subject string */ + PCRE_PUCHAR start_match_ptr; /* Start of matched string */ + PCRE_PUCHAR end_match_ptr; /* Subject position at end match */ + PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */ + int partial; /* PARTIAL options */ + int end_offset_top; /* Highwater mark at end of match */ + int capture_last; /* Most recent capture number */ + int start_offset; /* The start offset value */ + int match_function_type; /* Set for certain special calls of MATCH() */ + eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ + int eptrn; /* Next free eptrblock */ + recursion_info *recursive; /* Linked list of recursion data */ + void *callout_data; /* To pass back to callouts */ + const pcre_uchar *mark; /* Mark pointer to pass back on success */ + const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */ + const pcre_uchar *once_target; /* Where to back up to for atomic groups */ +#ifdef NO_RECURSE + void *match_frames_base; /* For remembering malloc'd frames */ +#endif } match_data; /* A similar structure is used for the same purpose by the DFA matching functions. */ typedef struct dfa_match_data { - const uschar *start_code; /* Start of the compiled pattern */ - const uschar *start_subject; /* Start of the subject string */ - const uschar *end_subject; /* End of subject string */ - const uschar *start_used_ptr; /* Earliest consulted character */ - const uschar *tables; /* Character tables */ - int start_offset; /* The start offset value */ - int moptions; /* Match options */ - int poptions; /* Pattern options */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - uschar nl[4]; /* Newline string when fixed */ - void *callout_data; /* To pass back to callouts */ + const pcre_uchar *start_code; /* Start of the compiled pattern */ + const pcre_uchar *start_subject ; /* Start of the subject string */ + const pcre_uchar *end_subject; /* End of subject string */ + const pcre_uchar *start_used_ptr; /* Earliest consulted character */ + const pcre_uint8 *tables; /* Character tables */ + int start_offset; /* The start offset value */ + int moptions; /* Match options */ + int poptions; /* Pattern options */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + pcre_uchar nl[4]; /* Newline string when fixed */ + void *callout_data; /* To pass back to callouts */ + dfa_recursion_info *recursive; /* Linked list of recursion data */ } dfa_match_data; /* Bit definitions for entries in the pcre_ctypes table. */ @@ -1791,6 +2194,28 @@ total length. */ #define ctypes_offset (cbits_offset + cbit_length) #define tables_length (ctypes_offset + 256) +/* Internal function and data prefixes. */ + +#ifdef COMPILE_PCRE8 +#ifndef PUBL +#define PUBL(name) pcre_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre_##name +#endif +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 +#ifndef PUBL +#define PUBL(name) pcre16_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre16_##name +#endif +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ +#endif /* COMPILE_PCRE8 */ + /* Layout of the UCP type table that translates property names into types and codes. Each entry used to point directly to a name, but to reduce the number of relocations in shared libraries, it now has an offset into a single string @@ -1808,62 +2233,116 @@ of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. The data for these tables is in the pcre_tables.c module. */ -extern const int _pcre_utf8_table1[]; -extern const int _pcre_utf8_table2[]; -extern const int _pcre_utf8_table3[]; -extern const uschar _pcre_utf8_table4[]; +#ifdef COMPILE_PCRE8 -extern const int _pcre_utf8_table1_size; +extern const int PRIV(utf8_table1)[]; +extern const int PRIV(utf8_table1_size); +extern const int PRIV(utf8_table2)[]; +extern const int PRIV(utf8_table3)[]; +extern const pcre_uint8 PRIV(utf8_table4)[]; -extern const char _pcre_utt_names[]; -extern const ucp_type_table _pcre_utt[]; -extern const int _pcre_utt_size; +#endif /* COMPILE_PCRE8 */ -extern const uschar _pcre_default_tables[]; +extern const char PRIV(utt_names)[]; +extern const ucp_type_table PRIV(utt)[]; +extern const int PRIV(utt_size); -extern const uschar _pcre_OP_lengths[]; +extern const pcre_uint8 PRIV(default_tables)[]; + +extern const pcre_uint8 PRIV(OP_lengths)[]; /* Internal shared functions. These are functions that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. */ -extern const uschar *_pcre_find_bracket(const uschar *, BOOL, int); -extern BOOL _pcre_is_newline(USPTR, int, USPTR, int *, BOOL); -extern int _pcre_ord2utf8(int, uschar *); -extern real_pcre *_pcre_try_flipped(const real_pcre *, real_pcre *, - const pcre_study_data *, pcre_study_data *); -extern int _pcre_valid_utf8(USPTR, int); -extern BOOL _pcre_was_newline(USPTR, int, USPTR, int *, BOOL); -extern BOOL _pcre_xclass(int, const uschar *); +/* String comparison functions. */ +#ifdef COMPILE_PCRE8 +#define STRCMP_UC_UC(str1, str2) \ + strcmp((char *)(str1), (char *)(str2)) +#define STRCMP_UC_C8(str1, str2) \ + strcmp((char *)(str1), (str2)) +#define STRNCMP_UC_UC(str1, str2, num) \ + strncmp((char *)(str1), (char *)(str2), (num)) +#define STRNCMP_UC_C8(str1, str2, num) \ + strncmp((char *)(str1), (str2), (num)) +#define STRLEN_UC(str) strlen((const char *)str) + +#else + +extern int PRIV(strcmp_uc_uc)(const pcre_uchar *, + const pcre_uchar *); +extern int PRIV(strcmp_uc_c8)(const pcre_uchar *, + const char *); +extern int PRIV(strncmp_uc_uc)(const pcre_uchar *, + const pcre_uchar *, unsigned int num); +extern int PRIV(strncmp_uc_c8)(const pcre_uchar *, + const char *, unsigned int num); +extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str); + +#define STRCMP_UC_UC(str1, str2) \ + PRIV(strcmp_uc_uc)((str1), (str2)) +#define STRCMP_UC_C8(str1, str2) \ + PRIV(strcmp_uc_c8)((str1), (str2)) +#define STRNCMP_UC_UC(str1, str2, num) \ + PRIV(strncmp_uc_uc)((str1), (str2), (num)) +#define STRNCMP_UC_C8(str1, str2, num) \ + PRIV(strncmp_uc_c8)((str1), (str2), (num)) +#define STRLEN_UC(str) PRIV(strlen_uc)(str) + +#endif /* COMPILE_PCRE8 */ + +extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int); +extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, + int *, BOOL); +extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *); +extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *); +extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, + int *, BOOL); +extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL); + +#ifdef SUPPORT_JIT +extern void PRIV(jit_compile)(const REAL_PCRE *, + PUBL(extra) *, int); +extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *, + const pcre_uchar *, int, int, int, int *, int); +extern void PRIV(jit_free)(void *); +extern int PRIV(jit_get_size)(void *); +extern const char* PRIV(jit_get_target)(void); +#endif /* Unicode character database (UCD) */ typedef struct { - uschar script; - uschar chartype; + pcre_uint8 script; + pcre_uint8 chartype; pcre_int32 other_case; } ucd_record; -extern const ucd_record _pcre_ucd_records[]; -extern const uschar _pcre_ucd_stage1[]; -extern const pcre_uint16 _pcre_ucd_stage2[]; -extern const int _pcre_ucp_gentype[]; - +extern const ucd_record PRIV(ucd_records)[]; +extern const pcre_uint8 PRIV(ucd_stage1)[]; +extern const pcre_uint16 PRIV(ucd_stage2)[]; +extern const int PRIV(ucp_gentype)[]; +#ifdef SUPPORT_JIT +extern const int PRIV(ucp_typerange)[]; +#endif +#ifdef SUPPORT_UCP /* UCD access macros */ #define UCD_BLOCK_SIZE 128 -#define GET_UCD(ch) (_pcre_ucd_records + \ - _pcre_ucd_stage2[_pcre_ucd_stage1[(ch) / UCD_BLOCK_SIZE] * \ - UCD_BLOCK_SIZE + ch % UCD_BLOCK_SIZE]) +#define GET_UCD(ch) (PRIV(ucd_records) + \ + PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \ + UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE]) #define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype #define UCD_SCRIPT(ch) GET_UCD(ch)->script -#define UCD_CATEGORY(ch) _pcre_ucp_gentype[UCD_CHARTYPE(ch)] +#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] #define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case) +#endif /* SUPPORT_UCP */ + #endif /* End of pcre_internal.h */ diff --git a/ext/pcre/pcrelib/pcre_maketables.c b/ext/pcre/pcrelib/pcre_maketables.c index 2ba612cec7d..5c73b75f74e 100644 --- a/ext/pcre/pcrelib/pcre_maketables.c +++ b/ext/pcre/pcrelib/pcre_maketables.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -57,21 +57,26 @@ compilation of dftables.c, in which case the macro DFTABLES is defined. */ /* This function builds a set of character tables for use by PCRE and returns a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as -part of the library, the store is obtained via pcre_malloc(), but when compiled -inside dftables, use malloc(). +part of the library, the store is obtained via PUBL(malloc)(), but when +compiled inside dftables, use malloc(). Arguments: none Returns: pointer to the contiguous block of data */ +#ifdef COMPILE_PCRE8 const unsigned char * pcre_maketables(void) +#else +const unsigned char * +pcre16_maketables(void) +#endif { unsigned char *yield, *p; int i; #ifndef DFTABLES -yield = (unsigned char*)(pcre_malloc)(tables_length); +yield = (unsigned char*)(PUBL(malloc))(tables_length); #else yield = (unsigned char*)malloc(tables_length); #endif diff --git a/ext/pcre/pcrelib/pcre_newline.c b/ext/pcre/pcrelib/pcre_newline.c index 3f6160ef22d..ddd7708fa06 100644 --- a/ext/pcre/pcrelib/pcre_newline.c +++ b/ext/pcre/pcrelib/pcre_newline.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-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -65,16 +65,25 @@ Arguments: type the newline type endptr pointer to the end of the string lenptr where to return the length - utf8 TRUE if in utf8 mode + utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL -_pcre_is_newline(USPTR ptr, int type, USPTR endptr, int *lenptr, BOOL utf8) +PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr, + BOOL utf) { int c; -if (utf8) { GETCHAR(c, ptr); } else c = *ptr; +(void)utf; +#ifdef SUPPORT_UTF +if (utf) + { + GETCHAR(c, ptr); + } +else +#endif /* SUPPORT_UTF */ + c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { @@ -93,9 +102,15 @@ else switch(c) case 0x000c: *lenptr = 1; return TRUE; /* FF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ - case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ +#ifdef COMPILE_PCRE8 + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else + case 0x0085: /* NEL */ + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } @@ -114,26 +129,27 @@ Arguments: type the newline type startptr pointer to the start of the string lenptr where to return the length - utf8 TRUE if in utf8 mode + utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL -_pcre_was_newline(USPTR ptr, int type, USPTR startptr, int *lenptr, BOOL utf8) +PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr, + BOOL utf) { int c; +(void)utf; ptr--; -#ifdef SUPPORT_UTF8 -if (utf8) +#ifdef SUPPORT_UTF +if (utf) { BACKCHAR(ptr); GETCHAR(c, ptr); } -else c = *ptr; -#else /* no UTF-8 support */ -c = *ptr; -#endif /* SUPPORT_UTF8 */ +else +#endif /* SUPPORT_UTF */ + c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { @@ -150,9 +166,15 @@ else switch(c) case 0x000b: /* VT */ case 0x000c: /* FF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ - case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ +#ifdef COMPILE_PCRE8 + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else + case 0x0085: /* NEL */ + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } diff --git a/ext/pcre/pcrelib/pcre_ord2utf8.c b/ext/pcre/pcrelib/pcre_ord2utf8.c index 7931241d679..917d943f0a1 100644 --- a/ext/pcre/pcrelib/pcre_ord2utf8.c +++ b/ext/pcre/pcrelib/pcre_ord2utf8.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -50,35 +50,45 @@ character value into a UTF8 string. */ * Convert character value to UTF-8 * *************************************************/ -/* This function takes an integer value in the range 0 - 0x7fffffff -and encodes it as a UTF-8 character in 0 to 6 bytes. +/* This function takes an integer value in the range 0 - 0x10ffff +and encodes it as a UTF-8 character in 1 to 6 pcre_uchars. Arguments: cvalue the character value - buffer pointer to buffer for result - at least 6 bytes long + buffer pointer to buffer for result - at least 6 pcre_uchars long Returns: number of characters placed in the buffer */ int -_pcre_ord2utf8(int cvalue, uschar *buffer) +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) { -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF + register int i, j; -for (i = 0; i < _pcre_utf8_table1_size; i++) - if (cvalue <= _pcre_utf8_table1[i]) break; + +/* Checking invalid cvalue character, encoded as invalid UTF-16 character. +Should never happen in practice. */ +if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) + cvalue = 0xfffe; + +for (i = 0; i < PRIV(utf8_table1_size); i++) + if ((int)cvalue <= PRIV(utf8_table1)[i]) break; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } -*buffer = _pcre_utf8_table2[i] | cvalue; +*buffer = PRIV(utf8_table2)[i] | cvalue; return i + 1; + #else + (void)(cvalue); /* Keep compiler happy; this function won't ever be */ -(void)(buffer); /* called when SUPPORT_UTF8 is not defined. */ +(void)(buffer); /* called when SUPPORT_UTF is not defined. */ return 0; + #endif } diff --git a/ext/pcre/pcrelib/pcre_refcount.c b/ext/pcre/pcrelib/pcre_refcount.c index c92d578e6eb..ec16713f0bb 100644 --- a/ext/pcre/pcrelib/pcre_refcount.c +++ b/ext/pcre/pcrelib/pcre_refcount.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -66,11 +66,18 @@ Returns: the (possibly updated) count value (a non-negative number), or a negative error number */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_refcount(pcre *argument_re, int adjust) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_refcount(pcre16 *argument_re, int adjust) +#endif { -real_pcre *re = (real_pcre *)argument_re; +REAL_PCRE *re = (REAL_PCRE *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; +if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; re->ref_count = (-adjust > re->ref_count)? 0 : (adjust + re->ref_count > 65535)? 65535 : re->ref_count + adjust; diff --git a/ext/pcre/pcrelib/pcre_study.c b/ext/pcre/pcrelib/pcre_study.c index 431ad9d0dd8..9d893d5e20c 100644 --- a/ext/pcre/pcrelib/pcre_study.c +++ b/ext/pcre/pcrelib/pcre_study.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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ supporting functions. */ /* Returns from set_start_bits() */ -enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE }; +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; @@ -64,25 +64,30 @@ string of that length that matches. In UTF8 mode, the result is in characters rather than bytes. Arguments: - code pointer to start of group (the bracket) - startcode pointer to start of the whole pattern - options the compiling options + code pointer to start of group (the bracket) + startcode pointer to start of the whole pattern + options the compiling options + int RECURSE depth Returns: the minimum length - -1 if \C was encountered + -1 if \C in UTF-8 mode or (*ACCEPT) was encountered -2 internal error (missing capturing bracket) + -3 internal error (opcode not listed) */ static int -find_minlength(const uschar *code, const uschar *startcode, int options) +find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options, + int recurse_depth) { int length = -1; -BOOL utf8 = (options & PCRE_UTF8) != 0; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; BOOL had_recurse = FALSE; register int branchlength = 0; -register uschar *cc = (uschar *)code + 1 + LINK_SIZE; +register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE; -if (*code == OP_CBRA || *code == OP_SCBRA) cc += 2; +if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ @@ -90,7 +95,7 @@ branch, check the length against that of the other branches. */ for (;;) { int d, min; - uschar *cs, *ce; + pcre_uchar *cs, *ce; register int op = *cc; switch (op) @@ -116,26 +121,40 @@ for (;;) case OP_SCBRA: case OP_BRA: case OP_SBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOS: + case OP_SBRAPOS: case OP_ONCE: - d = find_minlength(cc, startcode, options); + case OP_ONCE_NC: + d = find_minlength(cc, startcode, options, recurse_depth); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; + /* ACCEPT makes things far too complicated; we have to give up. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + return -1; + /* Reached end of a branch; if it's a ket it is the end of a nested - call. If it's ALT it is an alternation in a nested call. If it is - END it's the end of the outer call. All can be handled by the same code. */ + call. If it's ALT it is an alternation in a nested call. If it is END it's + the end of the outer call. All can be handled by the same code. If an + ACCEPT was previously encountered, use the length that was in force at that + time, and pass back the shortest ACCEPT length. */ case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: case OP_END: if (length < 0 || (!had_recurse && branchlength < length)) length = branchlength; - if (*cc != OP_ALT) return length; + if (op != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; had_recurse = FALSE; @@ -158,25 +177,27 @@ for (;;) case OP_RREF: case OP_NRREF: case OP_DEF: - case OP_OPT: case OP_CALLOUT: case OP_SOD: case OP_SOM: case OP_EOD: case OP_EODN: case OP_CIRC: + case OP_CIRCM: case OP_DOLL: + case OP_DOLLM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; break; /* Skip over a subpattern that has a {0} or {0,x} quantifier */ case OP_BRAZERO: case OP_BRAMINZERO: + case OP_BRAPOSZERO: case OP_SKIPZERO: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; @@ -184,18 +205,25 @@ for (;;) /* Handle literal characters and + repetitions */ case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: branchlength++; cc += 2; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -210,17 +238,20 @@ for (;;) need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: + case OP_EXACTI: case OP_NOTEXACT: + case OP_NOTEXACTI: branchlength += GET2(cc,1); - cc += 4; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); - cc += (cc[3] == OP_PROP || cc[3] == OP_NOTPROP)? 6 : 4; + cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); break; /* Handle single-char non-literal matchers */ @@ -247,18 +278,21 @@ for (;;) cc++; break; - /* "Any newline" might match two characters */ + /* "Any newline" might match two characters, but it also might match just + one. */ case OP_ANYNL: - branchlength += 2; + branchlength += 1; cc++; break; - /* The single-byte matcher means we can't proceed in UTF-8 mode */ + /* The single-byte matcher means we can't proceed in UTF-8 mode. (In + non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever + appear, but leave the code, just in case.) */ case OP_ANYBYTE: -#ifdef SUPPORT_UTF8 - if (utf8) return -1; +#ifdef SUPPORT_UTF + if (utf) return -1; #endif branchlength++; cc++; @@ -274,27 +308,28 @@ for (;;) case OP_TYPEPOSSTAR: case OP_TYPEPOSQUERY: if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; - cc += _pcre_OP_lengths[op]; + cc += PRIV(OP_lengths)[op]; break; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2; - cc += _pcre_OP_lengths[op]; + if (cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; + cc += PRIV(OP_lengths)[op]; break; /* Check a class for variable quantification */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: - cc += GET(cc, 1) - 33; + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: - cc += 33; + cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { @@ -313,7 +348,7 @@ for (;;) case OP_CRRANGE: case OP_CRMINRANGE: branchlength += GET2(cc,1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -335,9 +370,10 @@ for (;;) that case we must set the minimum length to zero. */ case OP_REF: + case OP_REFI: if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) { - ce = cs = (uschar *)_pcre_find_bracket(startcode, utf8, GET2(cc, 1)); + ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); if (cc > cs && cc < ce) @@ -345,10 +381,13 @@ for (;;) d = 0; had_recurse = TRUE; } - else d = find_minlength(cs, startcode, options); + else + { + d = find_minlength(cs, startcode, options, recurse_depth); + } } else d = 0; - cc += 3; + cc += 1 + IMM2_SIZE; /* Handle repeated back references */ @@ -362,10 +401,16 @@ for (;;) cc++; break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + cc++; + break; + case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(cc, 1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -376,39 +421,71 @@ for (;;) branchlength += min * d; break; + /* We can easily detect direct recursion, but not mutual recursion. This is + caught by a recursion depth count. */ + case OP_RECURSE: - cs = ce = (uschar *)startcode + GET(cc, 1); - if (cs == NULL) return -2; + cs = ce = (pcre_uchar *)startcode + GET(cc, 1); do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) + if ((cc > cs && cc < ce) || recurse_depth > 10) had_recurse = TRUE; else - branchlength += find_minlength(cs, startcode, options); + { + branchlength += find_minlength(cs, startcode, options, recurse_depth + 1); + } cc += 1 + LINK_SIZE; break; /* Anything else does not or need not match a character. We can get the item's length from the table, but for those that can match zero occurrences - of a character, we must take special action for UTF-8 characters. */ + of a character, we must take special action for UTF-8 characters. As it + happens, the "NOT" versions of these opcodes are used at present only for + ASCII characters, so they could be omitted from this list. However, in + future that may change, so we include them here so as not to leave a + gotcha for a future maintainer. */ case OP_UPTO: + case OP_UPTOI: case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: case OP_POSQUERY: + case OP_POSQUERYI: case OP_NOTPOSQUERY: - cc += _pcre_OP_lengths[op]; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + case OP_NOTPOSQUERYI: + + cc += PRIV(OP_lengths)[op]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -417,20 +494,27 @@ for (;;) case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: - cc += _pcre_OP_lengths[op] + cc[1]; - break; - case OP_THEN_ARG: - cc += _pcre_OP_lengths[op] + cc[1+LINK_SIZE]; + cc += PRIV(OP_lengths)[op] + cc[1]; break; - /* For the record, these are the opcodes that are matched by "default": - OP_ACCEPT, OP_CLOSE, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_SET_SOM, OP_SKIP, - OP_THEN. */ + /* The remaining opcodes are just skipped over. */ + + case OP_CLOSE: + case OP_COMMIT: + case OP_FAIL: + case OP_PRUNE: + case OP_SET_SOM: + case OP_SKIP: + case OP_THEN: + cc += PRIV(OP_lengths)[op]; + break; + + /* This should not occur: we list all opcodes explicitly so that when + new ones get added they are properly considered. */ default: - cc += _pcre_OP_lengths[op]; - break; + return -3; } } /* Control never gets here */ @@ -452,29 +536,30 @@ Arguments: p points to the character caseless the caseless flag cd the block with char table pointers - utf8 TRUE for UTF-8 mode + utf TRUE for UTF-8 / UTF-16 mode Returns: pointer after the character */ -static const uschar * -set_table_bit(uschar *start_bits, const uschar *p, BOOL caseless, - compile_data *cd, BOOL utf8) +static const pcre_uchar * +set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless, + compile_data *cd, BOOL utf) { unsigned int c = *p; +#ifdef COMPILE_PCRE8 SET_BIT(c); -#ifdef SUPPORT_UTF8 -if (utf8 && c > 127) +#ifdef SUPPORT_UTF +if (utf && c > 127) { GETCHARINC(c, p); #ifdef SUPPORT_UCP if (caseless) { - uschar buff[8]; + pcre_uchar buff[6]; c = UCD_OTHERCASE(c); - (void)_pcre_ord2utf8(c, buff); + (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } #endif @@ -486,6 +571,36 @@ if (utf8 && c > 127) if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; +#endif + +#ifdef COMPILE_PCRE16 +if (c > 0xff) + { + c = 0xff; + caseless = FALSE; + } +SET_BIT(c); + +#ifdef SUPPORT_UTF +if (utf && c > 127) + { + GETCHARINC(c, p); +#ifdef SUPPORT_UCP + if (caseless) + { + c = UCD_OTHERCASE(c); + if (c > 0xff) + c = 0xff; + SET_BIT(c); + } +#endif + return p; + } +#endif + +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); +return p + 1; +#endif } @@ -511,21 +626,23 @@ Returns: nothing */ static void -set_type_bits(uschar *start_bits, int cbit_type, int table_limit, +set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type]; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit == 32) return; for (c = 128; c < 256; c++) { if ((cd->cbits[c/8] & (1 << (c&7))) != 0) { - uschar buff[8]; - (void)_pcre_ord2utf8(c, buff); + pcre_uchar buff[6]; + (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } } +#endif } @@ -551,12 +668,14 @@ Returns: nothing */ static void -set_nottype_bits(uschar *start_bits, int cbit_type, int table_limit, +set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type]; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff; +#endif } @@ -576,22 +695,26 @@ function fails unless the result is SSB_DONE. Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 - caseless the current state of the caseless flag - utf8 TRUE if in UTF-8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd the block with char table pointers Returns: SSB_FAIL => Failed to find any starting bytes SSB_DONE => Found mandatory starting bytes SSB_CONTINUE => Found optional starting bytes + SSB_UNKNOWN => Hit an unrecognized opcode */ static int -set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, - BOOL utf8, compile_data *cd) +set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf, + compile_data *cd) { register int c; int yield = SSB_DONE; -int table_limit = utf8? 16:32; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +int table_limit = utf? 16:32; +#else +int table_limit = 32; +#endif #if 0 /* ========================================================================= */ @@ -612,19 +735,108 @@ volatile int dummy; do { - const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE; BOOL try_next = TRUE; + const pcre_uchar *tcode = code + 1 + LINK_SIZE; + + if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE; while (try_next) /* Loop for items in this branch */ { int rc; + switch(*tcode) { - /* Fail if we reach something we don't understand */ + /* If we reach something we don't understand, it means a new opcode has + been created that hasn't been added to this code. Hopefully this problem + will be discovered during testing. */ default: + return SSB_UNKNOWN; + + /* Fail for a valid opcode that implies no starting bits. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_ALLANY: + case OP_ANY: + case OP_ANYBYTE: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: + case OP_COND: + case OP_CREF: + case OP_DEF: + case OP_DOLL: + case OP_DOLLM: + case OP_END: + case OP_EOD: + case OP_EODN: + case OP_EXTUNI: + case OP_FAIL: + case OP_MARK: + case OP_NCREF: + case OP_NOT: + case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_NOTI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTPROP: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: + case OP_NRREF: + case OP_PROP: + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_RECURSE: + case OP_REF: + case OP_REFI: + case OP_REVERSE: + case OP_RREF: + case OP_SCOND: + case OP_SET_SOM: + case OP_SKIP: + case OP_SKIP_ARG: + case OP_SOD: + case OP_SOM: + case OP_THEN: + case OP_THEN_ARG: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: +#endif return SSB_FAIL; + /* We can ignore word boundary tests. */ + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + tcode++; + break; + /* If we hit a bracket or a positive lookahead assertion, recurse to set bits from within the subpattern. If it can't find anything, we have to give up. If it finds some mandatory character(s), we are done for this @@ -634,10 +846,15 @@ do case OP_SBRA: case OP_CBRA: case OP_SCBRA: + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: case OP_ONCE: + case OP_ONCE_NC: case OP_ASSERT: - rc = set_start_bits(tcode, start_bits, caseless, utf8, cd); - if (rc == SSB_FAIL) return SSB_FAIL; + rc = set_start_bits(tcode, start_bits, utf, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; if (rc == SSB_DONE) try_next = FALSE; else { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); @@ -660,6 +877,7 @@ do case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: return SSB_CONTINUE; /* Skip over callout */ @@ -677,19 +895,13 @@ do tcode += 1 + LINK_SIZE; break; - /* Skip over an option setting, changing the caseless flag */ - - case OP_OPT: - caseless = (tcode[1] & PCRE_CASELESS) != 0; - tcode += 2; - break; - /* BRAZERO does the bracket, but carries on. */ case OP_BRAZERO: case OP_BRAMINZERO: - if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL) - return SSB_FAIL; + case OP_BRAPOSZERO: + rc = set_start_bits(++tcode, start_bits, utf, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; /* ========================================================================= See the comment at the head of this function concerning the next line, which was an old fudge for the benefit of OS/2. @@ -715,7 +927,16 @@ do case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: - tcode = set_table_bit(start_bits, tcode + 1, caseless, cd, utf8); + tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); + break; + + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); break; /* Single-char upto sets the bit and tries the next */ @@ -723,20 +944,36 @@ do case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: - tcode = set_table_bit(start_bits, tcode + 3, caseless, cd, utf8); + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf); + break; + + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf); break; /* At least one single char sets the bit and stops */ - case OP_EXACT: /* Fall through */ - tcode += 2; - + case OP_EXACT: + tcode += IMM2_SIZE; + /* Fall through */ case OP_CHAR: - case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: - (void)set_table_bit(start_bits, tcode + 1, caseless, cd, utf8); + (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); + try_next = FALSE; + break; + + case OP_EXACTI: + tcode += IMM2_SIZE; + /* Fall through */ + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); try_next = FALSE; break; @@ -749,14 +986,28 @@ do case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif + } + else +#endif /* SUPPORT_UTF */ + { + SET_BIT(0xA0); +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0xA0); try_next = FALSE; break; @@ -766,12 +1017,26 @@ do SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); + SET_BIT(0xFF); /* For characters > 255 */ +#endif + } + else +#endif /* SUPPORT_UTF */ + { + SET_BIT(0x85); +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0x85); try_next = FALSE; break; @@ -829,7 +1094,7 @@ do break; case OP_TYPEEXACT: - tcode += 3; + tcode += 1 + IMM2_SIZE; break; /* Zero or more repeats of character types set the bits and then @@ -838,7 +1103,7 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += 2; /* Fall through */ + tcode += IMM2_SIZE; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -856,14 +1121,23 @@ do case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0xA0); + else +#endif /* SUPPORT_UTF */ + SET_BIT(0xA0); break; case OP_ANYNL: @@ -872,12 +1146,21 @@ do SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0x85); + else +#endif /* SUPPORT_UTF */ + SET_BIT(0x85); break; case OP_NOT_DIGIT: @@ -924,18 +1207,23 @@ do character with a value > 255. */ case OP_NCLASS: -#ifdef SUPPORT_UTF8 - if (utf8) +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) { start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ #endif /* Fall through */ case OP_CLASS: { + pcre_uint8 *map; tcode++; + map = (pcre_uint8 *)tcode; /* In UTF-8 mode, the bits in a bit map correspond to character values, not to byte values. However, the bit map we are constructing is @@ -943,13 +1231,13 @@ do value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ -#ifdef SUPPORT_UTF8 - if (utf8) +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) { - for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; + for (c = 0; c < 16; c++) start_bits[c] |= map[c]; for (c = 128; c < 256; c++) { - if ((tcode[c/8] && (1 << (c&7))) != 0) + if ((map[c/8] && (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ @@ -957,18 +1245,17 @@ do } } } - - /* In non-UTF-8 mode, the two bit maps are completely compatible. */ - else #endif { - for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; + /* In non-UTF-8 mode, the two bit maps are completely compatible. */ + for (c = 0; c < 32; c++) start_bits[c] |= map[c]; } - /* Advance past the bit map, and act on what follows */ + /* Advance past the bit map, and act on what follows. For a zero + minimum repeat, continue; otherwise stop processing. */ - tcode += 32; + tcode += 32 / sizeof(pcre_uchar); switch (*tcode) { case OP_CRSTAR: @@ -980,7 +1267,7 @@ do case OP_CRRANGE: case OP_CRMINRANGE: - if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; + if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; else try_next = FALSE; break; @@ -1002,12 +1289,14 @@ return yield; + + /************************************************* * Study a compiled expression * *************************************************/ /* This function is handed a compiled expression that it must study to produce -information that will speed up the matching. It returns a pcre_extra block +information that will speed up the matching. It returns a pcre[16]_extra block which then gets handed back to pcre_exec(). Arguments: @@ -1016,23 +1305,28 @@ Arguments: errorptr points to where to place error messages; set NULL unless error -Returns: pointer to a pcre_extra block, with study_data filled in and the - appropriate flags set; +Returns: pointer to a pcre[16]_extra block, with study_data filled in and + the appropriate flags set; NULL on error or if no optimization possible */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION pcre_study(const pcre *external_re, int options, const char **errorptr) +#else +PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION +pcre16_study(const pcre16 *external_re, int options, const char **errorptr) +#endif { int min; BOOL bits_set = FALSE; -uschar start_bits[32]; -pcre_extra *extra; +pcre_uint8 start_bits[32]; +PUBL(extra) *extra = NULL; pcre_study_data *study; -const uschar *tables; -uschar *code; +const pcre_uint8 *tables; +pcre_uchar *code; compile_data compile_block; -const real_pcre *re = (const real_pcre *)external_re; +const REAL_PCRE *re = (const REAL_PCRE *)external_re; *errorptr = NULL; @@ -1042,13 +1336,23 @@ if (re == NULL || re->magic_number != MAGIC_NUMBER) return NULL; } +if ((re->flags & PCRE_MODE) == 0) + { +#ifdef COMPILE_PCRE8 + *errorptr = "argument is compiled in 16 bit mode"; +#else + *errorptr = "argument is compiled in 8 bit mode"; +#endif + return NULL; + } + if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) { *errorptr = "unknown or incorrect option bit(s) set"; return NULL; } -code = (uschar *)re + re->name_table_offset + +code = (pcre_uchar *)re + re->name_table_offset + (re->name_count * re->name_entry_size); /* For an anchored pattern, or an unanchored pattern that has a first char, or @@ -1058,12 +1362,21 @@ seeking a list of starting bytes. */ if ((re->options & PCRE_ANCHORED) == 0 && (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0) { + int rc; + /* Set the character tables in the block that is passed around */ tables = re->tables; + +#ifdef COMPILE_PCRE8 if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); +#else + if (tables == NULL) + (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, + (void *)(&tables)); +#endif compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; @@ -1072,56 +1385,148 @@ if ((re->options & PCRE_ANCHORED) == 0 && /* See if we can find a fixed set of initial characters for the pattern. */ - memset(start_bits, 0, 32 * sizeof(uschar)); - bits_set = set_start_bits(code, start_bits, - (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0, - &compile_block) == SSB_DONE; + memset(start_bits, 0, 32 * sizeof(pcre_uint8)); + rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0, + &compile_block); + bits_set = rc == SSB_DONE; + if (rc == SSB_UNKNOWN) + { + *errorptr = "internal error: opcode not recognized"; + return NULL; + } } /* Find the minimum length of subject string. */ -min = find_minlength(code, code, re->options); - -/* Return NULL if no optimization is possible. */ - -if (!bits_set && min < 0) return NULL; - -/* Get a pcre_extra block and a pcre_study_data block. The study data is put in -the latter, which is pointed to by the former, which may also get additional -data set later by the calling program. At the moment, the size of -pcre_study_data is fixed. We nevertheless save it in a field for returning via -the pcre_fullinfo() function so that if it becomes variable in the future, we -don't have to change that code. */ - -extra = (pcre_extra *)(pcre_malloc) - (sizeof(pcre_extra) + sizeof(pcre_study_data)); - -if (extra == NULL) +switch(min = find_minlength(code, code, re->options, 0)) { - *errorptr = "failed to get memory"; - return NULL; + case -2: *errorptr = "internal error: missing capturing bracket"; return NULL; + case -3: *errorptr = "internal error: opcode not recognized"; return NULL; + default: break; } -study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); -extra->flags = PCRE_EXTRA_STUDY_DATA; -extra->study_data = study; +/* If a set of starting bytes has been identified, or if the minimum length is +greater than zero, or if JIT optimization has been requested, get a +pcre[16]_extra block and a pcre_study_data block. The study data is put in the +latter, which is pointed to by the former, which may also get additional data +set later by the calling program. At the moment, the size of pcre_study_data +is fixed. We nevertheless save it in a field for returning via the +pcre_fullinfo() function so that if it becomes variable in the future, +we don't have to change that code. */ -study->size = sizeof(pcre_study_data); -study->flags = 0; - -if (bits_set) +if (bits_set || min > 0 +#ifdef SUPPORT_JIT + || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0 +#endif + ) { - study->flags |= PCRE_STUDY_MAPPED; - memcpy(study->start_bits, start_bits, sizeof(start_bits)); - } + extra = (PUBL(extra) *)(PUBL(malloc)) + (sizeof(PUBL(extra)) + sizeof(pcre_study_data)); + if (extra == NULL) + { + *errorptr = "failed to get memory"; + return NULL; + } -if (min >= 0) - { - study->flags |= PCRE_STUDY_MINLEN; - study->minlength = min; + study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra))); + extra->flags = PCRE_EXTRA_STUDY_DATA; + extra->study_data = study; + + study->size = sizeof(pcre_study_data); + study->flags = 0; + + /* Set the start bits always, to avoid unset memory errors if the + study data is written to a file, but set the flag only if any of the bits + are set, to save time looking when none are. */ + + if (bits_set) + { + study->flags |= PCRE_STUDY_MAPPED; + memcpy(study->start_bits, start_bits, sizeof(start_bits)); + } + else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8)); + +#ifdef PCRE_DEBUG + if (bits_set) + { + pcre_uint8 *ptr = start_bits; + int i; + + printf("Start bits:\n"); + for (i = 0; i < 32; i++) + printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n"); + } +#endif + + /* Always set the minlength value in the block, because the JIT compiler + makes use of it. However, don't set the bit unless the length is greater than + zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time + checking the zero case. */ + + if (min > 0) + { + study->flags |= PCRE_STUDY_MINLEN; + study->minlength = min; + } + else study->minlength = 0; + + /* If JIT support was compiled and requested, attempt the JIT compilation. + If no starting bytes were found, and the minimum length is zero, and JIT + compilation fails, abandon the extra block and return NULL. */ + +#ifdef SUPPORT_JIT + extra->executable_jit = NULL; + if ((options & PCRE_STUDY_JIT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE); + + if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0) + { +#ifdef COMPILE_PCRE8 + pcre_free_study(extra); +#endif +#ifdef COMPILE_PCRE16 + pcre16_free_study(extra); +#endif + extra = NULL; + } +#endif } return extra; } + +/************************************************* +* Free the study data * +*************************************************/ + +/* This function frees the memory that was obtained by pcre_study(). + +Argument: a pointer to the pcre[16]_extra block +Returns: nothing +*/ + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DEFN void +pcre_free_study(pcre_extra *extra) +#else +PCRE_EXP_DEFN void +pcre16_free_study(pcre16_extra *extra) +#endif +{ +if (extra == NULL) + return; +#ifdef SUPPORT_JIT +if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + PRIV(jit_free)(extra->executable_jit); +#endif +PUBL(free)(extra); +} + /* End of pcre_study.c */ diff --git a/ext/pcre/pcrelib/pcre_tables.c b/ext/pcre/pcrelib/pcre_tables.c index 4dfcbc6f9db..2f605f5fa17 100644 --- a/ext/pcre/pcrelib/pcre_tables.c +++ b/ext/pcre/pcrelib/pcre_tables.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-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ +#ifndef PCRE_INCLUDED /* This module contains some fixed tables that are used by more than one of the PCRE code modules. The tables are also #included by the pcretest program, which @@ -48,11 +49,12 @@ clashes with the library. */ #include "pcre_internal.h" +#endif /* PCRE_INCLUDED */ /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre_internal.h. */ -const uschar _pcre_OP_lengths[] = { OP_LENGTHS }; +const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS }; @@ -63,31 +65,38 @@ const uschar _pcre_OP_lengths[] = { OP_LENGTHS }; /* These are the breakpoints for different numbers of bytes in a UTF-8 character. */ -#ifdef SUPPORT_UTF8 +#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \ + || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16) -const int _pcre_utf8_table1[] = +/* These tables are also required by pcretest in 16 bit mode. */ + +const int PRIV(utf8_table1)[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; -const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int); +const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); /* These are the indicator bits and the mask for the data bits to set in the first byte of a character, indexed by the number of additional bytes. */ -const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; -const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; +const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; +const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /* Table of the number of extra bytes, indexed by the first byte masked with 0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ -const uschar _pcre_utf8_table4[] = { +const pcre_uint8 PRIV(utf8_table4)[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; +#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/ + +#ifdef SUPPORT_UTF + /* Table to translate from particular type value to the general value. */ -const int _pcre_ucp_gentype[] = { +const int PRIV(ucp_gentype)[] = { ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ @@ -98,6 +107,21 @@ const int _pcre_ucp_gentype[] = { ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; +#ifdef SUPPORT_JIT +/* This table reverses PRIV(ucp_gentype). We can save the cost +of a memory load. */ + +const int PRIV(ucp_typerange)[] = { + ucp_Cc, ucp_Cs, + ucp_Ll, ucp_Lu, + ucp_Mc, ucp_Mn, + ucp_Nd, ucp_No, + ucp_Pc, ucp_Ps, + ucp_Sc, ucp_So, + ucp_Zl, ucp_Zs, +}; +#endif /* SUPPORT_JIT */ + /* The pcre_utt[] table below translates Unicode property names into type and code values. It is searched by binary chop, so must be in collating sequence of name. Originally, the table contained pointers to the name strings in the first @@ -108,7 +132,7 @@ table itself. Maintenance is more error-prone, but frequent changes to this data are unlikely. July 2008: There is now a script called maint/GenerateUtt.py that can be used -to generate this data instead of maintaining it entirely by hand. +to generate this data automatically instead of maintaining it by hand. The script was updated in March 2009 to generate a new EBCDIC-compliant version. Like all other character and string literals that are compared against @@ -121,8 +145,10 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0" #define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0" +#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0" #define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0" #define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0" +#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0" #define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0" #define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0" @@ -131,6 +157,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0" #define STRING_Cc0 STR_C STR_c "\0" #define STRING_Cf0 STR_C STR_f "\0" +#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0" #define STRING_Cham0 STR_C STR_h STR_a STR_m "\0" #define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0" #define STRING_Cn0 STR_C STR_n "\0" @@ -184,9 +211,13 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0" #define STRING_M0 STR_M "\0" #define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0" +#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0" #define STRING_Mc0 STR_M STR_c "\0" #define STRING_Me0 STR_M STR_e "\0" #define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0" +#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0" +#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" +#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0" #define STRING_Mn0 STR_M STR_n "\0" #define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0" #define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0" @@ -220,11 +251,13 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0" #define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0" #define STRING_Sc0 STR_S STR_c "\0" +#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0" #define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0" #define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0" #define STRING_Sk0 STR_S STR_k "\0" #define STRING_Sm0 STR_S STR_m "\0" #define STRING_So0 STR_S STR_o "\0" +#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0" #define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0" #define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0" #define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0" @@ -233,6 +266,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0" #define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0" #define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0" +#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0" #define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0" #define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0" #define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0" @@ -251,15 +285,17 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Zp0 STR_Z STR_p "\0" #define STRING_Zs0 STR_Z STR_s "\0" -const char _pcre_utt_names[] = +const char PRIV(utt_names)[] = STRING_Any0 STRING_Arabic0 STRING_Armenian0 STRING_Avestan0 STRING_Balinese0 STRING_Bamum0 + STRING_Batak0 STRING_Bengali0 STRING_Bopomofo0 + STRING_Brahmi0 STRING_Braille0 STRING_Buginese0 STRING_Buhid0 @@ -268,6 +304,7 @@ const char _pcre_utt_names[] = STRING_Carian0 STRING_Cc0 STRING_Cf0 + STRING_Chakma0 STRING_Cham0 STRING_Cherokee0 STRING_Cn0 @@ -321,9 +358,13 @@ const char _pcre_utt_names[] = STRING_Lydian0 STRING_M0 STRING_Malayalam0 + STRING_Mandaic0 STRING_Mc0 STRING_Me0 STRING_Meetei_Mayek0 + STRING_Meroitic_Cursive0 + STRING_Meroitic_Hieroglyphs0 + STRING_Miao0 STRING_Mn0 STRING_Mongolian0 STRING_Myanmar0 @@ -357,11 +398,13 @@ const char _pcre_utt_names[] = STRING_Samaritan0 STRING_Saurashtra0 STRING_Sc0 + STRING_Sharada0 STRING_Shavian0 STRING_Sinhala0 STRING_Sk0 STRING_Sm0 STRING_So0 + STRING_Sora_Sompeng0 STRING_Sundanese0 STRING_Syloti_Nagri0 STRING_Syriac0 @@ -370,6 +413,7 @@ const char _pcre_utt_names[] = STRING_Tai_Le0 STRING_Tai_Tham0 STRING_Tai_Viet0 + STRING_Takri0 STRING_Tamil0 STRING_Telugu0 STRING_Thaana0 @@ -388,146 +432,156 @@ const char _pcre_utt_names[] = STRING_Zp0 STRING_Zs0; -const ucp_type_table _pcre_utt[] = { +const ucp_type_table PRIV(utt)[] = { { 0, PT_ANY, 0 }, { 4, PT_SC, ucp_Arabic }, { 11, PT_SC, ucp_Armenian }, { 20, PT_SC, ucp_Avestan }, { 28, PT_SC, ucp_Balinese }, { 37, PT_SC, ucp_Bamum }, - { 43, PT_SC, ucp_Bengali }, - { 51, PT_SC, ucp_Bopomofo }, - { 60, PT_SC, ucp_Braille }, - { 68, PT_SC, ucp_Buginese }, - { 77, PT_SC, ucp_Buhid }, - { 83, PT_GC, ucp_C }, - { 85, PT_SC, ucp_Canadian_Aboriginal }, - { 105, PT_SC, ucp_Carian }, - { 112, PT_PC, ucp_Cc }, - { 115, PT_PC, ucp_Cf }, - { 118, PT_SC, ucp_Cham }, - { 123, PT_SC, ucp_Cherokee }, - { 132, PT_PC, ucp_Cn }, - { 135, PT_PC, ucp_Co }, - { 138, PT_SC, ucp_Common }, - { 145, PT_SC, ucp_Coptic }, - { 152, PT_PC, ucp_Cs }, - { 155, PT_SC, ucp_Cuneiform }, - { 165, PT_SC, ucp_Cypriot }, - { 173, PT_SC, ucp_Cyrillic }, - { 182, PT_SC, ucp_Deseret }, - { 190, PT_SC, ucp_Devanagari }, - { 201, PT_SC, ucp_Egyptian_Hieroglyphs }, - { 222, PT_SC, ucp_Ethiopic }, - { 231, PT_SC, ucp_Georgian }, - { 240, PT_SC, ucp_Glagolitic }, - { 251, PT_SC, ucp_Gothic }, - { 258, PT_SC, ucp_Greek }, - { 264, PT_SC, ucp_Gujarati }, - { 273, PT_SC, ucp_Gurmukhi }, - { 282, PT_SC, ucp_Han }, - { 286, PT_SC, ucp_Hangul }, - { 293, PT_SC, ucp_Hanunoo }, - { 301, PT_SC, ucp_Hebrew }, - { 308, PT_SC, ucp_Hiragana }, - { 317, PT_SC, ucp_Imperial_Aramaic }, - { 334, PT_SC, ucp_Inherited }, - { 344, PT_SC, ucp_Inscriptional_Pahlavi }, - { 366, PT_SC, ucp_Inscriptional_Parthian }, - { 389, PT_SC, ucp_Javanese }, - { 398, PT_SC, ucp_Kaithi }, - { 405, PT_SC, ucp_Kannada }, - { 413, PT_SC, ucp_Katakana }, - { 422, PT_SC, ucp_Kayah_Li }, - { 431, PT_SC, ucp_Kharoshthi }, - { 442, PT_SC, ucp_Khmer }, - { 448, PT_GC, ucp_L }, - { 450, PT_LAMP, 0 }, - { 453, PT_SC, ucp_Lao }, - { 457, PT_SC, ucp_Latin }, - { 463, PT_SC, ucp_Lepcha }, - { 470, PT_SC, ucp_Limbu }, - { 476, PT_SC, ucp_Linear_B }, - { 485, PT_SC, ucp_Lisu }, - { 490, PT_PC, ucp_Ll }, - { 493, PT_PC, ucp_Lm }, - { 496, PT_PC, ucp_Lo }, - { 499, PT_PC, ucp_Lt }, - { 502, PT_PC, ucp_Lu }, - { 505, PT_SC, ucp_Lycian }, - { 512, PT_SC, ucp_Lydian }, - { 519, PT_GC, ucp_M }, - { 521, PT_SC, ucp_Malayalam }, - { 531, PT_PC, ucp_Mc }, - { 534, PT_PC, ucp_Me }, - { 537, PT_SC, ucp_Meetei_Mayek }, - { 550, PT_PC, ucp_Mn }, - { 553, PT_SC, ucp_Mongolian }, - { 563, PT_SC, ucp_Myanmar }, - { 571, PT_GC, ucp_N }, - { 573, PT_PC, ucp_Nd }, - { 576, PT_SC, ucp_New_Tai_Lue }, - { 588, PT_SC, ucp_Nko }, - { 592, PT_PC, ucp_Nl }, - { 595, PT_PC, ucp_No }, - { 598, PT_SC, ucp_Ogham }, - { 604, PT_SC, ucp_Ol_Chiki }, - { 613, PT_SC, ucp_Old_Italic }, - { 624, PT_SC, ucp_Old_Persian }, - { 636, PT_SC, ucp_Old_South_Arabian }, - { 654, PT_SC, ucp_Old_Turkic }, - { 665, PT_SC, ucp_Oriya }, - { 671, PT_SC, ucp_Osmanya }, - { 679, PT_GC, ucp_P }, - { 681, PT_PC, ucp_Pc }, - { 684, PT_PC, ucp_Pd }, - { 687, PT_PC, ucp_Pe }, - { 690, PT_PC, ucp_Pf }, - { 693, PT_SC, ucp_Phags_Pa }, - { 702, PT_SC, ucp_Phoenician }, - { 713, PT_PC, ucp_Pi }, - { 716, PT_PC, ucp_Po }, - { 719, PT_PC, ucp_Ps }, - { 722, PT_SC, ucp_Rejang }, - { 729, PT_SC, ucp_Runic }, - { 735, PT_GC, ucp_S }, - { 737, PT_SC, ucp_Samaritan }, - { 747, PT_SC, ucp_Saurashtra }, - { 758, PT_PC, ucp_Sc }, - { 761, PT_SC, ucp_Shavian }, - { 769, PT_SC, ucp_Sinhala }, - { 777, PT_PC, ucp_Sk }, - { 780, PT_PC, ucp_Sm }, - { 783, PT_PC, ucp_So }, - { 786, PT_SC, ucp_Sundanese }, - { 796, PT_SC, ucp_Syloti_Nagri }, - { 809, PT_SC, ucp_Syriac }, - { 816, PT_SC, ucp_Tagalog }, - { 824, PT_SC, ucp_Tagbanwa }, - { 833, PT_SC, ucp_Tai_Le }, - { 840, PT_SC, ucp_Tai_Tham }, - { 849, PT_SC, ucp_Tai_Viet }, - { 858, PT_SC, ucp_Tamil }, - { 864, PT_SC, ucp_Telugu }, - { 871, PT_SC, ucp_Thaana }, - { 878, PT_SC, ucp_Thai }, - { 883, PT_SC, ucp_Tibetan }, - { 891, PT_SC, ucp_Tifinagh }, - { 900, PT_SC, ucp_Ugaritic }, - { 909, PT_SC, ucp_Vai }, - { 913, PT_ALNUM, 0 }, - { 917, PT_PXSPACE, 0 }, - { 921, PT_SPACE, 0 }, - { 925, PT_WORD, 0 }, - { 929, PT_SC, ucp_Yi }, - { 932, PT_GC, ucp_Z }, - { 934, PT_PC, ucp_Zl }, - { 937, PT_PC, ucp_Zp }, - { 940, PT_PC, ucp_Zs } + { 43, PT_SC, ucp_Batak }, + { 49, PT_SC, ucp_Bengali }, + { 57, PT_SC, ucp_Bopomofo }, + { 66, PT_SC, ucp_Brahmi }, + { 73, PT_SC, ucp_Braille }, + { 81, PT_SC, ucp_Buginese }, + { 90, PT_SC, ucp_Buhid }, + { 96, PT_GC, ucp_C }, + { 98, PT_SC, ucp_Canadian_Aboriginal }, + { 118, PT_SC, ucp_Carian }, + { 125, PT_PC, ucp_Cc }, + { 128, PT_PC, ucp_Cf }, + { 131, PT_SC, ucp_Chakma }, + { 138, PT_SC, ucp_Cham }, + { 143, PT_SC, ucp_Cherokee }, + { 152, PT_PC, ucp_Cn }, + { 155, PT_PC, ucp_Co }, + { 158, PT_SC, ucp_Common }, + { 165, PT_SC, ucp_Coptic }, + { 172, PT_PC, ucp_Cs }, + { 175, PT_SC, ucp_Cuneiform }, + { 185, PT_SC, ucp_Cypriot }, + { 193, PT_SC, ucp_Cyrillic }, + { 202, PT_SC, ucp_Deseret }, + { 210, PT_SC, ucp_Devanagari }, + { 221, PT_SC, ucp_Egyptian_Hieroglyphs }, + { 242, PT_SC, ucp_Ethiopic }, + { 251, PT_SC, ucp_Georgian }, + { 260, PT_SC, ucp_Glagolitic }, + { 271, PT_SC, ucp_Gothic }, + { 278, PT_SC, ucp_Greek }, + { 284, PT_SC, ucp_Gujarati }, + { 293, PT_SC, ucp_Gurmukhi }, + { 302, PT_SC, ucp_Han }, + { 306, PT_SC, ucp_Hangul }, + { 313, PT_SC, ucp_Hanunoo }, + { 321, PT_SC, ucp_Hebrew }, + { 328, PT_SC, ucp_Hiragana }, + { 337, PT_SC, ucp_Imperial_Aramaic }, + { 354, PT_SC, ucp_Inherited }, + { 364, PT_SC, ucp_Inscriptional_Pahlavi }, + { 386, PT_SC, ucp_Inscriptional_Parthian }, + { 409, PT_SC, ucp_Javanese }, + { 418, PT_SC, ucp_Kaithi }, + { 425, PT_SC, ucp_Kannada }, + { 433, PT_SC, ucp_Katakana }, + { 442, PT_SC, ucp_Kayah_Li }, + { 451, PT_SC, ucp_Kharoshthi }, + { 462, PT_SC, ucp_Khmer }, + { 468, PT_GC, ucp_L }, + { 470, PT_LAMP, 0 }, + { 473, PT_SC, ucp_Lao }, + { 477, PT_SC, ucp_Latin }, + { 483, PT_SC, ucp_Lepcha }, + { 490, PT_SC, ucp_Limbu }, + { 496, PT_SC, ucp_Linear_B }, + { 505, PT_SC, ucp_Lisu }, + { 510, PT_PC, ucp_Ll }, + { 513, PT_PC, ucp_Lm }, + { 516, PT_PC, ucp_Lo }, + { 519, PT_PC, ucp_Lt }, + { 522, PT_PC, ucp_Lu }, + { 525, PT_SC, ucp_Lycian }, + { 532, PT_SC, ucp_Lydian }, + { 539, PT_GC, ucp_M }, + { 541, PT_SC, ucp_Malayalam }, + { 551, PT_SC, ucp_Mandaic }, + { 559, PT_PC, ucp_Mc }, + { 562, PT_PC, ucp_Me }, + { 565, PT_SC, ucp_Meetei_Mayek }, + { 578, PT_SC, ucp_Meroitic_Cursive }, + { 595, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 616, PT_SC, ucp_Miao }, + { 621, PT_PC, ucp_Mn }, + { 624, PT_SC, ucp_Mongolian }, + { 634, PT_SC, ucp_Myanmar }, + { 642, PT_GC, ucp_N }, + { 644, PT_PC, ucp_Nd }, + { 647, PT_SC, ucp_New_Tai_Lue }, + { 659, PT_SC, ucp_Nko }, + { 663, PT_PC, ucp_Nl }, + { 666, PT_PC, ucp_No }, + { 669, PT_SC, ucp_Ogham }, + { 675, PT_SC, ucp_Ol_Chiki }, + { 684, PT_SC, ucp_Old_Italic }, + { 695, PT_SC, ucp_Old_Persian }, + { 707, PT_SC, ucp_Old_South_Arabian }, + { 725, PT_SC, ucp_Old_Turkic }, + { 736, PT_SC, ucp_Oriya }, + { 742, PT_SC, ucp_Osmanya }, + { 750, PT_GC, ucp_P }, + { 752, PT_PC, ucp_Pc }, + { 755, PT_PC, ucp_Pd }, + { 758, PT_PC, ucp_Pe }, + { 761, PT_PC, ucp_Pf }, + { 764, PT_SC, ucp_Phags_Pa }, + { 773, PT_SC, ucp_Phoenician }, + { 784, PT_PC, ucp_Pi }, + { 787, PT_PC, ucp_Po }, + { 790, PT_PC, ucp_Ps }, + { 793, PT_SC, ucp_Rejang }, + { 800, PT_SC, ucp_Runic }, + { 806, PT_GC, ucp_S }, + { 808, PT_SC, ucp_Samaritan }, + { 818, PT_SC, ucp_Saurashtra }, + { 829, PT_PC, ucp_Sc }, + { 832, PT_SC, ucp_Sharada }, + { 840, PT_SC, ucp_Shavian }, + { 848, PT_SC, ucp_Sinhala }, + { 856, PT_PC, ucp_Sk }, + { 859, PT_PC, ucp_Sm }, + { 862, PT_PC, ucp_So }, + { 865, PT_SC, ucp_Sora_Sompeng }, + { 878, PT_SC, ucp_Sundanese }, + { 888, PT_SC, ucp_Syloti_Nagri }, + { 901, PT_SC, ucp_Syriac }, + { 908, PT_SC, ucp_Tagalog }, + { 916, PT_SC, ucp_Tagbanwa }, + { 925, PT_SC, ucp_Tai_Le }, + { 932, PT_SC, ucp_Tai_Tham }, + { 941, PT_SC, ucp_Tai_Viet }, + { 950, PT_SC, ucp_Takri }, + { 956, PT_SC, ucp_Tamil }, + { 962, PT_SC, ucp_Telugu }, + { 969, PT_SC, ucp_Thaana }, + { 976, PT_SC, ucp_Thai }, + { 981, PT_SC, ucp_Tibetan }, + { 989, PT_SC, ucp_Tifinagh }, + { 998, PT_SC, ucp_Ugaritic }, + { 1007, PT_SC, ucp_Vai }, + { 1011, PT_ALNUM, 0 }, + { 1015, PT_PXSPACE, 0 }, + { 1019, PT_SPACE, 0 }, + { 1023, PT_WORD, 0 }, + { 1027, PT_SC, ucp_Yi }, + { 1030, PT_GC, ucp_Z }, + { 1032, PT_PC, ucp_Zl }, + { 1035, PT_PC, ucp_Zp }, + { 1038, PT_PC, ucp_Zs } }; -const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table); +const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* End of pcre_tables.c */ diff --git a/ext/pcre/pcrelib/pcre_try_flipped.c b/ext/pcre/pcrelib/pcre_try_flipped.c deleted file mode 100644 index 91ec76aae01..00000000000 --- a/ext/pcre/pcrelib/pcre_try_flipped.c +++ /dev/null @@ -1,137 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains an internal function that tests a compiled pattern to -see if it was compiled with the opposite endianness. If so, it uses an -auxiliary local function to flip the appropriate bytes. */ - - -#include "config.h" - -#include "pcre_internal.h" - - -/************************************************* -* Flip bytes in an integer * -*************************************************/ - -/* This function is called when the magic number in a regex doesn't match, in -order to flip its bytes to see if we are dealing with a pattern that was -compiled on a host of different endianness. If so, this function is used to -flip other byte values. - -Arguments: - value the number to flip - n the number of bytes to flip (assumed to be 2 or 4) - -Returns: the flipped value -*/ - -static unsigned long int -byteflip(unsigned long int value, int n) -{ -if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); -return ((value & 0x000000ff) << 24) | - ((value & 0x0000ff00) << 8) | - ((value & 0x00ff0000) >> 8) | - ((value & 0xff000000) >> 24); -} - - - -/************************************************* -* Test for a byte-flipped compiled regex * -*************************************************/ - -/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from -pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that -is, it was compiled on a system of opposite endianness. The function is called -only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped, -we flip all the relevant values into a different data block, and return it. - -Arguments: - re points to the regex - study points to study data, or NULL - internal_re points to a new regex block - internal_study points to a new study block - -Returns: the new block if is is indeed a byte-flipped regex - NULL if it is not -*/ - -real_pcre * -_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re, - const pcre_study_data *study, pcre_study_data *internal_study) -{ -if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER) - return NULL; - -*internal_re = *re; /* To copy other fields */ -internal_re->size = byteflip(re->size, sizeof(re->size)); -internal_re->options = byteflip(re->options, sizeof(re->options)); -internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags)); -internal_re->top_bracket = - (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket)); -internal_re->top_backref = - (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref)); -internal_re->first_byte = - (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte)); -internal_re->req_byte = - (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte)); -internal_re->name_table_offset = - (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset)); -internal_re->name_entry_size = - (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size)); -internal_re->name_count = - (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count)); - -if (study != NULL) - { - *internal_study = *study; /* To copy other fields */ - internal_study->size = byteflip(study->size, sizeof(study->size)); - internal_study->flags = byteflip(study->flags, sizeof(study->flags)); - internal_study->minlength = byteflip(study->minlength, - sizeof(study->minlength)); - } - -return internal_re; -} - -/* End of pcre_tryflipped.c */ diff --git a/ext/pcre/pcrelib/pcre_ucd.c b/ext/pcre/pcrelib/pcre_ucd.c index b1dfc03863a..39b59185a1b 100644 --- a/ext/pcre/pcrelib/pcre_ucd.c +++ b/ext/pcre/pcrelib/pcre_ucd.c @@ -4,7 +4,7 @@ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 56880 bytes, block size: 128. */ +/* Total size: 62904 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built */ /* into PCRE. This module should not be referenced otherwise, so */ @@ -16,21 +16,21 @@ /* Instead, just supply small dummy tables. */ #ifndef SUPPORT_UCP -const ucd_record _pcre_ucd_records[] = {{0,0,0 }}; -const uschar _pcre_ucd_stage1[] = {0}; -const pcre_uint16 _pcre_ucd_stage2[] = {0}; +const ucd_record PRIV(ucd_records)[] = {{0,0,0 }}; +const pcre_uint8 PRIV(ucd_stage1)[] = {0}; +const pcre_uint16 PRIV(ucd_stage2)[] = {0}; #else /* When recompiling tables with a new Unicode version, please check types in the structure definition from pcre_internal.h: typedef struct { -uschar property_0; -uschar property_1; +pcre_uint8 property_0; +pcre_uint8 property_1; pcre_int32 property_2; } ucd_record; */ -const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */ +const ucd_record PRIV(ucd_records)[] = { /* 4536 bytes, record size 8 */ { 9, 0, 0, }, /* 0 */ { 9, 29, 0, }, /* 1 */ { 9, 21, 0, }, /* 2 */ @@ -45,38 +45,38 @@ const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */ { 9, 16, 0, }, /* 11 */ { 33, 5, -32, }, /* 12 */ { 9, 26, 0, }, /* 13 */ - { 33, 5, 0, }, /* 14 */ + { 33, 7, 0, }, /* 14 */ { 9, 20, 0, }, /* 15 */ { 9, 1, 0, }, /* 16 */ { 9, 15, 0, }, /* 17 */ { 9, 5, 743, }, /* 18 */ { 9, 19, 0, }, /* 19 */ - { 33, 5, 121, }, /* 20 */ - { 33, 9, 1, }, /* 21 */ - { 33, 5, -1, }, /* 22 */ - { 33, 9, -199, }, /* 23 */ - { 33, 5, -232, }, /* 24 */ - { 33, 9, -121, }, /* 25 */ - { 33, 5, -300, }, /* 26 */ - { 33, 5, 195, }, /* 27 */ - { 33, 9, 210, }, /* 28 */ - { 33, 9, 206, }, /* 29 */ - { 33, 9, 205, }, /* 30 */ - { 33, 9, 79, }, /* 31 */ - { 33, 9, 202, }, /* 32 */ - { 33, 9, 203, }, /* 33 */ - { 33, 9, 207, }, /* 34 */ - { 33, 5, 97, }, /* 35 */ - { 33, 9, 211, }, /* 36 */ - { 33, 9, 209, }, /* 37 */ - { 33, 5, 163, }, /* 38 */ - { 33, 9, 213, }, /* 39 */ - { 33, 5, 130, }, /* 40 */ - { 33, 9, 214, }, /* 41 */ - { 33, 9, 218, }, /* 42 */ - { 33, 9, 217, }, /* 43 */ - { 33, 9, 219, }, /* 44 */ - { 33, 7, 0, }, /* 45 */ + { 33, 5, 0, }, /* 20 */ + { 33, 5, 121, }, /* 21 */ + { 33, 9, 1, }, /* 22 */ + { 33, 5, -1, }, /* 23 */ + { 33, 9, -199, }, /* 24 */ + { 33, 5, -232, }, /* 25 */ + { 33, 9, -121, }, /* 26 */ + { 33, 5, -300, }, /* 27 */ + { 33, 5, 195, }, /* 28 */ + { 33, 9, 210, }, /* 29 */ + { 33, 9, 206, }, /* 30 */ + { 33, 9, 205, }, /* 31 */ + { 33, 9, 79, }, /* 32 */ + { 33, 9, 202, }, /* 33 */ + { 33, 9, 203, }, /* 34 */ + { 33, 9, 207, }, /* 35 */ + { 33, 5, 97, }, /* 36 */ + { 33, 9, 211, }, /* 37 */ + { 33, 9, 209, }, /* 38 */ + { 33, 5, 163, }, /* 39 */ + { 33, 9, 213, }, /* 40 */ + { 33, 5, 130, }, /* 41 */ + { 33, 9, 214, }, /* 42 */ + { 33, 9, 218, }, /* 43 */ + { 33, 9, 217, }, /* 44 */ + { 33, 9, 219, }, /* 45 */ { 33, 5, 56, }, /* 46 */ { 33, 9, 2, }, /* 47 */ { 33, 8, -1, }, /* 48 */ @@ -101,463 +101,512 @@ const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */ { 33, 5, -202, }, /* 67 */ { 33, 5, -203, }, /* 68 */ { 33, 5, -207, }, /* 69 */ - { 33, 5, -209, }, /* 70 */ - { 33, 5, -211, }, /* 71 */ - { 33, 5, 10743, }, /* 72 */ - { 33, 5, 10749, }, /* 73 */ - { 33, 5, -213, }, /* 74 */ - { 33, 5, -214, }, /* 75 */ - { 33, 5, 10727, }, /* 76 */ - { 33, 5, -218, }, /* 77 */ - { 33, 5, -69, }, /* 78 */ - { 33, 5, -217, }, /* 79 */ - { 33, 5, -71, }, /* 80 */ - { 33, 5, -219, }, /* 81 */ - { 33, 6, 0, }, /* 82 */ - { 9, 6, 0, }, /* 83 */ - { 27, 12, 0, }, /* 84 */ - { 27, 12, 84, }, /* 85 */ - { 19, 9, 1, }, /* 86 */ - { 19, 5, -1, }, /* 87 */ - { 19, 24, 0, }, /* 88 */ - { 9, 2, 0, }, /* 89 */ - { 19, 6, 0, }, /* 90 */ - { 19, 5, 130, }, /* 91 */ - { 19, 9, 38, }, /* 92 */ - { 19, 9, 37, }, /* 93 */ - { 19, 9, 64, }, /* 94 */ - { 19, 9, 63, }, /* 95 */ - { 19, 5, 0, }, /* 96 */ - { 19, 9, 32, }, /* 97 */ - { 19, 5, -38, }, /* 98 */ - { 19, 5, -37, }, /* 99 */ - { 19, 5, -32, }, /* 100 */ - { 19, 5, -31, }, /* 101 */ - { 19, 5, -64, }, /* 102 */ - { 19, 5, -63, }, /* 103 */ - { 19, 9, 8, }, /* 104 */ - { 19, 5, -62, }, /* 105 */ - { 19, 5, -57, }, /* 106 */ - { 19, 9, 0, }, /* 107 */ - { 19, 5, -47, }, /* 108 */ - { 19, 5, -54, }, /* 109 */ - { 19, 5, -8, }, /* 110 */ - { 10, 9, 1, }, /* 111 */ - { 10, 5, -1, }, /* 112 */ - { 19, 5, -86, }, /* 113 */ - { 19, 5, -80, }, /* 114 */ - { 19, 5, 7, }, /* 115 */ - { 19, 9, -60, }, /* 116 */ - { 19, 5, -96, }, /* 117 */ - { 19, 25, 0, }, /* 118 */ - { 19, 9, -7, }, /* 119 */ - { 19, 9, -130, }, /* 120 */ - { 12, 9, 80, }, /* 121 */ - { 12, 9, 32, }, /* 122 */ - { 12, 5, -32, }, /* 123 */ - { 12, 5, -80, }, /* 124 */ - { 12, 9, 1, }, /* 125 */ - { 12, 5, -1, }, /* 126 */ - { 12, 26, 0, }, /* 127 */ - { 12, 12, 0, }, /* 128 */ - { 12, 11, 0, }, /* 129 */ - { 12, 9, 15, }, /* 130 */ - { 12, 5, -15, }, /* 131 */ - { 1, 9, 48, }, /* 132 */ - { 1, 6, 0, }, /* 133 */ - { 1, 21, 0, }, /* 134 */ - { 1, 5, -48, }, /* 135 */ - { 1, 5, 0, }, /* 136 */ - { 1, 17, 0, }, /* 137 */ - { 25, 12, 0, }, /* 138 */ - { 25, 17, 0, }, /* 139 */ - { 25, 21, 0, }, /* 140 */ - { 25, 7, 0, }, /* 141 */ - { 0, 25, 0, }, /* 142 */ - { 0, 21, 0, }, /* 143 */ - { 0, 23, 0, }, /* 144 */ - { 0, 26, 0, }, /* 145 */ - { 0, 12, 0, }, /* 146 */ - { 0, 7, 0, }, /* 147 */ - { 0, 11, 0, }, /* 148 */ - { 0, 6, 0, }, /* 149 */ - { 0, 13, 0, }, /* 150 */ - { 49, 21, 0, }, /* 151 */ - { 49, 1, 0, }, /* 152 */ - { 49, 7, 0, }, /* 153 */ - { 49, 12, 0, }, /* 154 */ - { 55, 7, 0, }, /* 155 */ - { 55, 12, 0, }, /* 156 */ - { 63, 13, 0, }, /* 157 */ - { 63, 7, 0, }, /* 158 */ - { 63, 12, 0, }, /* 159 */ - { 63, 6, 0, }, /* 160 */ - { 63, 26, 0, }, /* 161 */ - { 63, 21, 0, }, /* 162 */ - { 89, 7, 0, }, /* 163 */ - { 89, 12, 0, }, /* 164 */ - { 89, 6, 0, }, /* 165 */ - { 89, 21, 0, }, /* 166 */ - { 14, 12, 0, }, /* 167 */ - { 14, 10, 0, }, /* 168 */ - { 14, 7, 0, }, /* 169 */ - { 14, 13, 0, }, /* 170 */ - { 14, 6, 0, }, /* 171 */ - { 2, 12, 0, }, /* 172 */ - { 2, 10, 0, }, /* 173 */ - { 2, 7, 0, }, /* 174 */ - { 2, 13, 0, }, /* 175 */ - { 2, 23, 0, }, /* 176 */ - { 2, 15, 0, }, /* 177 */ - { 2, 26, 0, }, /* 178 */ - { 21, 12, 0, }, /* 179 */ - { 21, 10, 0, }, /* 180 */ - { 21, 7, 0, }, /* 181 */ - { 21, 13, 0, }, /* 182 */ - { 20, 12, 0, }, /* 183 */ - { 20, 10, 0, }, /* 184 */ - { 20, 7, 0, }, /* 185 */ - { 20, 13, 0, }, /* 186 */ - { 20, 23, 0, }, /* 187 */ - { 43, 12, 0, }, /* 188 */ - { 43, 10, 0, }, /* 189 */ - { 43, 7, 0, }, /* 190 */ - { 43, 13, 0, }, /* 191 */ - { 43, 26, 0, }, /* 192 */ - { 53, 12, 0, }, /* 193 */ - { 53, 7, 0, }, /* 194 */ - { 53, 10, 0, }, /* 195 */ - { 53, 13, 0, }, /* 196 */ - { 53, 15, 0, }, /* 197 */ - { 53, 26, 0, }, /* 198 */ - { 53, 23, 0, }, /* 199 */ - { 54, 10, 0, }, /* 200 */ - { 54, 7, 0, }, /* 201 */ - { 54, 12, 0, }, /* 202 */ - { 54, 13, 0, }, /* 203 */ - { 54, 15, 0, }, /* 204 */ - { 54, 26, 0, }, /* 205 */ - { 28, 10, 0, }, /* 206 */ - { 28, 7, 0, }, /* 207 */ - { 28, 12, 0, }, /* 208 */ - { 28, 13, 0, }, /* 209 */ - { 36, 10, 0, }, /* 210 */ - { 36, 7, 0, }, /* 211 */ - { 36, 12, 0, }, /* 212 */ - { 36, 13, 0, }, /* 213 */ - { 36, 15, 0, }, /* 214 */ - { 36, 26, 0, }, /* 215 */ - { 47, 10, 0, }, /* 216 */ - { 47, 7, 0, }, /* 217 */ - { 47, 12, 0, }, /* 218 */ - { 47, 21, 0, }, /* 219 */ - { 56, 7, 0, }, /* 220 */ - { 56, 12, 0, }, /* 221 */ - { 56, 6, 0, }, /* 222 */ - { 56, 21, 0, }, /* 223 */ - { 56, 13, 0, }, /* 224 */ - { 32, 7, 0, }, /* 225 */ - { 32, 12, 0, }, /* 226 */ - { 32, 6, 0, }, /* 227 */ - { 32, 13, 0, }, /* 228 */ - { 57, 7, 0, }, /* 229 */ - { 57, 26, 0, }, /* 230 */ - { 57, 21, 0, }, /* 231 */ - { 57, 12, 0, }, /* 232 */ - { 57, 13, 0, }, /* 233 */ - { 57, 15, 0, }, /* 234 */ - { 57, 22, 0, }, /* 235 */ - { 57, 18, 0, }, /* 236 */ - { 57, 10, 0, }, /* 237 */ - { 38, 7, 0, }, /* 238 */ - { 38, 10, 0, }, /* 239 */ - { 38, 12, 0, }, /* 240 */ - { 38, 13, 0, }, /* 241 */ - { 38, 21, 0, }, /* 242 */ - { 38, 26, 0, }, /* 243 */ - { 16, 9, 7264, }, /* 244 */ - { 16, 7, 0, }, /* 245 */ - { 16, 6, 0, }, /* 246 */ - { 23, 7, 0, }, /* 247 */ - { 15, 7, 0, }, /* 248 */ - { 15, 12, 0, }, /* 249 */ - { 15, 26, 0, }, /* 250 */ - { 15, 21, 0, }, /* 251 */ - { 15, 15, 0, }, /* 252 */ - { 8, 7, 0, }, /* 253 */ - { 7, 17, 0, }, /* 254 */ - { 7, 7, 0, }, /* 255 */ - { 7, 21, 0, }, /* 256 */ - { 40, 29, 0, }, /* 257 */ - { 40, 7, 0, }, /* 258 */ - { 40, 22, 0, }, /* 259 */ - { 40, 18, 0, }, /* 260 */ - { 45, 7, 0, }, /* 261 */ - { 45, 14, 0, }, /* 262 */ - { 50, 7, 0, }, /* 263 */ - { 50, 12, 0, }, /* 264 */ - { 24, 7, 0, }, /* 265 */ - { 24, 12, 0, }, /* 266 */ - { 6, 7, 0, }, /* 267 */ - { 6, 12, 0, }, /* 268 */ - { 51, 7, 0, }, /* 269 */ - { 51, 12, 0, }, /* 270 */ - { 31, 7, 0, }, /* 271 */ - { 31, 1, 0, }, /* 272 */ - { 31, 10, 0, }, /* 273 */ - { 31, 12, 0, }, /* 274 */ - { 31, 21, 0, }, /* 275 */ - { 31, 6, 0, }, /* 276 */ - { 31, 23, 0, }, /* 277 */ - { 31, 13, 0, }, /* 278 */ - { 31, 15, 0, }, /* 279 */ - { 37, 21, 0, }, /* 280 */ - { 37, 17, 0, }, /* 281 */ - { 37, 12, 0, }, /* 282 */ - { 37, 29, 0, }, /* 283 */ - { 37, 13, 0, }, /* 284 */ - { 37, 7, 0, }, /* 285 */ - { 37, 6, 0, }, /* 286 */ - { 34, 7, 0, }, /* 287 */ - { 34, 12, 0, }, /* 288 */ - { 34, 10, 0, }, /* 289 */ - { 34, 26, 0, }, /* 290 */ - { 34, 21, 0, }, /* 291 */ - { 34, 13, 0, }, /* 292 */ - { 52, 7, 0, }, /* 293 */ - { 39, 7, 0, }, /* 294 */ - { 39, 10, 0, }, /* 295 */ - { 39, 13, 0, }, /* 296 */ - { 39, 21, 0, }, /* 297 */ - { 31, 26, 0, }, /* 298 */ - { 5, 7, 0, }, /* 299 */ - { 5, 12, 0, }, /* 300 */ - { 5, 10, 0, }, /* 301 */ - { 5, 21, 0, }, /* 302 */ - { 90, 7, 0, }, /* 303 */ - { 90, 10, 0, }, /* 304 */ - { 90, 12, 0, }, /* 305 */ - { 90, 13, 0, }, /* 306 */ - { 90, 21, 0, }, /* 307 */ - { 90, 6, 0, }, /* 308 */ - { 61, 12, 0, }, /* 309 */ - { 61, 10, 0, }, /* 310 */ - { 61, 7, 0, }, /* 311 */ - { 61, 13, 0, }, /* 312 */ - { 61, 21, 0, }, /* 313 */ - { 61, 26, 0, }, /* 314 */ - { 75, 12, 0, }, /* 315 */ - { 75, 10, 0, }, /* 316 */ - { 75, 7, 0, }, /* 317 */ - { 75, 13, 0, }, /* 318 */ - { 69, 7, 0, }, /* 319 */ - { 69, 10, 0, }, /* 320 */ - { 69, 12, 0, }, /* 321 */ - { 69, 21, 0, }, /* 322 */ - { 69, 13, 0, }, /* 323 */ - { 72, 13, 0, }, /* 324 */ - { 72, 7, 0, }, /* 325 */ - { 72, 6, 0, }, /* 326 */ - { 72, 21, 0, }, /* 327 */ - { 9, 10, 0, }, /* 328 */ - { 9, 7, 0, }, /* 329 */ - { 12, 5, 0, }, /* 330 */ - { 12, 6, 0, }, /* 331 */ - { 33, 5, 35332, }, /* 332 */ - { 33, 5, 3814, }, /* 333 */ - { 33, 5, -59, }, /* 334 */ - { 33, 9, -7615, }, /* 335 */ - { 19, 5, 8, }, /* 336 */ - { 19, 9, -8, }, /* 337 */ - { 19, 5, 74, }, /* 338 */ - { 19, 5, 86, }, /* 339 */ - { 19, 5, 100, }, /* 340 */ - { 19, 5, 128, }, /* 341 */ - { 19, 5, 112, }, /* 342 */ - { 19, 5, 126, }, /* 343 */ - { 19, 8, -8, }, /* 344 */ - { 19, 5, 9, }, /* 345 */ - { 19, 9, -74, }, /* 346 */ - { 19, 8, -9, }, /* 347 */ - { 19, 5, -7205, }, /* 348 */ - { 19, 9, -86, }, /* 349 */ - { 19, 9, -100, }, /* 350 */ - { 19, 9, -112, }, /* 351 */ - { 19, 9, -128, }, /* 352 */ - { 19, 9, -126, }, /* 353 */ - { 27, 1, 0, }, /* 354 */ - { 9, 27, 0, }, /* 355 */ - { 9, 28, 0, }, /* 356 */ - { 27, 11, 0, }, /* 357 */ - { 9, 9, 0, }, /* 358 */ - { 9, 5, 0, }, /* 359 */ - { 19, 9, -7517, }, /* 360 */ - { 33, 9, -8383, }, /* 361 */ - { 33, 9, -8262, }, /* 362 */ - { 33, 9, 28, }, /* 363 */ - { 33, 5, -28, }, /* 364 */ - { 33, 14, 16, }, /* 365 */ - { 33, 14, -16, }, /* 366 */ - { 33, 14, 0, }, /* 367 */ - { 9, 26, 26, }, /* 368 */ - { 9, 26, -26, }, /* 369 */ - { 4, 26, 0, }, /* 370 */ - { 17, 9, 48, }, /* 371 */ - { 17, 5, -48, }, /* 372 */ - { 33, 9, -10743, }, /* 373 */ - { 33, 9, -3814, }, /* 374 */ - { 33, 9, -10727, }, /* 375 */ - { 33, 5, -10795, }, /* 376 */ - { 33, 5, -10792, }, /* 377 */ - { 33, 9, -10780, }, /* 378 */ - { 33, 9, -10749, }, /* 379 */ - { 33, 9, -10783, }, /* 380 */ - { 33, 9, -10782, }, /* 381 */ - { 33, 9, -10815, }, /* 382 */ - { 10, 5, 0, }, /* 383 */ - { 10, 26, 0, }, /* 384 */ - { 10, 12, 0, }, /* 385 */ - { 10, 21, 0, }, /* 386 */ - { 10, 15, 0, }, /* 387 */ - { 16, 5, -7264, }, /* 388 */ - { 58, 7, 0, }, /* 389 */ - { 58, 6, 0, }, /* 390 */ - { 22, 26, 0, }, /* 391 */ - { 22, 6, 0, }, /* 392 */ - { 22, 14, 0, }, /* 393 */ - { 26, 7, 0, }, /* 394 */ - { 26, 6, 0, }, /* 395 */ - { 29, 7, 0, }, /* 396 */ - { 29, 6, 0, }, /* 397 */ - { 3, 7, 0, }, /* 398 */ - { 23, 26, 0, }, /* 399 */ - { 29, 26, 0, }, /* 400 */ - { 22, 7, 0, }, /* 401 */ - { 60, 7, 0, }, /* 402 */ - { 60, 6, 0, }, /* 403 */ - { 60, 26, 0, }, /* 404 */ - { 85, 7, 0, }, /* 405 */ - { 85, 6, 0, }, /* 406 */ - { 85, 21, 0, }, /* 407 */ - { 76, 7, 0, }, /* 408 */ - { 76, 6, 0, }, /* 409 */ - { 76, 21, 0, }, /* 410 */ - { 76, 13, 0, }, /* 411 */ - { 12, 7, 0, }, /* 412 */ - { 12, 21, 0, }, /* 413 */ - { 78, 7, 0, }, /* 414 */ - { 78, 14, 0, }, /* 415 */ - { 78, 12, 0, }, /* 416 */ - { 78, 21, 0, }, /* 417 */ - { 33, 9, -35332, }, /* 418 */ - { 48, 7, 0, }, /* 419 */ - { 48, 12, 0, }, /* 420 */ - { 48, 10, 0, }, /* 421 */ - { 48, 26, 0, }, /* 422 */ - { 64, 7, 0, }, /* 423 */ - { 64, 21, 0, }, /* 424 */ - { 74, 10, 0, }, /* 425 */ - { 74, 7, 0, }, /* 426 */ - { 74, 12, 0, }, /* 427 */ - { 74, 21, 0, }, /* 428 */ - { 74, 13, 0, }, /* 429 */ - { 14, 21, 0, }, /* 430 */ - { 68, 13, 0, }, /* 431 */ - { 68, 7, 0, }, /* 432 */ - { 68, 12, 0, }, /* 433 */ - { 68, 21, 0, }, /* 434 */ - { 73, 7, 0, }, /* 435 */ - { 73, 12, 0, }, /* 436 */ - { 73, 10, 0, }, /* 437 */ - { 73, 21, 0, }, /* 438 */ - { 83, 12, 0, }, /* 439 */ - { 83, 10, 0, }, /* 440 */ - { 83, 7, 0, }, /* 441 */ - { 83, 21, 0, }, /* 442 */ - { 83, 6, 0, }, /* 443 */ - { 83, 13, 0, }, /* 444 */ - { 67, 7, 0, }, /* 445 */ - { 67, 12, 0, }, /* 446 */ - { 67, 10, 0, }, /* 447 */ - { 67, 13, 0, }, /* 448 */ - { 67, 21, 0, }, /* 449 */ - { 38, 6, 0, }, /* 450 */ - { 91, 7, 0, }, /* 451 */ - { 91, 12, 0, }, /* 452 */ - { 91, 6, 0, }, /* 453 */ - { 91, 21, 0, }, /* 454 */ - { 86, 7, 0, }, /* 455 */ - { 86, 10, 0, }, /* 456 */ - { 86, 12, 0, }, /* 457 */ - { 86, 21, 0, }, /* 458 */ - { 86, 13, 0, }, /* 459 */ - { 9, 4, 0, }, /* 460 */ - { 9, 3, 0, }, /* 461 */ - { 25, 25, 0, }, /* 462 */ - { 35, 7, 0, }, /* 463 */ - { 19, 14, 0, }, /* 464 */ - { 19, 15, 0, }, /* 465 */ - { 19, 26, 0, }, /* 466 */ - { 70, 7, 0, }, /* 467 */ - { 66, 7, 0, }, /* 468 */ - { 41, 7, 0, }, /* 469 */ - { 41, 15, 0, }, /* 470 */ - { 18, 7, 0, }, /* 471 */ - { 18, 14, 0, }, /* 472 */ - { 59, 7, 0, }, /* 473 */ - { 59, 21, 0, }, /* 474 */ - { 42, 7, 0, }, /* 475 */ - { 42, 21, 0, }, /* 476 */ - { 42, 14, 0, }, /* 477 */ - { 13, 9, 40, }, /* 478 */ - { 13, 5, -40, }, /* 479 */ - { 46, 7, 0, }, /* 480 */ - { 44, 7, 0, }, /* 481 */ - { 44, 13, 0, }, /* 482 */ - { 11, 7, 0, }, /* 483 */ - { 80, 7, 0, }, /* 484 */ - { 80, 21, 0, }, /* 485 */ - { 80, 15, 0, }, /* 486 */ - { 65, 7, 0, }, /* 487 */ - { 65, 15, 0, }, /* 488 */ - { 65, 21, 0, }, /* 489 */ - { 71, 7, 0, }, /* 490 */ - { 71, 21, 0, }, /* 491 */ - { 30, 7, 0, }, /* 492 */ - { 30, 12, 0, }, /* 493 */ - { 30, 15, 0, }, /* 494 */ - { 30, 21, 0, }, /* 495 */ - { 87, 7, 0, }, /* 496 */ - { 87, 15, 0, }, /* 497 */ - { 87, 21, 0, }, /* 498 */ - { 77, 7, 0, }, /* 499 */ - { 77, 21, 0, }, /* 500 */ - { 82, 7, 0, }, /* 501 */ - { 82, 15, 0, }, /* 502 */ - { 81, 7, 0, }, /* 503 */ - { 81, 15, 0, }, /* 504 */ - { 88, 7, 0, }, /* 505 */ - { 0, 15, 0, }, /* 506 */ - { 84, 12, 0, }, /* 507 */ - { 84, 10, 0, }, /* 508 */ - { 84, 7, 0, }, /* 509 */ - { 84, 21, 0, }, /* 510 */ - { 84, 1, 0, }, /* 511 */ - { 62, 7, 0, }, /* 512 */ - { 62, 14, 0, }, /* 513 */ - { 62, 21, 0, }, /* 514 */ - { 79, 7, 0, }, /* 515 */ - { 19, 12, 0, }, /* 516 */ - { 26, 26, 0, }, /* 517 */ + { 33, 5, 42280, }, /* 70 */ + { 33, 5, 42308, }, /* 71 */ + { 33, 5, -209, }, /* 72 */ + { 33, 5, -211, }, /* 73 */ + { 33, 5, 10743, }, /* 74 */ + { 33, 5, 10749, }, /* 75 */ + { 33, 5, -213, }, /* 76 */ + { 33, 5, -214, }, /* 77 */ + { 33, 5, 10727, }, /* 78 */ + { 33, 5, -218, }, /* 79 */ + { 33, 5, -69, }, /* 80 */ + { 33, 5, -217, }, /* 81 */ + { 33, 5, -71, }, /* 82 */ + { 33, 5, -219, }, /* 83 */ + { 33, 6, 0, }, /* 84 */ + { 9, 6, 0, }, /* 85 */ + { 3, 24, 0, }, /* 86 */ + { 27, 12, 0, }, /* 87 */ + { 27, 12, 84, }, /* 88 */ + { 19, 9, 1, }, /* 89 */ + { 19, 5, -1, }, /* 90 */ + { 19, 24, 0, }, /* 91 */ + { 9, 2, 0, }, /* 92 */ + { 19, 6, 0, }, /* 93 */ + { 19, 5, 130, }, /* 94 */ + { 19, 9, 38, }, /* 95 */ + { 19, 9, 37, }, /* 96 */ + { 19, 9, 64, }, /* 97 */ + { 19, 9, 63, }, /* 98 */ + { 19, 5, 0, }, /* 99 */ + { 19, 9, 32, }, /* 100 */ + { 19, 5, -38, }, /* 101 */ + { 19, 5, -37, }, /* 102 */ + { 19, 5, -32, }, /* 103 */ + { 19, 5, -31, }, /* 104 */ + { 19, 5, -64, }, /* 105 */ + { 19, 5, -63, }, /* 106 */ + { 19, 9, 8, }, /* 107 */ + { 19, 5, -62, }, /* 108 */ + { 19, 5, -57, }, /* 109 */ + { 19, 9, 0, }, /* 110 */ + { 19, 5, -47, }, /* 111 */ + { 19, 5, -54, }, /* 112 */ + { 19, 5, -8, }, /* 113 */ + { 10, 9, 1, }, /* 114 */ + { 10, 5, -1, }, /* 115 */ + { 19, 5, -86, }, /* 116 */ + { 19, 5, -80, }, /* 117 */ + { 19, 5, 7, }, /* 118 */ + { 19, 9, -60, }, /* 119 */ + { 19, 5, -96, }, /* 120 */ + { 19, 25, 0, }, /* 121 */ + { 19, 9, -7, }, /* 122 */ + { 19, 9, -130, }, /* 123 */ + { 12, 9, 80, }, /* 124 */ + { 12, 9, 32, }, /* 125 */ + { 12, 5, -32, }, /* 126 */ + { 12, 5, -80, }, /* 127 */ + { 12, 9, 1, }, /* 128 */ + { 12, 5, -1, }, /* 129 */ + { 12, 26, 0, }, /* 130 */ + { 12, 12, 0, }, /* 131 */ + { 12, 11, 0, }, /* 132 */ + { 12, 9, 15, }, /* 133 */ + { 12, 5, -15, }, /* 134 */ + { 1, 9, 48, }, /* 135 */ + { 1, 6, 0, }, /* 136 */ + { 1, 21, 0, }, /* 137 */ + { 1, 5, -48, }, /* 138 */ + { 1, 5, 0, }, /* 139 */ + { 1, 17, 0, }, /* 140 */ + { 1, 23, 0, }, /* 141 */ + { 25, 12, 0, }, /* 142 */ + { 25, 17, 0, }, /* 143 */ + { 25, 21, 0, }, /* 144 */ + { 25, 7, 0, }, /* 145 */ + { 0, 1, 0, }, /* 146 */ + { 0, 25, 0, }, /* 147 */ + { 0, 21, 0, }, /* 148 */ + { 0, 23, 0, }, /* 149 */ + { 0, 26, 0, }, /* 150 */ + { 0, 12, 0, }, /* 151 */ + { 0, 7, 0, }, /* 152 */ + { 0, 6, 0, }, /* 153 */ + { 0, 13, 0, }, /* 154 */ + { 49, 21, 0, }, /* 155 */ + { 49, 1, 0, }, /* 156 */ + { 49, 7, 0, }, /* 157 */ + { 49, 12, 0, }, /* 158 */ + { 55, 7, 0, }, /* 159 */ + { 55, 12, 0, }, /* 160 */ + { 63, 13, 0, }, /* 161 */ + { 63, 7, 0, }, /* 162 */ + { 63, 12, 0, }, /* 163 */ + { 63, 6, 0, }, /* 164 */ + { 63, 26, 0, }, /* 165 */ + { 63, 21, 0, }, /* 166 */ + { 89, 7, 0, }, /* 167 */ + { 89, 12, 0, }, /* 168 */ + { 89, 6, 0, }, /* 169 */ + { 89, 21, 0, }, /* 170 */ + { 94, 7, 0, }, /* 171 */ + { 94, 12, 0, }, /* 172 */ + { 94, 21, 0, }, /* 173 */ + { 14, 12, 0, }, /* 174 */ + { 14, 10, 0, }, /* 175 */ + { 14, 7, 0, }, /* 176 */ + { 14, 13, 0, }, /* 177 */ + { 14, 21, 0, }, /* 178 */ + { 14, 6, 0, }, /* 179 */ + { 2, 12, 0, }, /* 180 */ + { 2, 10, 0, }, /* 181 */ + { 2, 7, 0, }, /* 182 */ + { 2, 13, 0, }, /* 183 */ + { 2, 23, 0, }, /* 184 */ + { 2, 15, 0, }, /* 185 */ + { 2, 26, 0, }, /* 186 */ + { 21, 12, 0, }, /* 187 */ + { 21, 10, 0, }, /* 188 */ + { 21, 7, 0, }, /* 189 */ + { 21, 13, 0, }, /* 190 */ + { 20, 12, 0, }, /* 191 */ + { 20, 10, 0, }, /* 192 */ + { 20, 7, 0, }, /* 193 */ + { 20, 13, 0, }, /* 194 */ + { 20, 21, 0, }, /* 195 */ + { 20, 23, 0, }, /* 196 */ + { 43, 12, 0, }, /* 197 */ + { 43, 10, 0, }, /* 198 */ + { 43, 7, 0, }, /* 199 */ + { 43, 13, 0, }, /* 200 */ + { 43, 26, 0, }, /* 201 */ + { 43, 15, 0, }, /* 202 */ + { 53, 12, 0, }, /* 203 */ + { 53, 7, 0, }, /* 204 */ + { 53, 10, 0, }, /* 205 */ + { 53, 13, 0, }, /* 206 */ + { 53, 15, 0, }, /* 207 */ + { 53, 26, 0, }, /* 208 */ + { 53, 23, 0, }, /* 209 */ + { 54, 10, 0, }, /* 210 */ + { 54, 7, 0, }, /* 211 */ + { 54, 12, 0, }, /* 212 */ + { 54, 13, 0, }, /* 213 */ + { 54, 15, 0, }, /* 214 */ + { 54, 26, 0, }, /* 215 */ + { 28, 10, 0, }, /* 216 */ + { 28, 7, 0, }, /* 217 */ + { 28, 12, 0, }, /* 218 */ + { 28, 13, 0, }, /* 219 */ + { 36, 10, 0, }, /* 220 */ + { 36, 7, 0, }, /* 221 */ + { 36, 12, 0, }, /* 222 */ + { 36, 13, 0, }, /* 223 */ + { 36, 15, 0, }, /* 224 */ + { 36, 26, 0, }, /* 225 */ + { 47, 10, 0, }, /* 226 */ + { 47, 7, 0, }, /* 227 */ + { 47, 12, 0, }, /* 228 */ + { 47, 21, 0, }, /* 229 */ + { 56, 7, 0, }, /* 230 */ + { 56, 12, 0, }, /* 231 */ + { 56, 6, 0, }, /* 232 */ + { 56, 21, 0, }, /* 233 */ + { 56, 13, 0, }, /* 234 */ + { 32, 7, 0, }, /* 235 */ + { 32, 12, 0, }, /* 236 */ + { 32, 6, 0, }, /* 237 */ + { 32, 13, 0, }, /* 238 */ + { 57, 7, 0, }, /* 239 */ + { 57, 26, 0, }, /* 240 */ + { 57, 21, 0, }, /* 241 */ + { 57, 12, 0, }, /* 242 */ + { 57, 13, 0, }, /* 243 */ + { 57, 15, 0, }, /* 244 */ + { 57, 22, 0, }, /* 245 */ + { 57, 18, 0, }, /* 246 */ + { 57, 10, 0, }, /* 247 */ + { 38, 7, 0, }, /* 248 */ + { 38, 10, 0, }, /* 249 */ + { 38, 12, 0, }, /* 250 */ + { 38, 13, 0, }, /* 251 */ + { 38, 21, 0, }, /* 252 */ + { 38, 26, 0, }, /* 253 */ + { 16, 9, 7264, }, /* 254 */ + { 16, 7, 0, }, /* 255 */ + { 16, 6, 0, }, /* 256 */ + { 23, 7, 0, }, /* 257 */ + { 15, 7, 0, }, /* 258 */ + { 15, 12, 0, }, /* 259 */ + { 15, 21, 0, }, /* 260 */ + { 15, 15, 0, }, /* 261 */ + { 15, 26, 0, }, /* 262 */ + { 8, 7, 0, }, /* 263 */ + { 7, 17, 0, }, /* 264 */ + { 7, 7, 0, }, /* 265 */ + { 7, 21, 0, }, /* 266 */ + { 40, 29, 0, }, /* 267 */ + { 40, 7, 0, }, /* 268 */ + { 40, 22, 0, }, /* 269 */ + { 40, 18, 0, }, /* 270 */ + { 45, 7, 0, }, /* 271 */ + { 45, 14, 0, }, /* 272 */ + { 50, 7, 0, }, /* 273 */ + { 50, 12, 0, }, /* 274 */ + { 24, 7, 0, }, /* 275 */ + { 24, 12, 0, }, /* 276 */ + { 6, 7, 0, }, /* 277 */ + { 6, 12, 0, }, /* 278 */ + { 51, 7, 0, }, /* 279 */ + { 51, 12, 0, }, /* 280 */ + { 31, 7, 0, }, /* 281 */ + { 31, 12, 0, }, /* 282 */ + { 31, 10, 0, }, /* 283 */ + { 31, 21, 0, }, /* 284 */ + { 31, 6, 0, }, /* 285 */ + { 31, 23, 0, }, /* 286 */ + { 31, 13, 0, }, /* 287 */ + { 31, 15, 0, }, /* 288 */ + { 37, 21, 0, }, /* 289 */ + { 37, 17, 0, }, /* 290 */ + { 37, 12, 0, }, /* 291 */ + { 37, 29, 0, }, /* 292 */ + { 37, 13, 0, }, /* 293 */ + { 37, 7, 0, }, /* 294 */ + { 37, 6, 0, }, /* 295 */ + { 34, 7, 0, }, /* 296 */ + { 34, 12, 0, }, /* 297 */ + { 34, 10, 0, }, /* 298 */ + { 34, 26, 0, }, /* 299 */ + { 34, 21, 0, }, /* 300 */ + { 34, 13, 0, }, /* 301 */ + { 52, 7, 0, }, /* 302 */ + { 39, 7, 0, }, /* 303 */ + { 39, 10, 0, }, /* 304 */ + { 39, 13, 0, }, /* 305 */ + { 39, 15, 0, }, /* 306 */ + { 39, 26, 0, }, /* 307 */ + { 31, 26, 0, }, /* 308 */ + { 5, 7, 0, }, /* 309 */ + { 5, 12, 0, }, /* 310 */ + { 5, 10, 0, }, /* 311 */ + { 5, 21, 0, }, /* 312 */ + { 90, 7, 0, }, /* 313 */ + { 90, 10, 0, }, /* 314 */ + { 90, 12, 0, }, /* 315 */ + { 90, 13, 0, }, /* 316 */ + { 90, 21, 0, }, /* 317 */ + { 90, 6, 0, }, /* 318 */ + { 61, 12, 0, }, /* 319 */ + { 61, 10, 0, }, /* 320 */ + { 61, 7, 0, }, /* 321 */ + { 61, 13, 0, }, /* 322 */ + { 61, 21, 0, }, /* 323 */ + { 61, 26, 0, }, /* 324 */ + { 75, 12, 0, }, /* 325 */ + { 75, 10, 0, }, /* 326 */ + { 75, 7, 0, }, /* 327 */ + { 75, 13, 0, }, /* 328 */ + { 92, 7, 0, }, /* 329 */ + { 92, 12, 0, }, /* 330 */ + { 92, 10, 0, }, /* 331 */ + { 92, 21, 0, }, /* 332 */ + { 69, 7, 0, }, /* 333 */ + { 69, 10, 0, }, /* 334 */ + { 69, 12, 0, }, /* 335 */ + { 69, 21, 0, }, /* 336 */ + { 69, 13, 0, }, /* 337 */ + { 72, 13, 0, }, /* 338 */ + { 72, 7, 0, }, /* 339 */ + { 72, 6, 0, }, /* 340 */ + { 72, 21, 0, }, /* 341 */ + { 75, 21, 0, }, /* 342 */ + { 9, 10, 0, }, /* 343 */ + { 9, 7, 0, }, /* 344 */ + { 12, 5, 0, }, /* 345 */ + { 12, 6, 0, }, /* 346 */ + { 33, 5, 35332, }, /* 347 */ + { 33, 5, 3814, }, /* 348 */ + { 33, 5, -59, }, /* 349 */ + { 33, 9, -7615, }, /* 350 */ + { 19, 5, 8, }, /* 351 */ + { 19, 9, -8, }, /* 352 */ + { 19, 5, 74, }, /* 353 */ + { 19, 5, 86, }, /* 354 */ + { 19, 5, 100, }, /* 355 */ + { 19, 5, 128, }, /* 356 */ + { 19, 5, 112, }, /* 357 */ + { 19, 5, 126, }, /* 358 */ + { 19, 8, -8, }, /* 359 */ + { 19, 5, 9, }, /* 360 */ + { 19, 9, -74, }, /* 361 */ + { 19, 8, -9, }, /* 362 */ + { 19, 5, -7205, }, /* 363 */ + { 19, 9, -86, }, /* 364 */ + { 19, 9, -100, }, /* 365 */ + { 19, 9, -112, }, /* 366 */ + { 19, 9, -128, }, /* 367 */ + { 19, 9, -126, }, /* 368 */ + { 27, 1, 0, }, /* 369 */ + { 9, 27, 0, }, /* 370 */ + { 9, 28, 0, }, /* 371 */ + { 27, 11, 0, }, /* 372 */ + { 9, 9, 0, }, /* 373 */ + { 9, 5, 0, }, /* 374 */ + { 19, 9, -7517, }, /* 375 */ + { 33, 9, -8383, }, /* 376 */ + { 33, 9, -8262, }, /* 377 */ + { 33, 9, 28, }, /* 378 */ + { 33, 5, -28, }, /* 379 */ + { 33, 14, 16, }, /* 380 */ + { 33, 14, -16, }, /* 381 */ + { 33, 14, 0, }, /* 382 */ + { 9, 26, 26, }, /* 383 */ + { 9, 26, -26, }, /* 384 */ + { 4, 26, 0, }, /* 385 */ + { 17, 9, 48, }, /* 386 */ + { 17, 5, -48, }, /* 387 */ + { 33, 9, -10743, }, /* 388 */ + { 33, 9, -3814, }, /* 389 */ + { 33, 9, -10727, }, /* 390 */ + { 33, 5, -10795, }, /* 391 */ + { 33, 5, -10792, }, /* 392 */ + { 33, 9, -10780, }, /* 393 */ + { 33, 9, -10749, }, /* 394 */ + { 33, 9, -10783, }, /* 395 */ + { 33, 9, -10782, }, /* 396 */ + { 33, 9, -10815, }, /* 397 */ + { 10, 5, 0, }, /* 398 */ + { 10, 26, 0, }, /* 399 */ + { 10, 12, 0, }, /* 400 */ + { 10, 21, 0, }, /* 401 */ + { 10, 15, 0, }, /* 402 */ + { 16, 5, -7264, }, /* 403 */ + { 58, 7, 0, }, /* 404 */ + { 58, 6, 0, }, /* 405 */ + { 58, 21, 0, }, /* 406 */ + { 58, 12, 0, }, /* 407 */ + { 22, 26, 0, }, /* 408 */ + { 22, 6, 0, }, /* 409 */ + { 22, 14, 0, }, /* 410 */ + { 23, 10, 0, }, /* 411 */ + { 26, 7, 0, }, /* 412 */ + { 26, 6, 0, }, /* 413 */ + { 29, 7, 0, }, /* 414 */ + { 29, 6, 0, }, /* 415 */ + { 3, 7, 0, }, /* 416 */ + { 23, 26, 0, }, /* 417 */ + { 29, 26, 0, }, /* 418 */ + { 22, 7, 0, }, /* 419 */ + { 60, 7, 0, }, /* 420 */ + { 60, 6, 0, }, /* 421 */ + { 60, 26, 0, }, /* 422 */ + { 85, 7, 0, }, /* 423 */ + { 85, 6, 0, }, /* 424 */ + { 85, 21, 0, }, /* 425 */ + { 76, 7, 0, }, /* 426 */ + { 76, 6, 0, }, /* 427 */ + { 76, 21, 0, }, /* 428 */ + { 76, 13, 0, }, /* 429 */ + { 12, 7, 0, }, /* 430 */ + { 12, 21, 0, }, /* 431 */ + { 78, 7, 0, }, /* 432 */ + { 78, 14, 0, }, /* 433 */ + { 78, 12, 0, }, /* 434 */ + { 78, 21, 0, }, /* 435 */ + { 33, 9, -35332, }, /* 436 */ + { 33, 9, -42280, }, /* 437 */ + { 33, 9, -42308, }, /* 438 */ + { 48, 7, 0, }, /* 439 */ + { 48, 12, 0, }, /* 440 */ + { 48, 10, 0, }, /* 441 */ + { 48, 26, 0, }, /* 442 */ + { 64, 7, 0, }, /* 443 */ + { 64, 21, 0, }, /* 444 */ + { 74, 10, 0, }, /* 445 */ + { 74, 7, 0, }, /* 446 */ + { 74, 12, 0, }, /* 447 */ + { 74, 21, 0, }, /* 448 */ + { 74, 13, 0, }, /* 449 */ + { 68, 13, 0, }, /* 450 */ + { 68, 7, 0, }, /* 451 */ + { 68, 12, 0, }, /* 452 */ + { 68, 21, 0, }, /* 453 */ + { 73, 7, 0, }, /* 454 */ + { 73, 12, 0, }, /* 455 */ + { 73, 10, 0, }, /* 456 */ + { 73, 21, 0, }, /* 457 */ + { 83, 12, 0, }, /* 458 */ + { 83, 10, 0, }, /* 459 */ + { 83, 7, 0, }, /* 460 */ + { 83, 21, 0, }, /* 461 */ + { 83, 6, 0, }, /* 462 */ + { 83, 13, 0, }, /* 463 */ + { 67, 7, 0, }, /* 464 */ + { 67, 12, 0, }, /* 465 */ + { 67, 10, 0, }, /* 466 */ + { 67, 13, 0, }, /* 467 */ + { 67, 21, 0, }, /* 468 */ + { 38, 6, 0, }, /* 469 */ + { 91, 7, 0, }, /* 470 */ + { 91, 12, 0, }, /* 471 */ + { 91, 6, 0, }, /* 472 */ + { 91, 21, 0, }, /* 473 */ + { 86, 7, 0, }, /* 474 */ + { 86, 10, 0, }, /* 475 */ + { 86, 12, 0, }, /* 476 */ + { 86, 21, 0, }, /* 477 */ + { 86, 6, 0, }, /* 478 */ + { 86, 13, 0, }, /* 479 */ + { 9, 4, 0, }, /* 480 */ + { 9, 3, 0, }, /* 481 */ + { 25, 25, 0, }, /* 482 */ + { 0, 24, 0, }, /* 483 */ + { 35, 7, 0, }, /* 484 */ + { 19, 14, 0, }, /* 485 */ + { 19, 15, 0, }, /* 486 */ + { 19, 26, 0, }, /* 487 */ + { 70, 7, 0, }, /* 488 */ + { 66, 7, 0, }, /* 489 */ + { 41, 7, 0, }, /* 490 */ + { 41, 15, 0, }, /* 491 */ + { 18, 7, 0, }, /* 492 */ + { 18, 14, 0, }, /* 493 */ + { 59, 7, 0, }, /* 494 */ + { 59, 21, 0, }, /* 495 */ + { 42, 7, 0, }, /* 496 */ + { 42, 21, 0, }, /* 497 */ + { 42, 14, 0, }, /* 498 */ + { 13, 9, 40, }, /* 499 */ + { 13, 5, -40, }, /* 500 */ + { 46, 7, 0, }, /* 501 */ + { 44, 7, 0, }, /* 502 */ + { 44, 13, 0, }, /* 503 */ + { 11, 7, 0, }, /* 504 */ + { 80, 7, 0, }, /* 505 */ + { 80, 21, 0, }, /* 506 */ + { 80, 15, 0, }, /* 507 */ + { 65, 7, 0, }, /* 508 */ + { 65, 15, 0, }, /* 509 */ + { 65, 21, 0, }, /* 510 */ + { 71, 7, 0, }, /* 511 */ + { 71, 21, 0, }, /* 512 */ + { 97, 7, 0, }, /* 513 */ + { 96, 7, 0, }, /* 514 */ + { 30, 7, 0, }, /* 515 */ + { 30, 12, 0, }, /* 516 */ + { 30, 15, 0, }, /* 517 */ + { 30, 21, 0, }, /* 518 */ + { 87, 7, 0, }, /* 519 */ + { 87, 15, 0, }, /* 520 */ + { 87, 21, 0, }, /* 521 */ + { 77, 7, 0, }, /* 522 */ + { 77, 21, 0, }, /* 523 */ + { 82, 7, 0, }, /* 524 */ + { 82, 15, 0, }, /* 525 */ + { 81, 7, 0, }, /* 526 */ + { 81, 15, 0, }, /* 527 */ + { 88, 7, 0, }, /* 528 */ + { 0, 15, 0, }, /* 529 */ + { 93, 10, 0, }, /* 530 */ + { 93, 12, 0, }, /* 531 */ + { 93, 7, 0, }, /* 532 */ + { 93, 21, 0, }, /* 533 */ + { 93, 15, 0, }, /* 534 */ + { 93, 13, 0, }, /* 535 */ + { 84, 12, 0, }, /* 536 */ + { 84, 10, 0, }, /* 537 */ + { 84, 7, 0, }, /* 538 */ + { 84, 21, 0, }, /* 539 */ + { 84, 1, 0, }, /* 540 */ + { 100, 7, 0, }, /* 541 */ + { 100, 13, 0, }, /* 542 */ + { 95, 12, 0, }, /* 543 */ + { 95, 7, 0, }, /* 544 */ + { 95, 10, 0, }, /* 545 */ + { 95, 13, 0, }, /* 546 */ + { 95, 21, 0, }, /* 547 */ + { 99, 12, 0, }, /* 548 */ + { 99, 10, 0, }, /* 549 */ + { 99, 7, 0, }, /* 550 */ + { 99, 21, 0, }, /* 551 */ + { 99, 13, 0, }, /* 552 */ + { 101, 7, 0, }, /* 553 */ + { 101, 12, 0, }, /* 554 */ + { 101, 10, 0, }, /* 555 */ + { 101, 13, 0, }, /* 556 */ + { 62, 7, 0, }, /* 557 */ + { 62, 14, 0, }, /* 558 */ + { 62, 21, 0, }, /* 559 */ + { 79, 7, 0, }, /* 560 */ + { 98, 7, 0, }, /* 561 */ + { 98, 10, 0, }, /* 562 */ + { 98, 12, 0, }, /* 563 */ + { 98, 6, 0, }, /* 564 */ + { 19, 12, 0, }, /* 565 */ + { 26, 26, 0, }, /* 566 */ }; -const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ +const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */ 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */ - 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, /* U+2000 */ - 76, 76, 65, 77, 65, 65, 78, 17, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */ + 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */ + 75, 75, 65, 76, 65, 65, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */ 87, 88, 89, 90, 91, 92, 93, 70, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+4000 */ @@ -573,49 +622,49 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+9000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 96, /* U+9800 */ 97, 98, 98, 98, 98, 98, 98, 98, 98, 99,100,100,101,102,103,104, /* U+A000 */ -105,106,107,108,109,110, 17,111, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */ +105,106,107,108,109,110,111,112, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */ - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,112, /* U+D000 */ -113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, /* U+D800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F000 */ -114,114, 94, 94,115,116,117,118,119,119,120,121,122,123,124,125, /* U+F800 */ -126,127,128,129, 17,130,131,132,133,134, 17, 17, 17, 17, 17, 17, /* U+10000 */ -135, 17,136, 17,137, 17,138, 17,139, 17, 17, 17,140, 17, 17, 17, /* U+10800 */ - 17,141, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11800 */ -142,142,142,142,142,142,143, 17,144, 17, 17, 17, 17, 17, 17, 17, /* U+12000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+12800 */ -145,145,145,145,145,145,145,145,146, 17, 17, 17, 17, 17, 17, 17, /* U+13000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+13800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C800 */ - 70,147,148,149,150, 17,151, 17,152,153,154,155,156,157,158,159, /* U+1D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E800 */ -160,161,162,163,164, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F800 */ + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,113, /* U+D000 */ +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+D800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F000 */ +115,115, 94, 94,116,117,118,119,120,120,121,122,123,124,125,126, /* U+F800 */ +127,128,129,130, 78,131,132,133,134,135, 78, 78, 78, 78, 78, 78, /* U+10000 */ +136, 78,137,138,139, 78,140, 78,141, 78, 78, 78,142, 78, 78, 78, /* U+10800 */ +143,144,145,146, 78, 78, 78, 78, 78, 78, 78, 78, 78,147, 78, 78, /* U+11000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+11800 */ +148,148,148,148,148,148,149, 78,150, 78, 78, 78, 78, 78, 78, 78, /* U+12000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+12800 */ +151,151,151,151,151,151,151,151,152, 78, 78, 78, 78, 78, 78, 78, /* U+13000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+13800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+16000 */ +153,153,153,153,154, 78, 78, 78, 78, 78, 78, 78, 78, 78,155,156, /* U+16800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A800 */ +157, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C800 */ + 70,158,159,160,161, 78,162, 78,163,164,165,166,167,168,169,170, /* U+1D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,171,172, 78, 78, /* U+1E800 */ +173,174,175,176,177, 78,178,179,180,181,182,183,184,185,186, 78, /* U+1F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1F800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21000 */ @@ -636,469 +685,469 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,165, 94, 94, /* U+2A000 */ + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,187, 94, 94, /* U+2A000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+2A800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,166, 17, /* U+2B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F000 */ - 94, 94, 94, 94,167, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF800 */ -168, 17,169,170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FF000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+FF800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10F000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+10F800 */ + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,188, 94, /* U+2B000 */ +189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F000 */ + 94, 94, 94, 94,189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF800 */ +190, 78,191,192, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FF000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+FF800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10F000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+10F800 */ }; -const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ +const pcre_uint16 PRIV(ucd_stage2)[] = { /* 49664 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1112,635 +1161,635 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ /* block 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 3, 3, 3, 13, 13, 10, 13, 14, 15, 6, 16, 13, 10, - 13, 6, 17, 17, 10, 18, 13, 2, 10, 17, 14, 19, 17, 17, 17, 2, + 1, 2, 3, 3, 3, 3, 13, 2, 10, 13, 14, 15, 6, 16, 13, 10, + 13, 6, 17, 17, 10, 18, 2, 2, 10, 17, 14, 19, 17, 17, 17, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 14, + 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 20, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 20, + 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 21, /* block 2 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 23, 24, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, 21, - 22, 21, 22, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 25, 21, 22, 21, 22, 21, 22, 26, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 24, 25, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 26, 22, 23, 22, 23, 22, 23, 27, /* block 3 */ - 27, 28, 21, 22, 21, 22, 29, 21, 22, 30, 30, 21, 22, 14, 31, 32, - 33, 21, 22, 30, 34, 35, 36, 37, 21, 22, 38, 14, 36, 39, 40, 41, - 21, 22, 21, 22, 21, 22, 42, 21, 22, 42, 14, 14, 21, 22, 42, 21, - 22, 43, 43, 21, 22, 21, 22, 44, 21, 22, 14, 45, 21, 22, 14, 46, - 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 21, 22, 21, - 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 50, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 14, 47, 48, 49, 21, 22, 51, 52, 21, 22, 21, 22, 21, 22, 21, 22, + 28, 29, 22, 23, 22, 23, 30, 22, 23, 31, 31, 22, 23, 20, 32, 33, + 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39, 20, 37, 40, 41, 42, + 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 20, 20, 22, 23, 43, 22, + 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 20, 14, 22, 23, 20, 46, + 14, 14, 14, 14, 47, 48, 49, 47, 48, 49, 47, 48, 49, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 50, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 20, 47, 48, 49, 22, 23, 51, 52, 22, 23, 22, 23, 22, 23, 22, 23, /* block 4 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 53, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 14, 14, 14, 14, 14, 14, 54, 21, 22, 55, 56, 57, - 57, 21, 22, 58, 59, 60, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 61, 62, 63, 64, 65, 14, 66, 66, 14, 67, 14, 68, 14, 14, 14, 14, - 66, 14, 14, 69, 14, 14, 14, 14, 70, 71, 14, 72, 14, 14, 14, 71, - 14, 73, 74, 14, 14, 75, 14, 14, 14, 14, 14, 14, 14, 76, 14, 14, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 53, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 20, 20, 20, 20, 20, 20, 54, 22, 23, 55, 56, 57, + 57, 22, 23, 58, 59, 60, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 61, 62, 63, 64, 65, 20, 66, 66, 20, 67, 20, 68, 20, 20, 20, 20, + 66, 20, 20, 69, 20, 70, 71, 20, 72, 73, 20, 74, 20, 20, 20, 73, + 20, 75, 76, 20, 20, 77, 20, 20, 20, 20, 20, 20, 20, 78, 20, 20, /* block 5 */ - 77, 14, 14, 77, 14, 14, 14, 14, 77, 78, 79, 79, 80, 14, 14, 14, - 14, 14, 81, 14, 45, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 82, 82, 82, 82, 82, 10, 10, 10, 10, 10, 10, 10, 83, 10, 83, 10, + 79, 20, 20, 79, 20, 20, 20, 20, 79, 80, 81, 81, 82, 20, 20, 20, + 20, 20, 83, 20, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 84, 84, 84, 84, 84, 10, 10, 10, 10, 10, 86, 86, 85, 10, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* block 6 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 85, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 86, 87, 86, 87, 83, 88, 86, 87, 89, 89, 90, 91, 91, 91, 2, 89, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 89, 90, 89, 90, 85, 91, 89, 90, 92, 92, 93, 94, 94, 94, 2, 92, /* block 7 */ - 89, 89, 89, 89, 88, 10, 92, 2, 93, 93, 93, 89, 94, 89, 95, 95, - 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 89, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99, 99, - 96,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, -100,100,101,100,100,100,100,100,100,100,100,100,102,103,103,104, -105,106,107,107,107,108,109,110, 86, 87, 86, 87, 86, 87, 86, 87, - 86, 87,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -113,114,115, 96,116,117,118, 86, 87,119, 86, 87, 96,120,120,120, + 92, 92, 92, 92, 91, 10, 95, 2, 96, 96, 96, 92, 97, 92, 98, 98, + 99,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100, 92,100,100,100,100,100,100,100,100,100,101,102,102,102, + 99,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,104,103,103,103,103,103,103,103,103,103,105,106,106,107, +108,109,110,110,110,111,112,113, 89, 90, 89, 90, 89, 90, 89, 90, + 89, 90,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +116,117,118, 99,119,120,121, 89, 90,122, 89, 90, 99,123,123,123, /* block 8 */ -121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, -122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, -122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, -123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, -123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 9 */ -125,126,127,128,128, 84, 84,128,129,129,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -130,125,126,125,126,125,126,125,126,125,126,125,126,125,126,131, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, +128,129,130,131,131, 87, 87,131,132,132,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +133,128,129,128,129,128,129,128,129,128,129,128,129,128,129,134, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 10 */ -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, -132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, -132,132,132,132,132,132,132, 89, 89,133,134,134,134,134,134,134, - 89,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92, 92, + 92,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135, 92, 92,136,137,137,137,137,137,137, + 92,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, /* block 11 */ -135,135,135,135,135,135,135,136, 89, 2,137, 89, 89, 89, 89, 89, - 89,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, -138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, -138,138,138,138,138,138,138,138,138,138,138,138,138,138,139,138, -140,138,138,140,138,138,140,138, 89, 89, 89, 89, 89, 89, 89, 89, -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, -141,141,141,141,141,141,141,141,141,141,141, 89, 89, 89, 89, 89, -141,141,141,140,140, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +138,138,138,138,138,138,138,139, 92, 2,140, 92, 92, 92, 92,141, + 92,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,143,142, +144,142,142,144,142,142,144,142, 92, 92, 92, 92, 92, 92, 92, 92, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145, 92, 92, 92, 92, 92, +145,145,145,144,144, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 12 */ - 16, 16, 16, 16, 89, 89,142,142,142,143,143,144, 2,143,145,145, -146,146,146,146,146,146,146,146,146,146,146, 2, 89, 89,143, 2, - 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, - 83,147,147,147,147,147,147,147,147,147,147, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84,146,146,146,146,146,146,146,146,146, 89, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,143,143,143,143,147,147, - 84,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +146,146,146,146,146, 92,147,147,147,148,148,149, 2,148,150,150, +151,151,151,151,151,151,151,151,151,151,151, 2, 92, 92,148, 2, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 85,152,152,152,152,152,152,152,152,152,152, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87,151,151,151,151,151,151,151,151,151, 87, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,148,148,148,148,152,152, + 87,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 13 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,143,147,146,146,146,146,146,146,146, 16,148,146, -146,146,146,146,146,149,149,146,146,145,146,146,146,146,147,147, -150,150,150,150,150,150,150,150,150,150,147,147,147,145,145,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,148,152,151,151,151,151,151,151,151, 16,150,151, +151,151,151,151,151,153,153,151,151,150,151,151,151,151,152,152, +154,154,154,154,154,154,154,154,154,154,152,152,152,150,150,152, /* block 14 */ -151,151,151,151,151,151,151,151,151,151,151,151,151,151, 89,152, -153,154,153,153,153,153,153,153,153,153,153,153,153,153,153,153, -153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154, 89, 89,153,153,153, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +155,155,155,155,155,155,155,155,155,155,155,155,155,155, 92,156, +157,158,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158, 92, 92,157,157,157, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 15 */ -155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, -155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, -155,155,155,155,155,155,156,156,156,156,156,156,156,156,156,156, -156,155, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -157,157,157,157,157,157,157,157,157,157,158,158,158,158,158,158, -158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, -158,158,158,158,158,158,158,158,158,158,158,159,159,159,159,159, -159,159,159,159,160,160,161,162,162,162,160, 89, 89, 89, 89, 89, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160, +160,159, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +161,161,161,161,161,161,161,161,161,161,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,163,163,163,163,163, +163,163,163,163,164,164,165,166,166,166,164, 92, 92, 92, 92, 92, /* block 16 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,164,164,164,164,165,164,164,164,164,164, -164,164,164,164,165,164,164,164,165,164,164,164,164,164, 89, 89, -166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,168,168,168,168,169,168,168,168,168,168, +168,168,168,168,169,168,168,168,169,168,168,168,168,168, 92, 92, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, 92, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,172,172,172, 92, 92,173, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 17 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152, 92,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 92, /* block 18 */ -167,167,167,168,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169, 89, 89,167,169,168,168, -168,167,167,167,167,167,167,167,167,168,168,168,168,167,168, 89, -169, 84, 84,167,167,167, 89, 89,169,169,169,169,169,169,169,169, -169,169,167,167, 2, 2,170,170,170,170,170,170,170,170,170,170, - 2,171,169, 89, 89, 89, 89, 89, 89,169,169,169,169,169,169,169, +174,174,174,175,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,174,175,174,176,175,175, +175,174,174,174,174,174,174,174,174,175,175,175,175,174,175,175, +176, 87, 87,174,174,174,174,174,176,176,176,176,176,176,176,176, +176,176,174,174, 2, 2,177,177,177,177,177,177,177,177,177,177, +178,179,176,176,176,176,176,176, 92,176,176,176,176,176,176,176, /* block 19 */ - 89,172,173,173, 89,174,174,174,174,174,174,174,174, 89, 89,174, -174, 89, 89,174,174,174,174,174,174,174,174,174,174,174,174,174, -174,174,174,174,174,174,174,174,174, 89,174,174,174,174,174,174, -174, 89,174, 89, 89, 89,174,174,174,174, 89, 89,172,174,173,173, -173,172,172,172,172, 89, 89,173,173, 89, 89,173,173,172,174, 89, - 89, 89, 89, 89, 89, 89, 89,173, 89, 89, 89, 89,174,174, 89,174, -174,174,172,172, 89, 89,175,175,175,175,175,175,175,175,175,175, -174,174,176,176,177,177,177,177,177,177,178,176, 89, 89, 89, 89, + 92,180,181,181, 92,182,182,182,182,182,182,182,182, 92, 92,182, +182, 92, 92,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182, 92,182,182,182,182,182,182, +182, 92,182, 92, 92, 92,182,182,182,182, 92, 92,180,182,181,181, +181,180,180,180,180, 92, 92,181,181, 92, 92,181,181,180,182, 92, + 92, 92, 92, 92, 92, 92, 92,181, 92, 92, 92, 92,182,182, 92,182, +182,182,180,180, 92, 92,183,183,183,183,183,183,183,183,183,183, +182,182,184,184,185,185,185,185,185,185,186,184, 92, 92, 92, 92, /* block 20 */ - 89,179,179,180, 89,181,181,181,181,181,181, 89, 89, 89, 89,181, -181, 89, 89,181,181,181,181,181,181,181,181,181,181,181,181,181, -181,181,181,181,181,181,181,181,181, 89,181,181,181,181,181,181, -181, 89,181,181, 89,181,181, 89,181,181, 89, 89,179, 89,180,180, -180,179,179, 89, 89, 89, 89,179,179, 89, 89,179,179,179, 89, 89, - 89,179, 89, 89, 89, 89, 89, 89, 89,181,181,181,181, 89,181, 89, - 89, 89, 89, 89, 89, 89,182,182,182,182,182,182,182,182,182,182, -179,179,181,181,181,179, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,187,187,188, 92,189,189,189,189,189,189, 92, 92, 92, 92,189, +189, 92, 92,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189, 92,189,189,189,189,189,189, +189, 92,189,189, 92,189,189, 92,189,189, 92, 92,187, 92,188,188, +188,187,187, 92, 92, 92, 92,187,187, 92, 92,187,187,187, 92, 92, + 92,187, 92, 92, 92, 92, 92, 92, 92,189,189,189,189, 92,189, 92, + 92, 92, 92, 92, 92, 92,190,190,190,190,190,190,190,190,190,190, +187,187,189,189,189,187, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 21 */ - 89,183,183,184, 89,185,185,185,185,185,185,185,185,185, 89,185, -185,185, 89,185,185,185,185,185,185,185,185,185,185,185,185,185, -185,185,185,185,185,185,185,185,185, 89,185,185,185,185,185,185, -185, 89,185,185, 89,185,185,185,185,185, 89, 89,183,185,184,184, -184,183,183,183,183,183, 89,183,183,184, 89,184,184,183, 89, 89, -185, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -185,185,183,183, 89, 89,186,186,186,186,186,186,186,186,186,186, - 89,187, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,191,191,192, 92,193,193,193,193,193,193,193,193,193, 92,193, +193,193, 92,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193, 92,193,193,193,193,193,193, +193, 92,193,193, 92,193,193,193,193,193, 92, 92,191,193,192,192, +192,191,191,191,191,191, 92,191,191,192, 92,192,192,191, 92, 92, +193, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +193,193,191,191, 92, 92,194,194,194,194,194,194,194,194,194,194, +195,196, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 22 */ - 89,188,189,189, 89,190,190,190,190,190,190,190,190, 89, 89,190, -190, 89, 89,190,190,190,190,190,190,190,190,190,190,190,190,190, -190,190,190,190,190,190,190,190,190, 89,190,190,190,190,190,190, -190, 89,190,190, 89,190,190,190,190,190, 89, 89,188,190,189,188, -189,188,188,188,188, 89, 89,189,189, 89, 89,189,189,188, 89, 89, - 89, 89, 89, 89, 89, 89,188,189, 89, 89, 89, 89,190,190, 89,190, -190,190,188,188, 89, 89,191,191,191,191,191,191,191,191,191,191, -192,190, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,197,198,198, 92,199,199,199,199,199,199,199,199, 92, 92,199, +199, 92, 92,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199, 92,199,199,199,199,199,199, +199, 92,199,199, 92,199,199,199,199,199, 92, 92,197,199,198,197, +198,197,197,197,197, 92, 92,198,198, 92, 92,198,198,197, 92, 92, + 92, 92, 92, 92, 92, 92,197,198, 92, 92, 92, 92,199,199, 92,199, +199,199,197,197, 92, 92,200,200,200,200,200,200,200,200,200,200, +201,199,202,202,202,202,202,202, 92, 92, 92, 92, 92, 92, 92, 92, /* block 23 */ - 89, 89,193,194, 89,194,194,194,194,194,194, 89, 89, 89,194,194, -194, 89,194,194,194,194, 89, 89, 89,194,194, 89,194, 89,194,194, - 89, 89, 89,194,194, 89, 89, 89,194,194,194, 89, 89, 89,194,194, -194,194,194,194,194,194,194,194,194,194, 89, 89, 89, 89,195,195, -193,195,195, 89, 89, 89,195,195,195, 89,195,195,195,193, 89, 89, -194, 89, 89, 89, 89, 89, 89,195, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89,196,196,196,196,196,196,196,196,196,196, -197,197,197,198,198,198,198,198,198,199,198, 89, 89, 89, 89, 89, + 92, 92,203,204, 92,204,204,204,204,204,204, 92, 92, 92,204,204, +204, 92,204,204,204,204, 92, 92, 92,204,204, 92,204, 92,204,204, + 92, 92, 92,204,204, 92, 92, 92,204,204,204, 92, 92, 92,204,204, +204,204,204,204,204,204,204,204,204,204, 92, 92, 92, 92,205,205, +203,205,205, 92, 92, 92,205,205,205, 92,205,205,205,203, 92, 92, +204, 92, 92, 92, 92, 92, 92,205, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92,206,206,206,206,206,206,206,206,206,206, +207,207,207,208,208,208,208,208,208,209,208, 92, 92, 92, 92, 92, /* block 24 */ - 89,200,200,200, 89,201,201,201,201,201,201,201,201, 89,201,201, -201, 89,201,201,201,201,201,201,201,201,201,201,201,201,201,201, -201,201,201,201,201,201,201,201,201, 89,201,201,201,201,201,201, -201,201,201,201, 89,201,201,201,201,201, 89, 89, 89,201,202,202, -202,200,200,200,200, 89,202,202,202, 89,202,202,202,202, 89, 89, - 89, 89, 89, 89, 89,202,202, 89,201,201, 89, 89, 89, 89, 89, 89, -201,201,202,202, 89, 89,203,203,203,203,203,203,203,203,203,203, - 89, 89, 89, 89, 89, 89, 89, 89,204,204,204,204,204,204,204,205, + 92,210,210,210, 92,211,211,211,211,211,211,211,211, 92,211,211, +211, 92,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211, 92,211,211,211,211,211,211, +211,211,211,211, 92,211,211,211,211,211, 92, 92, 92,211,212,212, +212,210,210,210,210, 92,212,212,212, 92,212,212,212,212, 92, 92, + 92, 92, 92, 92, 92,212,212, 92,211,211, 92, 92, 92, 92, 92, 92, +211,211,212,212, 92, 92,213,213,213,213,213,213,213,213,213,213, + 92, 92, 92, 92, 92, 92, 92, 92,214,214,214,214,214,214,214,215, /* block 25 */ - 89, 89,206,206, 89,207,207,207,207,207,207,207,207, 89,207,207, -207, 89,207,207,207,207,207,207,207,207,207,207,207,207,207,207, -207,207,207,207,207,207,207,207,207, 89,207,207,207,207,207,207, -207,207,207,207, 89,207,207,207,207,207, 89, 89,208,207,206,208, -206,206,206,206,206, 89,208,206,206, 89,206,206,208,208, 89, 89, - 89, 89, 89, 89, 89,206,206, 89, 89, 89, 89, 89, 89, 89,207, 89, -207,207,208,208, 89, 89,209,209,209,209,209,209,209,209,209,209, - 89, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92,216,216, 92,217,217,217,217,217,217,217,217, 92,217,217, +217, 92,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217, 92,217,217,217,217,217,217, +217,217,217,217, 92,217,217,217,217,217, 92, 92,218,217,216,218, +216,216,216,216,216, 92,218,216,216, 92,216,216,218,218, 92, 92, + 92, 92, 92, 92, 92,216,216, 92, 92, 92, 92, 92, 92, 92,217, 92, +217,217,218,218, 92, 92,219,219,219,219,219,219,219,219,219,219, + 92,217,217, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 26 */ - 89, 89,210,210, 89,211,211,211,211,211,211,211,211, 89,211,211, -211, 89,211,211,211,211,211,211,211,211,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211, 89,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211,211, 89, 89, 89,211,210,210, -210,212,212,212,212, 89,210,210,210, 89,210,210,210,212, 89, 89, - 89, 89, 89, 89, 89, 89, 89,210, 89, 89, 89, 89, 89, 89, 89, 89, -211,211,212,212, 89, 89,213,213,213,213,213,213,213,213,213,213, -214,214,214,214,214,214, 89, 89, 89,215,211,211,211,211,211,211, + 92, 92,220,220, 92,221,221,221,221,221,221,221,221, 92,221,221, +221, 92,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221, 92, 92,221,220,220, +220,222,222,222,222, 92,220,220,220, 92,220,220,220,222,221, 92, + 92, 92, 92, 92, 92, 92, 92,220, 92, 92, 92, 92, 92, 92, 92, 92, +221,221,222,222, 92, 92,223,223,223,223,223,223,223,223,223,223, +224,224,224,224,224,224, 92, 92, 92,225,221,221,221,221,221,221, /* block 27 */ - 89, 89,216,216, 89,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217, 89, 89, 89,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217, 89,217,217,217,217,217,217,217,217,217, 89,217, 89, 89, -217,217,217,217,217,217,217, 89, 89, 89,218, 89, 89, 89, 89,216, -216,216,218,218,218, 89,218, 89,216,216,216,216,216,216,216,216, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89,216,216,219, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92,226,226, 92,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227, 92, 92, 92,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227, 92,227,227,227,227,227,227,227,227,227, 92,227, 92, 92, +227,227,227,227,227,227,227, 92, 92, 92,228, 92, 92, 92, 92,226, +226,226,228,228,228, 92,228, 92,226,226,226,226,226,226,226,226, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92,226,226,229, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 28 */ - 89,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,221,220,220,221,221,221,221,221,221,221, 89, 89, 89, 89, 3, -220,220,220,220,220,220,222,221,221,221,221,221,221,221,221,223, -224,224,224,224,224,224,224,224,224,224,223,223, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,231,230,230,231,231,231,231,231,231,231, 92, 92, 92, 92, 3, +230,230,230,230,230,230,232,231,231,231,231,231,231,231,231,233, +234,234,234,234,234,234,234,234,234,234,233,233, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 29 */ - 89,225,225, 89,225, 89, 89,225,225, 89,225, 89, 89,225, 89, 89, - 89, 89, 89, 89,225,225,225,225, 89,225,225,225,225,225,225,225, - 89,225,225,225, 89,225, 89,225, 89, 89,225,225, 89,225,225,225, -225,226,225,225,226,226,226,226,226,226, 89,226,226,225, 89, 89, -225,225,225,225,225, 89,227, 89,226,226,226,226,226,226, 89, 89, -228,228,228,228,228,228,228,228,228,228, 89, 89,225,225, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,235,235, 92,235, 92, 92,235,235, 92,235, 92, 92,235, 92, 92, + 92, 92, 92, 92,235,235,235,235, 92,235,235,235,235,235,235,235, + 92,235,235,235, 92,235, 92,235, 92, 92,235,235, 92,235,235,235, +235,236,235,235,236,236,236,236,236,236, 92,236,236,235, 92, 92, +235,235,235,235,235, 92,237, 92,236,236,236,236,236,236, 92, 92, +238,238,238,238,238,238,238,238,238,238, 92, 92,235,235,235,235, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 30 */ -229,230,230,230,231,231,231,231,231,231,231,231,231,231,231,231, -231,231,231,230,230,230,230,230,232,232,230,230,230,230,230,230, -233,233,233,233,233,233,233,233,233,233,234,234,234,234,234,234, -234,234,234,234,230,232,230,232,230,232,235,236,235,236,237,237, -229,229,229,229,229,229,229,229, 89,229,229,229,229,229,229,229, -229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, -229,229,229,229,229,229,229,229,229,229,229,229,229, 89, 89, 89, - 89,232,232,232,232,232,232,232,232,232,232,232,232,232,232,237, +239,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,240,241,240,240,240,242,242,240,240,240,240,240,240, +243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244, +244,244,244,244,240,242,240,242,240,242,245,246,245,246,247,247, +239,239,239,239,239,239,239,239, 92,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239, 92, 92, 92, + 92,242,242,242,242,242,242,242,242,242,242,242,242,242,242,247, /* block 31 */ -232,232,232,232,232,231,232,232,229,229,229,229, 89, 89, 89, 89, -232,232,232,232,232,232,232,232, 89,232,232,232,232,232,232,232, -232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, -232,232,232,232,232,232,232,232,232,232,232,232,232, 89,230,230, -230,230,230,230,230,230,232,230,230,230,230,230,230, 89,230,230, -231,231,231,231,231, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +242,242,242,242,242,241,242,242,239,239,239,239,239,242,242,242, +242,242,242,242,242,242,242,242, 92,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242, 92,240,240, +240,240,240,240,240,240,242,240,240,240,240,240,240, 92,240,240, +241,241,241,241,241, 13, 13, 13, 13,241,241, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 32 */ -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,239,239,240,240,240, -240,239,240,240,240,240,240,240,239,240,240,239,239,240,240,238, -241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242, -238,238,238,238,238,238,239,239,240,240,238,238,238,238,240,240, -240,238,239,239,239,238,238,239,239,239,239,239,239,239,238,238, -238,240,240,240,240,238,238,238,238,238,238,238,238,238,238,238, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,249,249,250,250,250, +250,249,250,250,250,250,250,250,249,250,250,249,249,250,250,248, +251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252, +248,248,248,248,248,248,249,249,250,250,248,248,248,248,250,250, +250,248,249,249,249,248,248,249,249,249,249,249,249,249,248,248, +248,250,250,250,250,248,248,248,248,248,248,248,248,248,248,248, /* block 33 */ -238,238,240,239,239,240,240,239,239,239,239,239,239,240,238,239, -241,241,241,241,241,241,241,241,241,241,239,239,239,240,243,243, -244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, -244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, -244,244,244,244,244,244, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, -245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, -245,245,245,245,245,245,245,245,245,245,245, 2,246, 89, 89, 89, +248,248,250,249,249,250,250,249,249,249,249,249,249,250,248,249, +251,251,251,251,251,251,251,251,251,251,249,249,249,250,253,253, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254, 92,254, 92, 92, 92, 92, 92,254, 92, 92, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255, 2,256,255,255,255, /* block 34 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 35 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248, 89,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258, 92,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 36 */ -248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248, 89, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258, 92, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 37 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248, 89, 89, 89, 89,249, -250,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252, -252,252,252,252,252,252,252,252,252,252,252,252,252, 89, 89, 89, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258, 92, 92,259,259,259, +260,260,260,260,260,260,260,260,260,261,261,261,261,261,261,261, +261,261,261,261,261,261,261,261,261,261,261,261,261, 92, 92, 92, /* block 38 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -250,250,250,250,250,250,250,250,250,250, 89, 89, 89, 89, 89, 89, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +262,262,262,262,262,262,262,262,262,262, 92, 92, 92, 92, 92, 92, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 39 */ -254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +264,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 40 */ -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 41 */ -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,256,256,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,266,266,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 42 */ -257,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, -258,258,258,258,258,258,258,258,258,258,258,259,260, 89, 89, 89, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261, 2, 2, 2,262,262, -262, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +267,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268, +268,268,268,268,268,268,268,268,268,268,268,269,270, 92, 92, 92, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271, 2, 2, 2,272,272, +272, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 43 */ -263,263,263,263,263,263,263,263,263,263,263,263,263, 89,263,263, -263,263,264,264,264, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, -265,265,266,266,266, 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89, -267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, -267,267,268,268, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -269,269,269,269,269,269,269,269,269,269,269,269,269, 89,269,269, -269, 89,270,270, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +273,273,273,273,273,273,273,273,273,273,273,273,273, 92,273,273, +273,273,274,274,274, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275, +275,275,276,276,276, 2, 2, 92, 92, 92, 92, 92, 92, 92, 92, 92, +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,278,278, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +279,279,279,279,279,279,279,279,279,279,279,279,279, 92,279,279, +279, 92,280,280, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 44 */ -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,272,272,273,274,274,274,274,274,274,274,273,273, -273,273,273,273,273,273,274,273,273,274,274,274,274,274,274,274, -274,274,274,274,275,275,275,276,275,275,275,277,271,274, 89, 89, -278,278,278,278,278,278,278,278,278,278, 89, 89, 89, 89, 89, 89, -279,279,279,279,279,279,279,279,279,279, 89, 89, 89, 89, 89, 89, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,282,282,283,282,282,282,282,282,282,282,283,283, +283,283,283,283,283,283,282,283,283,282,282,282,282,282,282,282, +282,282,282,282,284,284,284,285,284,284,284,286,281,282, 92, 92, +287,287,287,287,287,287,287,287,287,287, 92, 92, 92, 92, 92, 92, +288,288,288,288,288,288,288,288,288,288, 92, 92, 92, 92, 92, 92, /* block 45 */ -280,280, 2, 2,280, 2,281,280,280,280,280,282,282,282,283, 89, -284,284,284,284,284,284,284,284,284,284, 89, 89, 89, 89, 89, 89, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,286,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285, 89, 89, 89, 89, 89, 89, 89, 89, +289,289, 2, 2,289, 2,290,289,289,289,289,291,291,291,292, 92, +293,293,293,293,293,293,293,293,293,293, 92, 92, 92, 92, 92, 92, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,295,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294, 92, 92, 92, 92, 92, 92, 92, 92, /* block 46 */ -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,282,285, 89, 89, 89, 89, 89, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,291,294, 92, 92, 92, 92, 92, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 47 */ -287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287, -287,287,287,287,287,287,287,287,287,287,287,287,287, 89, 89, 89, -288,288,288,289,289,289,289,288,288,289,289,289, 89, 89, 89, 89, -289,289,288,289,289,289,289,289,289,288,288,288, 89, 89, 89, 89, -290, 89, 89, 89,291,291,292,292,292,292,292,292,292,292,292,292, -293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293, -293,293,293,293,293,293,293,293,293,293,293,293,293,293, 89, 89, -293,293,293,293,293, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, +296,296,296,296,296,296,296,296,296,296,296,296,296, 92, 92, 92, +297,297,297,298,298,298,298,297,297,298,298,298, 92, 92, 92, 92, +298,298,297,298,298,298,298,298,298,297,297,297, 92, 92, 92, 92, +299, 92, 92, 92,300,300,301,301,301,301,301,301,301,301,301,301, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302, 92, 92, +302,302,302,302,302, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 48 */ -294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, -294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, -294,294,294,294,294,294,294,294,294,294,294,294, 89, 89, 89, 89, -295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295, -295,294,294,294,294,294,294,294,295,295, 89, 89, 89, 89, 89, 89, -296,296,296,296,296,296,296,296,296,296,296, 89, 89, 89,297,297, -298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, -298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, +303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, +303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, +303,303,303,303,303,303,303,303,303,303,303,303, 92, 92, 92, 92, +304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304, +304,303,303,303,303,303,303,303,304,304, 92, 92, 92, 92, 92, 92, +305,305,305,305,305,305,305,305,305,305,306, 92, 92, 92,307,307, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, /* block 49 */ -299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299, -299,299,299,299,299,299,299,300,300,301,301,301, 89, 89,302,302, -303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, -303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, -303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, -303,303,303,303,303,304,305,304,305,305,305,305,305,305,305, 89, -305,304,305,304,304,305,305,305,305,305,305,305,305,304,304,304, -304,304,304,305,305,305,305,305,305,305,305,305,305, 89, 89,305, +309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309, +309,309,309,309,309,309,309,310,310,311,311,311, 92, 92,312,312, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,314,315,314,315,315,315,315,315,315,315, 92, +315,314,315,314,314,315,315,315,315,315,315,315,315,314,314,314, +314,314,314,315,315,315,315,315,315,315,315,315,315, 92, 92,315, /* block 50 */ -306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89, -306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89, -307,307,307,307,307,307,307,308,307,307,307,307,307,307, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, +316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, +317,317,317,317,317,317,317,318,317,317,317,317,317,317, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 51 */ -309,309,309,309,310,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,309,310,309,309,309,309,309,310,309,310,310,310, -310,310,309,310,310,311,311,311,311,311,311,311, 89, 89, 89, 89, -312,312,312,312,312,312,312,312,312,312,313,313,313,313,313,313, -313,314,314,314,314,314,314,314,314,314,314,309,309,309,309,309, -309,309,309,309,314,314,314,314,314,314,314,314,314, 89, 89, 89, +319,319,319,319,320,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,319,320,319,319,319,319,319,320,319,320,320,320, +320,320,319,320,320,321,321,321,321,321,321,321, 92, 92, 92, 92, +322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323, +323,324,324,324,324,324,324,324,324,324,324,319,319,319,319,319, +319,319,319,319,324,324,324,324,324,324,324,324,324, 92, 92, 92, /* block 52 */ -315,315,316,317,317,317,317,317,317,317,317,317,317,317,317,317, -317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317, -317,316,315,315,315,315,316,316,315,315,316, 89, 89, 89,317,317, -318,318,318,318,318,318,318,318,318,318, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +325,325,326,327,327,327,327,327,327,327,327,327,327,327,327,327, +327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, +327,326,325,325,325,325,326,326,325,325,326,325,326,326,327,327, +328,328,328,328,328,328,328,328,328,328,327,327,327,327,327,327, +329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, +329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, +329,329,329,329,329,329,330,331,330,330,331,331,331,330,331,330, +330,330,331,331, 92, 92, 92, 92, 92, 92, 92, 92,332,332,332,332, /* block 53 */ -319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319, -319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319, -319,319,319,319,320,320,320,320,320,320,320,320,321,321,321,321, -321,321,321,321,320,320,321,321, 89, 89, 89,322,322,322,322,322, -323,323,323,323,323,323,323,323,323,323, 89, 89, 89,319,319,319, -324,324,324,324,324,324,324,324,324,324,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,326,326,326,326,326,326,327,327, +333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, +333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, +333,333,333,333,334,334,334,334,334,334,334,334,335,335,335,335, +335,335,335,335,334,334,335,335, 92, 92, 92,336,336,336,336,336, +337,337,337,337,337,337,337,337,337,337, 92, 92, 92,333,333,333, +338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,340,340,340,340,340,340,341,341, /* block 54 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84,328, 84, 84, 84, 84, 84, 84, 84,329,329,329,329, 84,329,329, -329,329,328, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +342,342,342,342,342,342,342,342, 92, 92, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87,343, 87, 87, 87, 87, 87, 87, 87,344,344,344,344, 87,344,344, +344,344,343,343, 87,344,344, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 55 */ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 96, 96, 96, 96, 96,330, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, 90, 90, - 90, 90, 14, 14, 14, 14, 96, 96, 96, 96, 96, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14,331,332, 14, 14, 14,333, 14, 14, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 99, 99, 99, 99, 99,345, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, 93, 93, + 93, 93, 84, 84, 84, 84, 93, 93, 93, 93, 93, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20,346,347, 20, 20, 20,348, 20, 20, /* block 56 */ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87, /* block 57 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 58 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 14, 14, 14, 14, 14,334, 14, 14,335, 14, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 20, 20, 20, 20, 20,349, 20, 20,350, 20, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 59 */ -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89, - 96,336, 96,336, 96,336, 96,336, 89,337, 89,337, 89,337, 89,337, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -338,338,339,339,339,339,340,340,341,341,342,342,343,343, 89, 89, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, + 99,351, 99,351, 99,351, 99,351, 92,352, 92,352, 92,352, 92,352, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +353,353,354,354,354,354,355,355,356,356,357,357,358,358, 92, 92, /* block 60 */ -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336, 96,345, 96, 89, 96, 96,337,337,346,346,347, 88,348, 88, - 88, 88, 96,345, 96, 89, 96, 96,349,349,349,349,347, 88, 88, 88, -336,336, 96, 96, 89, 89, 96, 96,337,337,350,350, 89, 88, 88, 88, -336,336, 96, 96, 96,115, 96, 96,337,337,351,351,119, 88, 88, 88, - 89, 89, 96,345, 96, 89, 96, 96,352,352,353,353,347, 88, 88, 89, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351, 99,360, 99, 92, 99, 99,352,352,361,361,362, 91,363, 91, + 91, 91, 99,360, 99, 92, 99, 99,364,364,364,364,362, 91, 91, 91, +351,351, 99, 99, 92, 92, 99, 99,352,352,365,365, 92, 91, 91, 91, +351,351, 99, 99, 99,118, 99, 99,352,352,366,366,122, 91, 91, 91, + 92, 92, 99,360, 99, 92, 99, 99,367,367,368,368,362, 91, 91, 92, /* block 61 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,354,354, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,369,369, 16, 16, 7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15, - 2, 2, 2, 2, 2, 2, 2, 2,355,356, 16, 16, 16, 16, 16, 1, + 2, 2, 2, 2, 2, 2, 2, 2,370,371, 16, 16, 16, 16, 16, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11, 11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, - 16, 16, 16, 16, 16, 89, 89, 89, 89, 89, 16, 16, 16, 16, 16, 16, - 17, 82, 89, 89, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 82, + 16, 16, 16, 16, 16, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16, + 17, 84, 92, 92, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 84, /* block 62 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 89, - 82, 82, 82, 82, 82, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 92, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,357,357,357, -357, 84,357,357,357, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,372,372,372, +372, 87,372,372,372, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 63 */ - 13, 13,358, 13, 13, 13, 13,358, 13, 13,359,358,358,358,359,359, -358,358,358,359, 13,358, 13, 13, 13,358,358,358,358,358, 13, 13, - 13, 13, 13, 13,358, 13,360, 13,358, 13,361,362,358,358, 13,359, -358,358,363,358,359,329,329,329,329,359, 13, 13,359,359,358,358, - 6, 6, 6, 6, 6,358,359,359,359,359, 13, 6, 13, 13,364, 13, + 13, 13,373, 13, 13, 13, 13,373, 13, 13,374,373,373,373,374,374, +373,373,373,374, 13,373, 13, 13, 6,373,373,373,373,373, 13, 13, + 13, 13, 13, 13,373, 13,375, 13,373, 13,376,377,373,373, 13,374, +373,373,378,373,374,344,344,344,344,374, 13, 13,374,374,373,373, + 6, 6, 6, 6, 6,373,374,374,374,374, 13, 6, 13, 13,379, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366, +380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, /* block 64 */ -367,367,367, 21, 22,367,367,367,367, 17, 89, 89, 89, 89, 89, 89, +382,382,382, 22, 23,382,382,382,382, 17, 92, 92, 92, 92, 92, 92, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13, 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1776,16 +1825,16 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, - 6, 6, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 68 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1793,10 +1842,10 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13,368,368,368,368,368,368,368,368,368,368, -368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369, 17, 17, 17, 17, 17, 17, + 13, 13, 13, 13, 13, 13,383,383,383,383,383,383,383,383,383,383, +383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, +384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, +384,384,384,384,384,384,384,384,384,384, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 70 */ @@ -1830,46 +1879,36 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 73 */ + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 89, 13, 89, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - -/* block 74 */ - 89, 13, 13, 13, 13, 89, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 89, 13, - 13, 13, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 89, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, + 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -/* block 75 */ +/* block 74 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 89, 6, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -/* block 76 */ -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, +/* block 75 */ +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, -/* block 77 */ +/* block 76 */ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -1879,145 +1918,155 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6, -/* block 78 */ +/* block 77 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 78 */ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 79 */ -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, 89, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, 89, - 21, 22,373,374,375,376,377, 21, 22, 21, 22, 21, 22,378,379,380, -381, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 82,382,382, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 92, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 92, + 22, 23,388,389,390,391,392, 22, 23, 22, 23, 22, 23,393,394,395, +396, 20, 22, 23, 20, 22, 23, 20, 20, 20, 20, 20, 84, 84,397,397, /* block 80 */ -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,383,384,384,384,384,384,384,111,112,111,112,385, -385,385, 89, 89, 89, 89, 89, 89, 89,386,386,386,386,387,386,386, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,398,399,399,399,399,399,399,114,115,114,115,400, +400,400,114,115, 92, 92, 92, 92, 92,401,401,401,401,402,401,401, /* block 81 */ -388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388, -388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388, -388,388,388,388,388,388, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389, 89, 89, 89, 89, 89, 89, 89, 89, 89,390, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, +403,403,403,403,403,403, 92,403, 92, 92, 92, 92, 92,403, 92, 92, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404, 92, 92, 92, 92, 92, 92, 92,405, +406, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,407, /* block 82 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248, 89, 89, 89, 89, 89, 89, 89, 89, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, /* block 83 */ 2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2, - 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 83, - 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 85, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 84 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391, 89,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408, 92,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 85 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, /* block 86 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, /* block 87 */ - 1, 2, 2, 2, 13,392,329,393, 4, 5, 4, 5, 4, 5, 4, 5, + 1, 2, 2, 2, 13,409,344,410, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5, - 13,393,393,393,393,393,393,393,393,393, 84, 84, 84, 84, 84, 84, - 7, 83, 83, 83, 83, 83, 13, 13,393,393,393,392,329, 2, 13, 13, - 89,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, + 13,410,410,410,410,410,410,410,410,410, 87, 87, 87, 87,411,411, + 7, 85, 85, 85, 85, 85, 13, 13,410,410,410,409,344, 2, 13, 13, + 92,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, /* block 88 */ -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394, 89, 89, 84, 84, 10, 10,395,395,394, - 7,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396, 2, 83,397,397,396, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412, 92, 92, 87, 87, 10, 10,413,413,412, + 7,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414, 2, 85,415,415,414, /* block 89 */ - 89, 89, 89, 89, 89,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398, 89, 89, - 89,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, + 92, 92, 92, 92, 92,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416, 92, 92, + 92,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 90 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398, 89, 89, 89, 89, 89, 89, 89, 89, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 91 */ -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 89, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 13, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 13, /* block 92 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, @@ -2025,799 +2074,1019 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, 89, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 92, /* block 93 */ -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400, 13, 13, 13, 13, 13, 13, 13, 13, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 94 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 95 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 96 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 97 */ -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,403,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,421,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 98 */ -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 99 */ -402,402,402,402,402,402,402,402,402,402,402,402,402, 89, 89, 89, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404, 89, 89, 89, 89, 89, 89, 89, 89, 89, -405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405, -405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405, -405,405,405,405,405,405,405,405,406,406,406,406,406,406,407,407, +420,420,420,420,420,420,420,420,420,420,420,420,420, 92, 92, 92, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422, 92, 92, 92, 92, 92, 92, 92, 92, 92, +423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, +423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, +423,423,423,423,423,423,423,423,424,424,424,424,424,424,425,425, /* block 100 */ -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, /* block 101 */ -408,408,408,408,408,408,408,408,408,408,408,408,409,410,410,410, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -411,411,411,411,411,411,411,411,411,411,408,408, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, - 89, 89,125,126,125,126,125,126,125,126,125,126,125,126,412,128, -129,129,129,413, 89, 89, 89, 89, 89, 89, 89, 89,128,128,413,331, +426,426,426,426,426,426,426,426,426,426,426,426,427,428,428,428, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +429,429,429,429,429,429,429,429,429,429,426,426, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,430,131, +132,132,132,431,131,131,131,131,131,131,131,131,131,131,431,346, /* block 102 */ -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,415,415,415,415,415,415,415,415,415,415, -416,416,417,417,417,417,417,417, 89, 89, 89, 89, 89, 89, 89, 89, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92,131, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,433, +434,434,435,435,435,435,435,435, 92, 92, 92, 92, 92, 92, 92, 92, /* block 103 */ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 10, 10, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 14, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 82, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,418, 21, 22, + 10, 10, 10, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 10, 10, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 20, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 84, 20, 20, 20, 20, 20, 20, 20, 20, 22, 23, 22, 23,436, 22, 23, /* block 104 */ - 21, 22, 21, 22, 21, 22, 21, 22, 83, 10, 10, 21, 22, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 45, 45, 45, 45, 45, + 22, 23, 22, 23, 22, 23, 22, 23, 85, 10, 10, 22, 23,437, 20, 92, + 22, 23, 22, 23, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,438, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 84, 84, 20, 14, 14, 14, 14, 14, /* block 105 */ -419,419,420,419,419,419,420,419,419,419,419,420,419,419,419,419, -419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, -419,419,419,421,421,420,420,421,422,422,422,422, 89, 89, 89, 89, - 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 89, 89, 89, 89, 89, 89, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,424,424,424,424, 89, 89, 89, 89, 89, 89, 89, 89, +439,439,440,439,439,439,440,439,439,439,439,440,439,439,439,439, +439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439, +439,439,439,441,441,440,440,441,442,442,442,442, 92, 92, 92, 92, + 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 92, 92, 92, 92, 92, 92, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,444,444,444,444, 92, 92, 92, 92, 92, 92, 92, 92, /* block 106 */ -425,425,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,425,425,425,425,425,425,425,425,425,425,425,425, -425,425,425,425,427, 89, 89, 89, 89, 89, 89, 89, 89, 89,428,428, -429,429,429,429,429,429,429,429,429,429, 89, 89, 89, 89, 89, 89, -167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, -167,167,169,169,169,169,169,169,430,430,430,169, 89, 89, 89, 89, +445,445,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,445,445,445,445,445,445,445,445,445,445,445,445, +445,445,445,445,447, 92, 92, 92, 92, 92, 92, 92, 92, 92,448,448, +449,449,449,449,449,449,449,449,449,449, 92, 92, 92, 92, 92, 92, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,176,176,176,176,176,176,178,178,178,176, 92, 92, 92, 92, /* block 107 */ -431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432, -432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, -432,432,432,432,432,432,433,433,433,433,433,433,433,433,434,434, -435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435, -435,435,435,435,435,435,435,436,436,436,436,436,436,436,436,436, -436,436,437,437, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,438, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89, +450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451, +451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, +451,451,451,451,451,451,452,452,452,452,452,452,452,452,453,453, +454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454, +454,454,454,454,454,454,454,455,455,455,455,455,455,455,455,455, +455,455,456,456, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,457, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, /* block 108 */ -439,439,439,440,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,439,440,440,439,439,439,439,440,440,439,440,440,440, -440,442,442,442,442,442,442,442,442,442,442,442,442,442, 89,443, -444,444,444,444,444,444,444,444,444,444, 89, 89, 89, 89,442,442, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +458,458,458,459,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,458,459,459,458,458,458,458,459,459,458,459,459,459, +459,461,461,461,461,461,461,461,461,461,461,461,461,461, 92,462, +463,463,463,463,463,463,463,463,463,463, 92, 92, 92, 92,461,461, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 109 */ -445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445, -445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445, -445,445,445,445,445,445,445,445,445,446,446,446,446,446,446,447, -447,446,446,447,447,446,446, 89, 89, 89, 89, 89, 89, 89, 89, 89, -445,445,445,446,445,445,445,445,445,445,445,445,446,447, 89, 89, -448,448,448,448,448,448,448,448,448,448, 89, 89,449,449,449,449, -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -450,238,238,238,238,238,238,243,243,243,238,239, 89, 89, 89, 89, +464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, +464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, +464,464,464,464,464,464,464,464,464,465,465,465,465,465,465,466, +466,465,465,466,466,465,465, 92, 92, 92, 92, 92, 92, 92, 92, 92, +464,464,464,465,464,464,464,464,464,464,464,464,465,466, 92, 92, +467,467,467,467,467,467,467,467,467,467, 92, 92,468,468,468,468, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +469,248,248,248,248,248,248,253,253,253,248,249, 92, 92, 92, 92, /* block 110 */ -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -452,451,452,452,452,451,451,452,452,451,451,451,451,451,452,452, -451,452,451, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,451,451,453,454,454, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +471,470,471,471,471,470,470,471,471,470,470,470,470,470,471,471, +470,471,470, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,470,470,472,473,473, +474,474,474,474,474,474,474,474,474,474,474,475,476,476,475,475, +477,477,474,478,478,475,476, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 111 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455, -455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455, -455,455,455,456,456,457,456,456,457,456,456,458,456,457, 89, 89, -459,459,459,459,459,459,459,459,459,459, 89, 89, 89, 89, 89, 89, + 92,258,258,258,258,258,258, 92, 92,258,258,258,258,258,258, 92, + 92,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 112 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247, 89, 89, 89, 89,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, +474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, +474,474,474,475,475,476,475,475,476,475,475,477,475,476, 92, 92, +479,479,479,479,479,479,479,479,479,479, 92, 92, 92, 92, 92, 92, /* block 113 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257, 92, 92, 92, 92,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, 92, /* block 114 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, /* block 115 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, /* block 116 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 117 */ - 14, 14, 14, 14, 14, 14, 14, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89,136,136,136,136,136, 89, 89, 89, 89, 89,141,138,141, -141,141,141,141,141,141,141,141,141,462,141,141,141,141,141,141, -141,141,141,141,141,141,141, 89,141,141,141,141,141, 89,141, 89, -141,141, 89,141,141, 89,141,141,141,141,141,141,141,141,141,141, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 118 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, + 20, 20, 20, 20, 20, 20, 20, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92,139,139,139,139,139, 92, 92, 92, 92, 92,145,142,145, +145,145,145,145,145,145,145,145,145,482,145,145,145,145,145,145, +145,145,145,145,145,145,145, 92,145,145,145,145,145, 92,145, 92, +145,145, 92,145,145, 92,145,145,145,145,145,145,145,145,145,145, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 119 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 120 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147, 4, 5, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 121 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, - 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -147,147,147,147,147,147,147,147,147,147,147,147,144, 13, 89, 89, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152, 4, 5, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 122 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, - 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11, - 2, 2, 2, 89, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, - 2, 2, 6, 7, 6, 6, 6, 89, 2, 3, 2, 2, 89, 89, 89, 89, -147,147,147,147,147, 89,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152,152,152,152,152,152,152,152,152,152,152,152,149, 13, 92, 92, /* block 123 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147, 89, 89, 16, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, + 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11, + 2, 2, 2, 92, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, + 2, 2, 6, 7, 6, 6, 6, 92, 2, 3, 2, 2, 92, 92, 92, 92, +152,152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152, /* block 124 */ - 89, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 16, + +/* block 125 */ + 92, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4, - 5, 2, 4, 5, 2, 2,396,396,396,396,396,396,396,396,396,396, - 83,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, - -/* block 125 */ -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396, 83, 83, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89, - 89, 89,247,247,247,247,247,247, 89, 89,247,247,247,247,247,247, - 89, 89,247,247,247,247,247,247, 89, 89,247,247,247, 89, 89, 89, - 3, 3, 6, 10, 13, 3, 3, 89, 13, 6, 6, 6, 6, 13, 13, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 16, 16, 16, 13, 13, 89, 89, + 5, 2, 4, 5, 2, 2,414,414,414,414,414,414,414,414,414,414, + 85,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 126 */ -463,463,463,463,463,463,463,463,463,463,463,463, 89,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463, 89,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463, 89,463,463, 89,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89, -463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414, 85, 85, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, + 92, 92,257,257,257,257,257,257, 92, 92,257,257,257,257,257,257, + 92, 92,257,257,257,257,257,257, 92, 92,257,257,257, 92, 92, 92, + 3, 3, 6, 10, 13, 3, 3, 92, 13, 6, 6, 6, 6, 13, 13, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 13, 13, 92, 92, /* block 127 */ -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463, 89, 89, 89, 89, 89, +484,484,484,484,484,484,484,484,484,484,484,484, 92,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484, 92,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484, 92,484,484, 92,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, +484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 128 */ - 2, 2, 13, 89, 89, 89, 89, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,465,465,465,465,466,466,466,466,466,466,466, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484, 92, 92, 92, 92, 92, /* block 129 */ -466,466,466,466,466,466,466,466,466,466,465, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 89, 89, + 2, 2, 2, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,486,486,486,486,487,487,487,487,487,487,487, /* block 130 */ -467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467, -467,467,467,467,467,467,467,467,467,467,467,467,467, 89, 89, 89, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +487,487,487,487,487,487,487,487,487,487,486, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 92, 92, /* block 131 */ -469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, -469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, 89, -470,470,470,470, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,472,471,471,471,471,471,471,471,471,472, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488, +488,488,488,488,488,488,488,488,488,488,488,488,488, 92, 92, 92, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 132 */ -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473, 89,474, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475, 89, 89, 89, 89,475,475,475,475,475,475,475,475, -476,477,477,477,477,477, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, +490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, 92, +491,491,491,491, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,493,492,492,492,492,492,492,492,492,493, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 133 */ -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494, +494,494,494,494,494,494,494,494,494,494,494,494,494,494, 92,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496, 92, 92, 92, 92,496,496,496,496,496,496,496,496, +497,498,498,498,498,498, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 134 */ -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481, 89, 89, -482,482,482,482,482,482,482,482,482,482, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, +499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, +499,499,499,499,499,499,499,499,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, /* block 135 */ -483,483,483,483,483,483, 89, 89,483, 89,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483, 89,483,483, 89, 89, 89,483, 89, 89,483, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484, 89,485,486,486,486,486,486,486,486,486, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502, 92, 92, +503,503,503,503,503,503,503,503,503,503, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 136 */ -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,488,488,488,488,488,488, 89, 89, 89,489, -490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, -490,490,490,490,490,490,490,490,490,490, 89, 89, 89, 89, 89,491, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +504,504,504,504,504,504, 92, 92,504, 92,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504, 92,504,504, 92, 92, 92,504, 92, 92,504, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505, 92,506,507,507,507,507,507,507,507,507, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 137 */ -492,493,493,493, 89,493,493, 89, 89, 89, 89, 89,493,493,493,493, -492,492,492,492, 89,492,492,492, 89,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492, 89, 89, 89, 89,493,493,493, 89, 89, 89, 89,493, -494,494,494,494,494,494,494,494, 89, 89, 89, 89, 89, 89, 89, 89, -495,495,495,495,495,495,495,495,495, 89, 89, 89, 89, 89, 89, 89, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,497,497,498, +508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508, +508,508,508,508,508,508,509,509,509,509,509,509, 92, 92, 92,510, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511, 92, 92, 92, 92, 92,512, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 138 */ -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499, 89, 89, 89,500,500,500,500,500,500,500, -501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, -501,501,501,501,501,501, 89, 89,502,502,502,502,502,502,502,502, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503, 89, 89, 89, 89, 89,504,504,504,504,504,504,504,504, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514, 92, 92, 92, 92, 92, 92,514,514, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 139 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +515,516,516,516, 92,516,516, 92, 92, 92, 92, 92,516,516,516,516, +515,515,515,515, 92,515,515,515, 92,515,515,515,515,515,515,515, +515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +515,515,515,515, 92, 92, 92, 92,516,516,516, 92, 92, 92, 92,516, +517,517,517,517,517,517,517,517, 92, 92, 92, 92, 92, 92, 92, 92, +518,518,518,518,518,518,518,518,518, 92, 92, 92, 92, 92, 92, 92, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519,519,519,519,519,519,519,519,519,519,519,520,520,521, /* block 140 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, 89, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522, 92, 92, 92,523,523,523,523,523,523,523, +524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +524,524,524,524,524,524, 92, 92,525,525,525,525,525,525,525,525, +526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, +526,526,526, 92, 92, 92, 92, 92,527,527,527,527,527,527,527,527, /* block 141 */ -507,507,508,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -508,508,508,507,507,507,507,508,508,507,507,510,510,511,510,510, -510,510, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 142 */ -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, 92, /* block 143 */ -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +530,531,530,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,533,533,533,533,533,533,533, 92, 92, + 92, 92,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,535,535,535,535,535,535,535,535,535,535, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 144 */ -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -514,514,514,514, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +536,536,537,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +537,537,537,536,536,536,536,537,537,536,536,539,539,540,539,539, +539,539, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541, 92, 92, 92, 92, 92, 92, 92, +542,542,542,542,542,542,542,542,542,542, 92, 92, 92, 92, 92, 92, /* block 145 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +543,543,543,544,544,544,544,544,544,544,544,544,544,544,544,544, +544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, +544,544,544,544,544,544,544,543,543,543,543,543,545,543,543,543, +543,543,543,543,543, 92,546,546,546,546,546,546,546,546,546,546, +547,547,547,547, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 146 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +548,548,549,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,549,549,549,548,548,548,548,548,548,548,548,548,549, +549,550,550,550,550,551,551,551,551, 92, 92, 92, 92, 92, 92, 92, +552,552,552,552,552,552,552,552,552,552, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 147 */ - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,554,555,554,555,555, +554,554,554,554,554,554,555,554, 92, 92, 92, 92, 92, 92, 92, 92, +556,556,556,556,556,556,556,556,556,556, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 148 */ - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13,328,328, 84, 84, 84, 13, 13, 13,328,328,328, -328,328,328, 16, 16, 16, 16, 16, 16, 16, 16, 84, 84, 84, 84, 84, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, /* block 149 */ - 84, 84, 84, 13, 13, 84, 84, 84, 84, 84, 84, 84, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 84, 84, 84, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 150 */ -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,516,516,516,466, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +559,559,559,559, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 151 */ - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, /* block 152 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359, -359,359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 153 */ -358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358, 89,358,358, - 89, 89,358, 89, 89,358,358, 89, 89,358,358,358,358, 89,358,358, -358,358,358,358,358,358,359,359,359,359, 89,359, 89,359,359,359, -359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, /* block 154 */ -359,359,359,359,358,358, 89,358,358,358,358, 89, 89,358,358,358, -358,358,358,358,358, 89,358,358,358,358,358,358,358, 89,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,358,358, 89,358,358,358,358, 89, -358,358,358,358,358, 89,358, 89, 89, 89,358,358,358,358,358,358, -358, 89,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 155 */ -358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +561,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 92, /* block 156 */ -359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,563, +563,563,563,564,564,564,564,564,564,564,564,564,564,564,564,564, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 157 */ -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359, 89, 89,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358, 6,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359, 6,359,359,359,359, -359,359,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358, 6,359,359,359,359, +414,412, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 158 */ -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359, 6,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358, 6,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 6, -359,359,359,359,359,359,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 6, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 159 */ -359,359,359,359,359,359,359,359,359, 6,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358, 6,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359, 6,359,359,359,359,359,359,358,359, 89, 89, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13,343,343, 87, 87, 87, 13, 13, 13,343,343,343, +343,343,343, 16, 16, 16, 16, 16, 16, 16, 16, 87, 87, 87, 87, 87, /* block 160 */ + 87, 87, 87, 13, 13, 87, 87, 87, 87, 87, 87, 87, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 87, 87, 87, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 161 */ - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,565,565,565,487, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 162 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 89, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13, - 89, 89, 13, 89, 89, 89, 13, 89, 89, 89, 13, 13, 13, 13, 13, 89, - 89, 89, 89, 89, 89, 89, 89, 13, 89, 89, 89, 89, 89, 89, 89, 13, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13, 13, 89, 89, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 163 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 13, 13, 13, 89, 89, - 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, +374,374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 164 */ -517, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373, 92,373,373, + 92, 92,373, 92, 92,373,373, 92, 92,373,373,373,373, 92,373,373, +373,373,373,373,373,373,374,374,374,374, 92,374, 92,374,374,374, +374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 165 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +374,374,374,374,373,373, 92,373,373,373,373, 92, 92,373,373,373, +373,373,373,373,373, 92,373,373,373,373,373,373,373, 92,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,373,373, 92,373,373,373,373, 92, +373,373,373,373,373, 92,373, 92, 92, 92,373,373,373,373,373,373, +373, 92,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 166 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 167 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, /* block 168 */ - 89, 16, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374, 92, 92,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373, 6,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374, 6,374,374,374,374, +374,374,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373, 6,374,374,374,374, /* block 169 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374, 6,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373, 6,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 6, +374,374,374,374,374,374,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 6, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, /* block 170 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +374,374,374,374,374,374,374,374,374, 6,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373, 6,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374, 6,374,374,374,374,374,374,373,374, 92, 92, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* block 171 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461, 89, 89, +152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 92,152,152, 92,152, 92, 92,152, 92,152,152,152,152,152,152,152, +152,152,152, 92,152,152,152,152, 92,152, 92,152, 92, 92, 92, 92, + 92, 92,152, 92, 92, 92, 92,152, 92,152, 92,152, 92,152,152,152, + 92,152,152, 92,152, 92, 92,152, 92,152, 92,152, 92,152, 92,152, + 92,152,152, 92,152, 92, 92,152,152,152,152, 92,152,152,152,152, +152,152,152, 92,152,152,152,152, 92,152,152,152,152, 92,152, 92, + +/* block 172 */ +152,152,152,152,152,152,152,152,152,152, 92,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, + 92,152,152,152, 92,152,152,152,152,152, 92,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +147,147, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 173 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + +/* block 174 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 175 */ + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + +/* block 176 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + +/* block 177 */ +566, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 178 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, + +/* block 179 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 180 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + +/* block 181 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 92, 92, 92, + +/* block 182 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 183 */ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, + +/* block 184 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 185 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 186 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 187 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 188 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, + +/* block 189 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 190 */ + 92, 16, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + +/* block 191 */ + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + +/* block 192 */ + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 193 */ +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481, 92, 92, }; diff --git a/ext/pcre/pcrelib/pcre_valid_utf8.c b/ext/pcre/pcrelib/pcre_valid_utf8.c index d54d3bd2d6a..f49832dc5b8 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-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -52,127 +52,246 @@ strings. */ *************************************************/ /* This function is called (optionally) at the start of compile or match, to -validate that a supposed UTF-8 string is actually valid. The early check means +check that a supposed UTF-8 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check -can be turned off for maximum performance, but the consequences of supplying -an invalid string are then undefined. +can be turned off for maximum performance, but the consequences of supplying an +invalid string are then undefined. Originally, this function checked according to RFC 2279, allowing for values in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in the canonical format. Once somebody had pointed out RFC 3629 to me (it obsoletes 2279), additional restrictions were applied. The values are now limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the -subrange 0xd000 to 0xdfff is excluded. +subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte +characters is still checked. + +From release 8.13 more information about the details of the error are passed +back in the returned value: + +PCRE_UTF8_ERR0 No error +PCRE_UTF8_ERR1 Missing 1 byte at the end of the string +PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string +PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string +PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string +PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string +PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80 +PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80 +PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629 +PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629 +PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted +PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted +PCRE_UTF8_ERR15 Overlong 2-byte sequence +PCRE_UTF8_ERR16 Overlong 3-byte sequence +PCRE_UTF8_ERR17 Overlong 4-byte sequence +PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) +PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) +PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) +PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff Arguments: string points to the string length length of string, or -1 if the string is zero-terminated + errp pointer to an error position offset variable -Returns: < 0 if the string is a valid UTF-8 string - >= 0 otherwise; the value is the offset of the bad byte - -Bad bytes can be: - - . An isolated byte whose most significant bits are 0x80, because this - can only correctly appear within a UTF-8 character; - - . A byte whose most significant bits are 0xc0, but whose other bits indicate - that there are more than 3 additional bytes (i.e. an RFC 2279 starting - byte, which is no longer valid under RFC 3629); - - . - -The returned offset may also be equal to the length of the string; this means -that one or more bytes is missing from the final UTF-8 character. +Returns: = 0 if the string is a valid UTF-8 string + > 0 otherwise, setting the offset of the bad character */ int -_pcre_valid_utf8(USPTR string, int length) +PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset) { -#ifdef SUPPORT_UTF8 -register USPTR p; +#ifdef SUPPORT_UTF +register PCRE_PUCHAR p; if (length < 0) { for (p = string; *p != 0; p++); - length = p - string; + length = (int)(p - string); } for (p = string; length-- > 0; p++) { - register int ab; - register int c = *p; - if (c < 128) continue; - if (c < 0xc0) return p - string; - ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ - if (ab > 3) return p - string; /* Too many for RFC 3629 */ - if (length < ab) return p + 1 + length - string; /* Missing bytes */ - length -= ab; + register int ab, c, d; + + c = *p; + if (c < 128) continue; /* ASCII character */ + + if (c < 0xc0) /* Isolated 10xx xxxx byte */ + { + *erroroffset = (int)(p - string); + return PCRE_UTF8_ERR20; + } + + if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */ + { + *erroroffset = (int)(p - string); + return PCRE_UTF8_ERR21; + } + + ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ + if (length < ab) + { + *erroroffset = (int)(p - string); /* Missing bytes */ + return ab - length; /* Codes ERR1 to ERR5 */ + } + length -= ab; /* Length remaining */ /* Check top bits in the second byte */ - if ((*(++p) & 0xc0) != 0x80) return p - string; - /* Check for overlong sequences for each different length, and for the - excluded range 0xd000 to 0xdfff. */ + if (((d = *(++p)) & 0xc0) != 0x80) + { + *erroroffset = (int)(p - string) - 1; + return PCRE_UTF8_ERR6; + } + + /* For each length, check that the remaining bytes start with the 0x80 bit + set and not the 0x40 bit. Then check for an overlong sequence, and for the + excluded range 0xd800 to 0xdfff. */ switch (ab) { - /* Check for xx00 000x (overlong sequence) */ + /* 2-byte character. No further bytes to check for 0x80. Check first byte + for for xx00 000x (overlong sequence). */ - case 1: - if ((c & 0x3e) == 0) return p - string; - continue; /* We know there aren't any more bytes to check */ + case 1: if ((c & 0x3e) == 0) + { + *erroroffset = (int)(p - string) - 1; + return PCRE_UTF8_ERR15; + } + break; - /* Check for 1110 0000, xx0x xxxx (overlong sequence) or - 1110 1101, 1010 xxxx (0xd000 - 0xdfff) */ + /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes + for 1110 0000, xx0x xxxx (overlong sequence) or + 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */ case 2: - if ((c == 0xe0 && (*p & 0x20) == 0) || - (c == 0xed && *p >= 0xa0)) - return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if (c == 0xe0 && (d & 0x20) == 0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR16; + } + if (c == 0xed && d >= 0xa0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR14; + } break; - /* Check for 1111 0000, xx00 xxxx (overlong sequence) or - greater than 0x0010ffff (f4 8f bf bf) */ + /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 + bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a + character greater than 0x0010ffff (f4 8f bf bf) */ case 3: - if ((c == 0xf0 && (*p & 0x30) == 0) || - (c > 0xf4 ) || - (c == 0xf4 && *p > 0x8f)) - return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if (c == 0xf0 && (d & 0x30) == 0) + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR17; + } + if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR13; + } break; -#if 0 - /* These cases can no longer occur, as we restrict to a maximum of four - bytes nowadays. Leave the code here in case we ever want to add an option - for longer sequences. */ + /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be + rejected by the length test below. However, we do the appropriate tests + here so that overlong sequences get diagnosed, and also in case there is + ever an option for handling these larger code points. */ + + /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for + 1111 1000, xx00 0xxx */ - /* Check for 1111 1000, xx00 0xxx */ case 4: - if (c == 0xf8 && (*p & 0x38) == 0) return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR9; + } + if (c == 0xf8 && (d & 0x38) == 0) + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR18; + } break; - /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ + /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for + 1111 1100, xx00 00xx. */ + case 5: - if (c == 0xfe || c == 0xff || - (c == 0xfc && (*p & 0x3c) == 0)) return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR9; + } + if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ + { + *erroroffset = (int)(p - string) - 5; + return PCRE_UTF8_ERR10; + } + if (c == 0xfc && (d & 0x3c) == 0) + { + *erroroffset = (int)(p - string) - 5; + return PCRE_UTF8_ERR19; + } break; -#endif - } - /* Check for valid bytes after the 2nd, if any; all must start 10 */ - while (--ab > 0) + /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are + excluded by RFC 3629. The pointer p is currently at the last byte of the + character. */ + + if (ab > 3) { - if ((*(++p) & 0xc0) != 0x80) return p - string; + *erroroffset = (int)(p - string) - ab; + return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; } } -#else + +#else /* SUPPORT_UTF */ (void)(string); /* Keep picky compilers happy */ (void)(length); #endif -return -1; +return PCRE_UTF8_ERR0; /* This indicates success */ } /* End of pcre_valid_utf8.c */ diff --git a/ext/pcre/pcrelib/pcre_version.c b/ext/pcre/pcrelib/pcre_version.c index bd63f41e6eb..3dd60a5bc2e 100644 --- a/ext/pcre/pcrelib/pcre_version.c +++ b/ext/pcre/pcrelib/pcre_version.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-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -77,8 +77,13 @@ I could find no way of detecting that a macro is defined as an empty string at pre-processor time. This hack uses a standard trick for avoiding calling the STRING macro with an empty argument when doing the test. */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION pcre_version(void) +#else +PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION +pcre16_version(void) +#endif { return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)? XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) : diff --git a/ext/pcre/pcrelib/pcre_xclass.c b/ext/pcre/pcrelib/pcre_xclass.c index 98841c5560c..446f85db537 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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -62,39 +62,63 @@ Returns: TRUE if character matches, else FALSE */ BOOL -_pcre_xclass(int c, const uschar *data) +PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf) { int t; BOOL negated = (*data & XCL_NOT) != 0; +(void)utf; +#ifdef COMPILE_PCRE8 +/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ +utf = TRUE; +#endif + /* Character values < 256 are matched against a bitmap, if one is present. If not, we still carry on, because there may be ranges that start below 256 in the additional data. */ if (c < 256) { - if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0) - return !negated; /* char found */ + if ((*data & XCL_MAP) != 0 && + (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0) + return !negated; /* char found */ } /* First skip the bit map if present. Then match against the list of Unicode properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ -if ((*data++ & XCL_MAP) != 0) data += 32; +if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar); while ((t = *data++) != XCL_END) { int x, y; if (t == XCL_SINGLE) { - GETCHARINC(x, data); +#ifdef SUPPORT_UTF + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + } + else +#endif + x = *data++; if (c == x) return !negated; } else if (t == XCL_RANGE) { - GETCHARINC(x, data); - GETCHARINC(y, data); +#ifdef SUPPORT_UTF + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + GETCHARINC(y, data); /* macro generates multiple statements */ + } + else +#endif + { + x = *data++; + y = *data++; + } if (c >= x && c <= y) return !negated; } @@ -115,7 +139,7 @@ while ((t = *data++) != XCL_END) break; case PT_GC: - if ((data[1] == _pcre_ucp_gentype[prop->chartype]) == (t == XCL_PROP)) + if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP)) return !negated; break; @@ -128,28 +152,28 @@ while ((t = *data++) != XCL_END) break; case PT_ALNUM: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == (t == XCL_PROP)) + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP)) return !negated; break; case PT_SPACE: /* Perl space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_PXSPACE: /* POSIX space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_WORD: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (t == XCL_PROP)) return !negated; break; diff --git a/ext/pcre/pcrelib/pcredemo.c b/ext/pcre/pcrelib/pcredemo.c index 3a38ced9bf9..946aba45cdc 100644 --- a/ext/pcre/pcrelib/pcredemo.c +++ b/ext/pcre/pcrelib/pcredemo.c @@ -248,7 +248,7 @@ if (namecount <= 0) printf("No named substrings\n"); else * more than one byte. * * * * However, there is a complication concerned with newlines. When the * -* newline convention is such that CRLF is a valid newline, we want must * +* newline convention is such that CRLF is a valid newline, we must * * advance by two characters rather than one. The newline convention can * * be set in the regex by (*CR), etc.; if not, we must find the default. * *************************************************************************/ diff --git a/ext/pcre/pcrelib/pcreposix.c b/ext/pcre/pcrelib/pcreposix.c index ec2517c87ae..d45a15fc65e 100644 --- a/ext/pcre/pcrelib/pcreposix.c +++ b/ext/pcre/pcrelib/pcreposix.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-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -150,6 +150,16 @@ static const int eint[] = { REG_BADPAT, /* (*MARK) must have an argument */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */ REG_BADPAT, /* \c must be followed by an ASCII character */ + REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */ + /* 70 */ + REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */ + REG_BADPAT, /* \N is not supported in a class */ + REG_BADPAT, /* too many forward references */ + REG_BADPAT, /* disallowed UTF-8/16 code point (>= 0xd800 && <= 0xdfff) */ + REG_BADPAT, /* invalid UTF-16 string (should not occur) */ + /* 75 */ + REG_BADPAT, /* overlong MARK name */ + REG_BADPAT /* character value in \u.... sequence is too large */ }; /* Table of texts corresponding to POSIX error codes */ @@ -220,7 +230,7 @@ return length + addlength; PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION regfree(regex_t *preg) { -(pcre_free)(preg->re_pcre); +(PUBL(free))(preg->re_pcre); } @@ -265,11 +275,12 @@ should not happen, but we all make mistakes), return REG_BADPAT. */ if (preg->re_pcre == NULL) { - return (errorcode < sizeof(eint)/sizeof(const int))? + return (errorcode < (int)(sizeof(eint)/sizeof(const int)))? eint[errorcode] : REG_BADPAT; } -preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); +(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, + &(preg->re_nsub)); return 0; } @@ -395,6 +406,7 @@ switch(rc) case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; case PCRE_ERROR_BADUTF8: return REG_INVARG; case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; + case PCRE_ERROR_BADMODE: return REG_INVARG; default: return REG_ASSERT; } } diff --git a/ext/pcre/pcrelib/pcreposix.h b/ext/pcre/pcrelib/pcreposix.h index b90e2ec6dc7..c77c0b0523c 100644 --- a/ext/pcre/pcrelib/pcreposix.h +++ b/ext/pcre/pcrelib/pcreposix.h @@ -9,7 +9,7 @@ Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without diff --git a/ext/pcre/pcrelib/testdata/grepinput b/ext/pcre/pcrelib/testdata/grepinput index ed33f86d4a3..0f00edd93ca 100644 --- a/ext/pcre/pcrelib/testdata/grepinput +++ b/ext/pcre/pcrelib/testdata/grepinput @@ -602,6 +602,8 @@ ABOVE theatre AB.VE AB.VE the turtle +010203040506 + PUT NEW DATA ABOVE THIS LINE. ============================= diff --git a/ext/pcre/pcrelib/testdata/grepinput8 b/ext/pcre/pcrelib/testdata/grepinput8 index e8ddc273324..7163aa69d3e 100644 --- a/ext/pcre/pcrelib/testdata/grepinput8 +++ b/ext/pcre/pcrelib/testdata/grepinput8 @@ -1,6 +1,5 @@ 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 diff --git a/ext/pcre/pcrelib/testdata/grepoutput b/ext/pcre/pcrelib/testdata/grepoutput index a0392509c0a..e9072bcd61c 100644 --- a/ext/pcre/pcrelib/testdata/grepoutput +++ b/ext/pcre/pcrelib/testdata/grepoutput @@ -10,7 +10,7 @@ RC=0 7:PATTERN at the start of a line. 8:In the middle of a line, PATTERN appears. 10:This pattern is in lower case. -608:Check up on PATTERN near the end. +610:Check up on PATTERN near the end. RC=0 ---------------------------- Test 4 ------------------------------ 4 @@ -19,7 +19,7 @@ RC=0 ./testdata/grepinput:7:PATTERN at the start of a line. ./testdata/grepinput:8:In the middle of a line, PATTERN appears. ./testdata/grepinput:10:This pattern is in lower case. -./testdata/grepinput:608:Check up on PATTERN near the end. +./testdata/grepinput:610:Check up on PATTERN near the end. ./testdata/grepinputx:3:Here is the pattern again. ./testdata/grepinputx:5:Pattern ./testdata/grepinputx:42:This line contains pattern not on a line by itself. @@ -28,7 +28,7 @@ RC=0 7:PATTERN at the start of a line. 8:In the middle of a line, PATTERN appears. 10:This pattern is in lower case. -608:Check up on PATTERN near the end. +610:Check up on PATTERN near the end. 3:Here is the pattern again. 5:Pattern 42:This line contains pattern not on a line by itself. @@ -323,10 +323,10 @@ RC=0 ./testdata/grepinput-9- ./testdata/grepinput:10:This pattern is in lower case. -- -./testdata/grepinput-605-PUT NEW DATA ABOVE THIS LINE. -./testdata/grepinput-606-============================= -./testdata/grepinput-607- -./testdata/grepinput:608:Check up on PATTERN near the end. +./testdata/grepinput-607-PUT NEW DATA ABOVE THIS LINE. +./testdata/grepinput-608-============================= +./testdata/grepinput-609- +./testdata/grepinput:610:Check up on PATTERN near the end. -- ./testdata/grepinputx-1-This is a second file of input for the pcregrep tests. ./testdata/grepinputx-2- @@ -348,8 +348,8 @@ RC=0 ./testdata/grepinput-12-Here follows a whole lot of stuff that makes the file over 24K long. ./testdata/grepinput-13- -- -./testdata/grepinput:608:Check up on PATTERN near the end. -./testdata/grepinput-609-This is the last line of this file. +./testdata/grepinput:610:Check up on PATTERN near the end. +./testdata/grepinput-611-This is the last line of this file. -- ./testdata/grepinputx:3:Here is the pattern again. ./testdata/grepinputx-4- @@ -380,6 +380,7 @@ RC=0 ---------------------------- Test 37 ----------------------------- aaaaa0 aaaaa2 +010203040506 RC=0 ======== STDERR ======== pcregrep: pcre_exec() gave error -8 while matching this text: @@ -390,7 +391,7 @@ pcregrep: pcre_exec() gave error -8 while matching this text: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. ---------------------------- Test 38 ------------------------------ This line contains a binary zero here >< for testing. @@ -514,7 +515,7 @@ This is a file of miscellaneous text that is used as test data for checking that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 63 ----------------------------- @@ -524,7 +525,7 @@ This is a file of miscellaneous text that is used as test data for checking that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 64 ------------------------------ @@ -593,3 +594,77 @@ RC=0 triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt RC=0 +---------------------------- Test 71 ----------------------------- +01 +RC=0 +---------------------------- Test 72 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 73 ----------------------------- +01 +RC=0 +---------------------------- Test 74 ----------------------------- +01 +02 +RC=0 +---------------------------- Test 75 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 76 ----------------------------- +01 +02 +RC=0 +---------------------------- Test 77 ----------------------------- +01 +03 +RC=0 +---------------------------- Test 78 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 79 ----------------------------- +01 +03 +RC=0 +---------------------------- Test 80 ----------------------------- +01 +RC=0 +---------------------------- Test 81 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 82 ----------------------------- +01 +RC=0 +---------------------------- Test 83 ----------------------------- +pcregrep: line 4 of file ./testdata/grepinput3 is too long for the internal buffer +pcregrep: check the --buffer-size option +RC=2 +---------------------------- Test 84 ----------------------------- +testdata/grepinputv:fox jumps +testdata/grepinputx:complete pair +testdata/grepinputx:That was a complete pair +testdata/grepinputx:complete pair +RC=0 +---------------------------- Test 85 ----------------------------- +./testdata/grepinput3: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. +RC=0 +---------------------------- Test 86 ----------------------------- +Binary file ./testdata/grepbinary matches +RC=0 +---------------------------- Test 87 ----------------------------- +RC=1 +---------------------------- Test 88 ----------------------------- +Binary file ./testdata/grepbinary matches +RC=0 +---------------------------- Test 89 ----------------------------- +RC=1 +---------------------------- Test 90 ----------------------------- +RC=1 +---------------------------- Test 91 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 +---------------------------- Test 92 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 +---------------------------- Test 93 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 diff --git a/ext/pcre/pcrelib/testdata/grepoutput8 b/ext/pcre/pcrelib/testdata/grepoutput8 index 6317355cc6a..385266b3cf7 100644 --- a/ext/pcre/pcrelib/testdata/grepoutput8 +++ b/ext/pcre/pcrelib/testdata/grepoutput8 @@ -1,11 +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 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 170a4321ee3..6760314aa28 100644 --- a/ext/pcre/pcrelib/testdata/grepoutputN +++ b/ext/pcre/pcrelib/testdata/grepoutputN @@ -1,22 +1,16 @@ ---------------------------- Test N1 ------------------------------ -1:abc -2:def ----------------------------- Test N2 ------------------------------ -1:abc -def +1:abc 2:def ---------------------------- Test N2 ------------------------------ +1:abc def 2:ghi jkl---------------------------- Test N3 ------------------------------ -2:def -3: +2:def 3: ghi jkl---------------------------- Test N4 ------------------------------ 2:ghi jkl---------------------------- Test N5 ------------------------------ -1:abc -2:def +1:abc 2:def 3:ghi 4:jkl---------------------------- Test N6 ------------------------------ -1:abc -2:def +1:abc 2:def 3:ghi 4:jkl \ No newline at end of file diff --git a/ext/pcre/pcrelib/testdata/testinput1 b/ext/pcre/pcrelib/testdata/testinput1 index 97e5c366ef9..1ec7689a1ca 100644 --- a/ext/pcre/pcrelib/testdata/testinput1 +++ b/ext/pcre/pcrelib/testdata/testinput1 @@ -1,5 +1,6 @@ /-- This set of tests is for features that are compatible with all versions of - Perl 5, in non-UTF-8 mode. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and + 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox @@ -4079,4 +4080,1186 @@ /^\c/ ? +/(abc)\1/i + abc + +/(abc)\1/ + abc + +/[^a]*/i + 12abc + 12ABC + +/[^a]*+/i + 12abc + 12ABC + +/[^a]*?X/i + ** Failers + 12abc + 12ABC + +/[^a]+?X/i + ** Failers + 12abc + 12ABC + +/[^a]?X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]??X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]?+X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]{2,3}/i + abcdef + ABCDEF + +/[^a]{2,3}?/i + abcdef + ABCDEF + +/[^a]{2,3}+/i + abcdef + ABCDEF + +/((a|)+)+Z/ + Z + +/(a)b|(a)c/ + ac + +/(?>(a))b|(a)c/ + ac + +/(?=(a))ab|(a)c/ + ac + +/((?>(a))b|(a)c)/ + ac + +/((?>(a))b|(a)c)++/ + ac + +/(?:(?>(a))b|(a)c)++/ + ac + +/(?=(?>(a))b|(a)c)(..)/ + ac + +/(?>(?>(a))b|(a)c)/ + ac + +/(?:(?>([ab])))+a=/+ + =ba= + +/(?>([ab]))+a=/+ + =ba= + +/((?>(a+)b)+(aabab))/ + aaaabaaabaabab + +/(?>a+|ab)+?c/ + aabc + +/(?>a+|ab)+c/ + aabc + +/(?:a+|ab)+c/ + aabc + +/(?(?=(a))a)/ + a + +/(?(?=(a))a)(b)/ + ab + +/^(?:a|ab)++c/ + aaaabc + +/^(?>a|ab)++c/ + aaaabc + +/^(?:a|ab)+c/ + aaaabc + +/(?=abc){3}abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)+abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)++abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc){0}xyz/ + xyz + +/(?=abc){1}xyz/ + ** Failers + xyz + +/(?=(a))?./ + ab + bc + +/(?=(a))??./ + ab + bc + +/^(?=(a)){0}b(?1)/ + backgammon + +/^(?=(?1))?[az]([abc])d/ + abd + zcdxx + +/^(?!a){0}\w+/ + aaaaa + +/(?<=(abc))?xyz/ + abcxyz + pqrxyz + +/^[\g]+/ + ggg<<>> + ** Failers + \\ga + +/^[\ga]+/ + gggagagaxyz + +/^[:a[:digit:]]+/ + aaaa444:::Z + +/^[:a[:digit:]:b]+/ + aaaa444:::bbbZ + +/[:a]xxx[b:]/ + :xxx: + +/(?<=a{2})b/i + xaabc + ** Failers + xabc + +/(?XNNNYZ + > X NYQZ + ** Failers + >XYZ + > X NY Z + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/(foo)\Kbar/ + foobar + +/(foo)(\Kbar|baz)/ + foobar + foobaz + +/(foo\Kbar)baz/ + foobarbaz + +/abc\K|def\K/g+ + Xabcdefghi + +/ab\Kc|de\Kf/g+ + Xabcdefghi + +/(?=C)/g+ + ABCDECBA + +/^abc\K/+ + abcdef + ** Failers + defabcxyz + +/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ + ababababbbabZXXXX + +/(?tom|bon)-\g{A}/ + tom-tom + bon-bon + +/(^(a|b\g{-1}))/ + bacxxx + +/(?|(abc)|(xyz))\1/ + abcabc + xyzxyz + ** Failers + abcxyz + xyzabc + +/(?|(abc)|(xyz))(?1)/ + abcabc + xyzabc + ** Failers + xyzxyz + +/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ + XYabcdY + +/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ + XYabcdY + +/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ + XYabcdY + +/(?'abc'\w+):\k{2}/ + a:aaxyz + ab:ababxyz + ** Failers + a:axyz + ab:abxyz + +/(?'abc'\w+):\g{abc}{2}/ + a:aaxyz + ab:ababxyz + ** Failers + a:axyz + ab:abxyz + +/^(?a)? (?()b|c) (?('ab')d|e)/x + abd + ce + +/^(a.)\g-1Z/ + aXaXZ + +/^(a.)\g{-1}Z/ + aXaXZ + +/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x + abcd + +/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) + (?(DEFINE) + (?[a-z]+) + (?\d+) + )/x + metcalfe 33 + +/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ + 1.2.3.4 + 131.111.10.206 + 10.0.0.0 + ** Failers + 10.6 + 455.3.4.5 + +/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ + 1.2.3.4 + 131.111.10.206 + 10.0.0.0 + ** Failers + 10.6 + 455.3.4.5 + +/^(\w++|\s++)*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d++)(\w)/ + 12345a + *** Failers + 12345+ + +/a++b/ + aaab + +/(a++b)/ + aaab + +/(a++)b/ + aaab + +/([^()]++|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(([^()]++|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/^([^()]|\((?1)*\))*$/ + abc + a(b)c + a(b(c))d + *** Failers) + a(b(c)d + +/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x + <> + + hij> + hij> + def> + + *** Failers + a)(?<=b(?&X))/ + baz + +/^(?|(abc)|(def))\1/ + abcabc + defdef + ** Failers + abcdef + defabc + +/^(?|(abc)|(def))(?1)/ + abcabc + defabc + ** Failers + defdef + abcdef + +/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ + a\"aaaaa + b\"aaaaa + ** Failers + b\"11111 + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + CCD + ** Failers + CAD + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + BCD + ** Failers + ABCD + CAD + BAD + +/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ + AAD + ACD + BAD + BCD + BAX + ** Failers + ACX + ABC + +/(?(DEFINE)(A))B(?1)C/ + BAC + +/(?(DEFINE)((A)\2))B(?1)C/ + BAAC + +/(? \( ( [^()]++ | (?&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 + ac + +/^(?=a(*ACCEPT)b)/ + ac + +/^(?(?!a(*SKIP)b))/ + ac + +/(?>a\Kb)/ + ab + +/((?>a\Kb))/ + ab + +/(a\Kb)/ + ab + +/^a\Kcz|ac/ + ac + +/(?>a\Kbz|ab)/ + ab + +/^(?&t)(?(DEFINE)(?a\Kb))$/ + ab + +/^([^()]|\((?1)*\))*$/ + a(b)c + a(b(c)d)e + +/(?P(?P0)(?P>L1)|(?P>L2))/ + 0 + 00 + 0000 + +/(?P(?P0)|(?P>L2)(?P>L1))/ + 0 + 00 + 0000 + +/--- This one does fail, as expected, in Perl. It needs the complex item at the + end of the pattern. A single letter instead of (B|D) makes it not fail, + which I think is a Perl bug. --- / + +/A(*COMMIT)(B|D)/ + ACABX + +/--- Check the use of names for failure ---/ + +/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K + ** Failers + AC + CB + +/--- Force no study, otherwise mark is not seen. The studied version is in + test 2 because it isn't Perl-compatible. ---/ + +/(*MARK:A)(*SKIP:B)(C|X)/KSS + C + D + +/^(A(*THEN:A)B|C(*THEN:B)D)/K + ** Failers + CB + +/^(?:A(*THEN:A)B|C(*THEN:B)D)/K + CB + +/^(?>A(*THEN:A)B|C(*THEN:B)D)/K + CB + +/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note +that we have to have something complicated such as (B|Z) at the end because, +for Perl, a simple character somehow causes an unwanted optimization to mess +with the handling of backtracking verbs. ---/ + +/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Test skipping over a non-matching mark. ---/ + +/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Check shorthand for MARK ---/ + +/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Don't loop! Force no study, otherwise mark is not seen. ---/ + +/(*:A)A+(*SKIP:A)(B|Z)/KSS + AAAC + +/--- This should succeed, as a non-existent skip name disables the skip ---/ + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK + AAAC + +/--- COMMIT at the start of a pattern should act like an anchor. Again, +however, we need the complication for Perl. ---/ + +/(*COMMIT)(A|P)(B|P)(C|P)/ + ABCDEFG + ** Failers + DEFGABC + +/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ + +/(\w+)(?>b(*COMMIT))\w{2}/ + abbb + +/(\w+)b(*COMMIT)\w{2}/ + abbb + +/--- Check opening parens in comment when seeking forward reference. ---/ + +/(?&t)(?#()(?(DEFINE)(?a))/ + bac + +/--- COMMIT should override THEN ---/ + +/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ + yes + +/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ + yes + +/b?(*SKIP)c/ + bc + abc + +/(*SKIP)bc/ + a + +/(*SKIP)b/ + a + +/(?P(?P=abn)xxx|)+/ + xxx + +/(?i:([^b]))(?1)/ + aa + aA + ** Failers + ab + aB + Ba + ba + +/^(?&t)*+(?(DEFINE)(?a))\w$/ + aaaaaaX + ** Failers + aaaaaa + +/^(?&t)*(?(DEFINE)(?a))\w$/ + aaaaaaX + aaaaaa + +/^(a)*+(\w)/ + aaaaX + YZ + ** Failers + aaaa + +/^(?:a)*+(\w)/ + aaaaX + YZ + ** Failers + aaaa + +/^(a)++(\w)/ + aaaaX + ** Failers + aaaa + YZ + +/^(?:a)++(\w)/ + aaaaX + ** Failers + aaaa + YZ + +/^(a)?+(\w)/ + aaaaX + YZ + +/^(?:a)?+(\w)/ + aaaaX + YZ + +/^(a){2,}+(\w)/ + aaaaX + ** Failers + aaa + YZ + +/^(?:a){2,}+(\w)/ + aaaaX + ** Failers + aaa + YZ + +/(a|)*(?1)b/ + b + ab + aab + +/(a)++(?1)b/ + ** Failers + ab + aab + +/(a)*+(?1)b/ + ** Failers + ab + aab + +/(?1)(?:(b)){0}/ + b + +/(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x + foo(bar(baz)+baz(bop)) + +/(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 + +/(?:(b))++/ + beetle + +/(?(?=(a(*ACCEPT)z))a)/ + a + +/^(a)(?1)+ab/ + aaaab + +/^(a)(?1)++ab/ + aaaab + +/^(?=a(*:M))aZ/K + aZbc + +/^(?!(*:M)b)aZ/K + aZbc + +/(?(DEFINE)(a))?b(?1)/ + backgammon + +/^\N+/ + abc\ndef + +/^\N{1,}/ + abc\ndef + +/(?(R)a+|(?R)b)/ + aaaabcde + +/(?(R)a+|((?R))b)/ + aaaabcde + +/((?(R)a+|(?1)b))/ + aaaabcde + +/((?(R1)a+|(?1)b))/ + aaaabcde + +/a(*:any +name)/K + abc + +/(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ + a + ba + bba + +/--- Checking revised (*THEN) handling ---/ + +/--- Capture ---/ + +/^.*? (a(*THEN)b) c/x + aabc + +/^.*? (a(*THEN)b|(*F)) c/x + aabc + +/^.*? ( (a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? ( (a(*THEN)b) ) c/x + aabc + +/--- Non-capture ---/ + +/^.*? (?:a(*THEN)b) c/x + aabc + +/^.*? (?:a(*THEN)b|(*F)) c/x + aabc + +/^.*? (?: (?:a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? (?: (?:a(*THEN)b) ) c/x + aabc + +/--- Atomic ---/ + +/^.*? (?>a(*THEN)b) c/x + aabc + +/^.*? (?>a(*THEN)b|(*F)) c/x + aabc + +/^.*? (?> (?>a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? (?> (?>a(*THEN)b) ) c/x + aabc + +/--- Possessive capture ---/ + +/^.*? (a(*THEN)b)++ c/x + aabc + +/^.*? (a(*THEN)b|(*F))++ c/x + aabc + +/^.*? ( (a(*THEN)b)++ | (*F) )++ c/x + aabc + +/^.*? ( (a(*THEN)b)++ )++ c/x + aabc + +/--- Possessive non-capture ---/ + +/^.*? (?:a(*THEN)b)++ c/x + aabc + +/^.*? (?:a(*THEN)b|(*F))++ c/x + aabc + +/^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x + aabc + +/^.*? (?: (?:a(*THEN)b)++ )++ c/x + aabc + +/--- Condition assertion ---/ + +/^(?(?=a(*THEN)b)ab|ac)/ + ac + +/--- Condition ---/ + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba + +/^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ + ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac + +/--- Assertion ---/ + +/^.*(?=a(*THEN)b)/ + aabc + +/------------------------------/ + +/(?>a(*:m))/imsxSK + a + +/(?>(a)(*:m))/imsxSK + a + +/(?<=a(*ACCEPT)b)c/ + xacd + +/(?<=(a(*ACCEPT)b))c/ + xacd + +/(?<=(a(*COMMIT)b))c/ + xabcd + ** Failers + xacd + +/(?a?)*)*c/ + aac + /-- End of testinput1 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput10 b/ext/pcre/pcrelib/testdata/testinput10 index 7210cc5f8ef..7856518e1a6 100644 --- a/ext/pcre/pcrelib/testdata/testinput10 +++ b/ext/pcre/pcrelib/testdata/testinput10 @@ -1,137 +1,1029 @@ -/-- 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. --/ +/-- This set of tests check Unicode property support with the DFA matching + functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest + when running it. --/ -/((?i)b)/BM +/\pL\P{Nd}/8 + AB + *** Failers + A0 + 00 -/(?s)(.*X|^B)/BM +/\X./8 + AB + A\x{300}BC + A\x{300}\x{301}\x{302}BC + *** Failers + \x{300} -/(?s:.*X|^B)/BM +/\X\X/8 + ABC + A\x{300}B\x{300}\x{301}C + A\x{300}\x{301}\x{302}BC + *** Failers + \x{300} -/^[[:alnum:]]/BM +/^\pL+/8 + abcd + a + *** Failers -/#/IxMD +/^\PL+/8 + 1234 + = + *** Failers + abcd -/a#/IxMD +/^\X+/8 + abcdA\x{300}\x{301}\x{302} + A\x{300}\x{301}\x{302} + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} + a + *** Failers + \x{300}\x{301}\x{302} -/x?+/BM +/\X?abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc + *** Failers -/x++/BM +/^\X?abc/8 + abc + A\x{300}abc + *** Failers + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc -/x{1,3}+/BM +/\X*abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc + *** Failers -/(x)*+/BM +/^\X*abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + *** Failers + \x{300}abc -/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM +/^\pL?=./8 + A=b + =c + *** Failers + 1=2 + AAAA=b -|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\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 +/^\pL*=./8 + AAAA=b + =c + *** Failers + 1=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\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{2,3}X/8 + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + *** Failers + X + A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X -/(a(?1)b)/BM - -/(a(?1)+b)/BM - -/a(?Pb|c)d(?Pe)/BM - -/(?:a(?Pc(?Pd)))(?Pa)/BM - -/(?Pa)...(?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{1000000}/8BM - -/\x{4000000}/8BM - -/\x{7fffFFFF}/8BM - -/[\x{ff}]/8BM - -/[\x{100}]/8BM - -/\x80/8BM - -/\xff/8BM - -/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +/^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + ** Failers + \x{0b} + +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}*/8 + > \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} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xsp}]+/8 + > \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} + >\x{a0} + ** Failers + \x{0b} + +/^>\p{Xps}+/8 + > \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} + +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^\p{Xwd}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_12\x{6ca}\x{a6c}\x{10a7} + +/^[\p{Xwd}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Caseless single negated characters > 127 need UCP support --/ + +/[^\x{100}]/8i + \x{100}\x{101}X + +/[^\x{100}]+/8i + \x{100}\x{101}XX + +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P + +/-- End of testinput10 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput2 b/ext/pcre/pcrelib/testdata/testinput2 index 7cc87616500..883d52e63b9 100644 --- a/ext/pcre/pcrelib/testdata/testinput2 +++ b/ext/pcre/pcrelib/testdata/testinput2 @@ -3,12 +3,11 @@ It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl - bug. --/ + bug. + + 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. --/ -/-- Originally, the Perl >= 5.10 things were in here too, but now I have - separated many (most?) of them out into test 11. However, there may still - be some that were overlooked. --/ - /(a)b|/I /abc/I @@ -144,40 +143,6 @@ defabc \Zdefabc -/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/ @@ -442,8 +407,6 @@ /abc/\ -/abc/\P - /abc/\i /(a)bc(d)/I @@ -491,9 +454,6 @@ /\Biss\B/I+ Mississippi -/\Biss\B/I+P - Mississippi - /iss/IG+ Mississippi @@ -629,15 +589,6 @@ *** Failers \Nabc -/a*(b+)(z)(z)/P - aaaabbbbzzzz - aaaabbbbzzzz\O0 - aaaabbbbzzzz\O1 - aaaabbbbzzzz\O2 - aaaabbbbzzzz\O3 - aaaabbbbzzzz\O4 - aaaabbbbzzzz\O5 - /^.?abcd/IS /\( # ( at start @@ -1061,7 +1012,12 @@ /abc(?C)de(?C1)f/I 123abcdef -/(?C1)\dabc(?C2)def/I +/(?C1)\dabc(?C2)def/IS + 1234abcdef + *** Failers + abcdef + +/(?C1)\dabc(?C2)def/ISS 1234abcdef *** Failers abcdef @@ -1310,7 +1266,12 @@ abcde abcdfe -/a*b/ICDZ +/a*b/ICDZS + ab + aaaab + aaaacb + +/a*b/ICDZSS ab aaaab aaaacb @@ -1320,9 +1281,16 @@ aaaab aaaacb -/(abc|def)x/ICDZ +/(abc|def)x/ICDZS abcx defx + ** Failers + abcdefzx + +/(abc|def)x/ICDZSS + abcx + defx + ** Failers abcdefzx /(ab|cd){3,4}/IC @@ -1330,7 +1298,10 @@ abcdabcd abcdcdcdcdcd -/([ab]{,4}c|xy)/ICDZ +/([ab]{,4}c|xy)/ICDZS + Note: that { does NOT introduce a quantifier + +/([ab]{,4}c|xy)/ICDZSS Note: that { does NOT introduce a quantifier /([ab]{1,4}c|xy){4,5}?123/ICDZ @@ -1404,13 +1375,25 @@ 1X 123456\P -/abc/I>testsavedregex +/abc/IS>testsavedregex testsavedregex +/abc/ISS>testsavedregex +testsavedregex +testsavedregex testsavedregex +testsavedregex testsavedregex +(.)*~smgI - \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n /^a/IF @@ -1447,17 +1442,6 @@ ** Failers line one\nthis is a line\nbreak in the second line -/ab.cd/P - ab-cd - ab=cd - ** Failers - ab\ncd - -/ab.cd/Ps - ab-cd - ab=cd - ab\ncd - /(?i)(?-i)AbCd/I AbCd ** Failers @@ -1508,14 +1492,6 @@ (this) ((this)) -/a(b)c/PN - abc - -/a(?Pb)c/PN - abc - -/\x{100}/I - /\x{0000ff}/I /^((?Pa1)|(?Pa2)b)/I @@ -1593,8 +1569,6 @@ a random value. /Ix /()()()()()()()()()(?:(?(A)(?P=A)a|b)(?PX|Y))+/I bXXaYYaY -/\777/I - /\s*,\s*/IS \x0b,\x0b \x0c,\x0d @@ -1976,8 +1950,6 @@ a random value. /Ix /(?(DEFINE) abc) xyz/xI -/(?(DEFINE) abc){3} xyz/x - /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 @@ -2199,22 +2171,6 @@ a random value. /Ix xabcpqrx xxyzx -/[\h]/BZ - >\x09< - -/[\h]+/BZ - >\x09\x20\xa0< - -/[\v]/BZ - -/[\H]/BZ - -/[^\h]/BZ - -/[\V]/BZ - -/[\x0a\V]/BZ - /\H++X/BZ ** Failers XXXX @@ -2255,7 +2211,7 @@ a random value. /Ix /\V+\v\V+\w/BZ /\( (?: [^()]* | (?R) )* \)/x -(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) +\J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ @@ -2295,7 +2251,7 @@ a random value. /Ix /\g6666666666/ -/[\g6666666666]/ +/[\g6666666666]/BZ /(?1)\c[/ @@ -2453,6 +2409,10 @@ a random value. /Ix /\k{}/ +/\k/ + +/\kabc/ + /(?P=)/ /(?P>)/ @@ -2570,11 +2530,6 @@ a random value. /Ix /(?(?=.*b).*b|^d)/I -/a?|b?/P - abc - ** Failers - ddd\N - /xyz/C xyz abcxyz @@ -2766,12 +2721,6 @@ a random value. /Ix abc\P abc\P\P -/\w+A/P - CDAAAAB - -/\w+A/PU - CDAAAAB - /abc\K123/ xyzabc123pqr xyzabc12\P @@ -2915,201 +2864,6 @@ a random value. /Ix /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI -/ (?: [\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 - /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS "(?>.*/)foo"SI @@ -3276,104 +3030,19 @@ a random value. /Ix /A(*PRUNE)B|A(*PRUNE)C/K AC -/--- A whole lot of tests of verbs with arguments are here rather than in test - 11 because Perl doesn't seem to follow its specification entirely - correctly. ---/ - -/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is - not clear how Perl defines "involved in the failure of the match". ---/ - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - AB - CD - ** Failers - AC - CB - -/--- Check the use of names for success and failure. PCRE doesn't show these -names for success, though Perl does, contrary to its spec. ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - AB - CD - ** Failers - AC - CB - -/--- An empty name does not pass back an empty string. It is the same as if no -name were given. ---/ - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K - AB - CD - -/--- PRUNE goes to next bumpalong; COMMIT does not. ---/ - -/A(*PRUNE:A)B/K - ACAB - -/(*MARK:A)(*PRUNE:B)(C|X)/K - C - D - -/(*MARK:A)(*THEN:B)(C|X)/K - C - D - -/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/ - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK - AAAC - -/--- Same --/ - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK - AAAC - /--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. ---/ + PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC -/A(*:A)A+(*SKIP)(B|Z) | AC/xK - AAAC +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ -/--- This should fail, as a null name is the same as no name ---/ - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK - AAAC - -/--- This fails in PCRE, and I think that is in accordance with Perl's - documentation, though in Perl it succeeds. ---/ - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK - AAAC - -/--- Mark names can be duplicated ---/ - -/A(*:A)B|X(*:A)Y/K - AABC - XXYZ - /^A(*:A)B|^X(*:A)Y/K ** Failers XAQQ -/--- A check on what happens after hitting a mark and them bumping along to -something that does not even start. Perl reports tags after the failures here, -though it does not when the individual letters are made into something -more complicated. ---/ - -/A(*:A)B|XX(*:B)Y/K - AABC - XXYZ - ** Failers - XAQQ - XAQQXZZ - AXQQQ - AXXQQQ - /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ @@ -3383,78 +3052,6 @@ with \Y. ---/ ** Failers DEFGABC\Y -/--- Repeat some tests with added studying. ---/ - -/A(*COMMIT)B/+KS - ACABX - -/A(*THEN)B|A(*THEN)C/KS - AC - -/A(*PRUNE)B|A(*PRUNE)C/KS - AC - -/^(A(*THEN:A)B|C(*THEN:B)D)/KS - AB - CD - ** Failers - AC - CB - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS - AB - CD - ** Failers - AC - CB - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS - AB - CD - -/A(*PRUNE:A)B/KS - ACAB - -/(*MARK:A)(*PRUNE:B)(C|X)/KS - C - D - -/(*MARK:A)(*THEN:B)(C|X)/KS - C - D - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS - AAAC - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS - AAAC - -/A(*:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS - AAAC - -/A(*:A)B|XX(*:B)Y/KS - AABC - XXYZ - ** Failers - XAQQ - XAQQXZZ - AXQQQ - AXXQQQ - -/(*COMMIT)ABC/ - ABCDEFG - ** Failers - DEFGABC\Y - /^(ab (c+(*THEN)cd) | xyz)/x abcccd @@ -3505,6 +3102,24 @@ with \Y. ---/ /\d*\R/BZ /\s*\R/BZ + \x20\x0a + \x20\x0d + \x20\x0d\x0a + +/\S*\R/BZ + a\x0a + +/X\h*\R/BZ + X\x20\x0a + +/X\H*\R/BZ + X\x0d\x0a + +/X\H+\R/BZ + X\x0d\x0a + +/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. --/ @@ -3570,4 +3185,588 @@ with \Y. ---/ /(?P(?P=axn)xxx)(?yy)/BZ +/-- These tests are here because Perl gets the first one wrong. --/ + +/(\R*)(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/(\R)*(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/-- --/ + +/^abc$/BZ + +/^abc$/BZm + +/^(a)*+(\w)/S + aaaaX + ** Failers + aaaa + +/^(?:a)*+(\w)/S + aaaaX + ** Failers + aaaa + +/(a)++1234/SDZ + +/([abc])++1234/SI + +/(?<=(abc)+)X/ + +/(^ab)/I + +/(^ab)++/I + +/(^ab|^)+/I + +/(^ab|^)++/I + +/(?:^ab)/I + +/(?:^ab)++/I + +/(?:^ab|^)+/I + +/(?:^ab|^)++/I + +/(.*ab)/I + +/(.*ab)++/I + +/(.*ab|.*)+/I + +/(.*ab|.*)++/I + +/(?:.*ab)/I + +/(?:.*ab)++/I + +/(?:.*ab|.*)+/I + +/(?:.*ab|.*)++/I + +/(?=a)[bcd]/I + +/((?=a))[bcd]/I + +/((?=a))+[bcd]/I + +/((?=a))++[bcd]/I + +/(?=a+)[bcd]/iI + +/(?=a+?)[bcd]/iI + +/(?=a++)[bcd]/iI + +/(?=a{3})[bcd]/iI + +/(abc)\1+/S + +/-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ + +/(?1)(?:(b(*ACCEPT))){0}/ + b + +/(?1)(?:(b(*ACCEPT))){0}c/ + bc + ** Failers + b + +/(?1)(?:((*ACCEPT))){0}c/ + c + c\N + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba + +/^.*?(?(?=a)a|bc)/ + ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac + +/^.*?(?(?=a)a(*THEN)b)c/ + ac + +/^.*?(a(*THEN)b)c/ + aabc + +/^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x + aabc + +/^.*?(a(*THEN)b|z)c/ + aabc + +/^.*?(z|a(*THEN)b)c/ + aabc + +/-- --/ + +/-- These studied versions are here because they are not Perl-compatible; the + studying means the mark is not seen. --/ + +/(*MARK:A)(*SKIP:B)(C|X)/KS + C + D + +/(*:A)A+(*SKIP:A)(B|Z)/KS + AAAC + +/-- --/ + +"(?=a*(*ACCEPT)b)c" + c + c\N + +/(?1)c(?(DEFINE)((*ACCEPT)b))/ + c + c\N + +/(?>(*ACCEPT)b)c/ + c + c\N + +/(?:(?>(a)))+a%/++ + %aa% + +/(a)b|ac/++SS + ac\O3 + +/(a)(b)x|abc/++ + abc\O6 + +/(a)bc|(a)(b)\2/ + \O3abc + \O4abc + +/(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI + +/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI + +/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI + +/(abc)(?1)/SI + +/^(?>a)++/ + aa\M + aaaaaaaaa\M + +/(a)(?1)++/ + aa\M + aaaaaaaaa\M + +/(?:(foo)|(bar)|(baz))X/SS= + bazfooX + foobazbarX + barfooX + bazX + foobarbazX + bazfooX\O0 + bazfooX\O2 + bazfooX\O4 + bazfooX\O6 + bazfooX\O8 + bazfooX\O10 + +/(?=abc){3}abc/BZ + +/(?=abc)+abc/BZ + +/(?=abc)++abc/BZ + +/(?=abc){0}xyz/BZ + +/(?=(a))?./BZ + +/(?=(a))??./BZ + +/^(?=(a)){0}b(?1)/BZ + +/(?(DEFINE)(a))?b(?1)/BZ + +/^(?=(?1))?[az]([abc])d/BZ + +/^(?!a){0}\w+/BZ + +/(?<=(abc))?xyz/BZ + +/[:a[:abc]b:]/BZ + +/((?2))((?1))/SS + abc + +/((?(R2)a+|(?1)b))/SS + aaaabcde + +/(?(R)a*(?1)|((?R))b)/SS + aaaabcde + +/(a+|(?R)b)/ + +/^(a(*:A)(d|e(*:B))z|aeq)/C + adz + aez + aeqwerty + +/.(*F)/ + \P\Pabc + +/\btype\b\W*?\btext\b\W*?\bjavascript\b/IS + +/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ + aaaazzzzb + ** Failers + aazz + +/(.)(\1|a(?2))/ + bab + +/\1|(.)(?R)\1/ + cbbbc + +/(.)((?(1)c|a)|a(?2))/ + baa + +/(?P(?P=abn)xxx)/BZ + +/(a\1z)/BZ + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + \Maabbccddee + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + \Maabbccddee + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + \Maabbccddee + +/^a\x41z/ + aAz + *** Failers + ax41z + +/^a[m\x41]z/ + aAz + +/^a\x1z/ + ax1z + +/^a\u0041z/ + aAz + *** Failers + au0041z + +/^a[m\u0041]z/ + aAz + +/^a\u041z/ + au041z + *** Failers + aAz + +/^a\U0041z/ + aU0041z + *** Failers + aAz + +/(?(?=c)c|d)++Y/BZ + +/(?(?=c)c|d)*+Y/BZ + +/a[\NB]c/ + aNc + +/a[B-\Nc]/ + +/(a)(?2){0,1999}?(b)/ + +/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ + +/--- This test, with something more complicated than individual letters, causes +different behaviour in Perl. Perhaps it disables some optimization; no tag is +passed back for the failures, whereas in PCRE there is a tag. ---/ + +/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK + AABC + XXYZ + ** Failers + XAQQ + XAQQXZZ + AXQQQ + AXXQQQ + +/-- Perl doesn't give marks for these, though it does if the alternatives are +replaced by single letters. --/ + +/(b|q)(*:m)f|a(*:n)w/K + aw + ** Failers + abc + +/(q|b)(*:m)f|a(*:n)w/K + aw + ** Failers + abc + +/-- After a partial match, the behaviour is as for a failure. --/ + +/^a(*:X)bcde/K + abc\P + +/-- These are here because Perl doesn't return a mark, except for the first --/ + +/(?=(*:x))(q|)/K+ + abc + +/(?=(*:x))((*:y)q|)/K+ + abc + +/(?=(*:x))(?:(*:y)q|)/K+ + abc + +/(?=(*:x))(?>(*:y)q|)/K+ + abc + +/(?=a(*:x))(?!a(*:y)c)/K+ + ab + +/(?=a(*:x))(?=a(*:y)c|)/K+ + ab + +/(..)\1/ + ab\P + aba\P + abab\P + +/(..)\1/i + ab\P + abA\P + aBAb\P + +/(..)\1{2,}/ + ab\P + aba\P + abab\P + ababa\P + ababab\P + ababab\P\P + abababa\P + abababa\P\P + +/(..)\1{2,}/i + ab\P + aBa\P + aBAb\P + AbaBA\P + abABAb\P + aBAbaB\P\P + abABabA\P + abaBABa\P\P + +/(..)\1{2,}?x/i + ab\P + abA\P + aBAb\P + abaBA\P + abAbaB\P + abaBabA\P + abAbABaBx\P + +/^(..)\1/ + aba\P + +/^(..)\1{2,3}x/ + aba\P + ababa\P + ababa\P\P + abababx + ababababx + +/^(..)\1{2,3}?x/ + aba\P + ababa\P + ababa\P\P + abababx + ababababx + +/^(..)(\1{2,3})ab/ + abababab + +/^\R/ + \r\P + \r\P\P + +/^\R{2,3}x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R{2,3}?x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R?x/ + \r\P + \r\P\P + x + \rx + +/^\R+x/ + \r\P + \r\P\P + \r\n\P + \r\n\P\P + \rx + +/^a$/ + a\r\P + a\r\P\P + +/^a$/m + a\r\P + a\r\P\P + +/^(a$|a\r)/ + a\r\P + a\r\P\P + +/^(a$|a\r)/m + a\r\P + a\r\P\P + +/./ + \r\P + \r\P\P + +/.{2,3}/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \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 + /-- End of testinput2 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput4 b/ext/pcre/pcrelib/testdata/testinput4 index e2bae423b88..c7bb370cfdf 100644 --- a/ext/pcre/pcrelib/testdata/testinput4 +++ b/ext/pcre/pcrelib/testdata/testinput4 @@ -1,5 +1,6 @@ -/-- This set of tests if for UTF-8 support, excluding Unicode properties. It is - compatible with all versions of Perl 5. --/ +/-- 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. --/ /a.b/8 acb @@ -126,31 +127,6 @@ *** Failers XYZ -/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]+/8g bcd \x{100}aY\x{256}Z @@ -456,17 +432,6 @@ \x{150}X \x{200}X -/a\Cb/ - aXb - a\nb - -/a\Cb/8 - aXb - a\nb - -/a\C\Cb/8 - a\x{100}b - /[z-\x{100}]/8i z Z @@ -644,4 +609,16 @@ /A*/g8 AAB\x{123}BAA +/(abc)\1/8i + abc + +/(abc)\1/8 + abc + +/a(*:a\x{1234}b)/8K + abc + +/a(*:a£b)/8K + abc + /-- End of testinput4 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput5 b/ext/pcre/pcrelib/testdata/testinput5 index 5e200b3e319..642749c315c 100644 --- a/ext/pcre/pcrelib/testdata/testinput5 +++ b/ext/pcre/pcrelib/testdata/testinput5 @@ -1,72 +1,36 @@ -/-- This set of tests checks the API, internals, and non-Perl stuff for UTF-8 - support, excluding Unicode properties. --/ +/-- 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). --/ -/\x{100}/8DZ - -/\x{1000}/8DZ - -/\x{10000}/8DZ - -/\x{100000}/8DZ - -/\x{1000000}/8DZ - -/\x{4000000}/8DZ - -/\x{7fffFFFF}/8DZ - -/[\x{ff}]/8DZ - -/[\x{100}]/8DZ +/\x{110000}/8DZ /\x{ffffffff}/8 /\x{100000000}/8 +/\x{d800}/8 + +/\x{dfff}/8 + +/\x{d7ff}/8 + +/\x{e000}/8 + /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd -/\x80/8DZ - -/\xff/8DZ - /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 \x{0041}\x{2262}\x{0391}\x{002e} -/\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 - /.{3,5}X/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861}X - /.{3,5}?/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861} /(?<=\C)X/8 Should produce an error diagnostic -/-- 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 - /^[ab]/8DZ bar *** Failers @@ -81,26 +45,6 @@ can't tell the difference.) --/ *** Failers aaa -/[^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}*(\d+|"(?1)")/8 1234 "1234" @@ -111,33 +55,17 @@ can't tell the difference.) --/ *** Failers \x{100}\x{100}abcd -/\x{100}/8DZ - /\x{100}*/8DZ /a\x{100}*/8DZ /ab\x{100}*/8DZ -/a\x{100}\x{101}*/8DZ - -/a\x{100}\x{101}+/8DZ - /\x{100}*A/8DZ A /\x{100}*\d(?R)/8DZ -/[^\x{c4}]/DZ - -/[^\x{c4}]/8DZ - -/[\x{100}]/8DZ - \x{100} - Z\x{100} - \x{100}Z - *** Failers - /[Z\x{100}]/8DZ Z\x{100} \x{100} @@ -162,13 +90,8 @@ can't tell the difference.) --/ /[\xFF]/DZ >\xff< -/[\xff]/DZ8 - >\x{ff}< - /[^\xFF]/DZ -/[^\xff]/8DZ - /[Ä-Ãœ]/8 Ö # Matches without Study \x{d6} @@ -185,45 +108,6 @@ can't tell the difference.) --/ Ö <-- Same with Study \x{d6} -/[Ã]/8 - -/Ã/8 - -/ÃÃÃxxx/8 - -/ÃÃÃxxx/8?DZ - -/abc/8 - Ã] - à - ÃÃà - ÃÃÃ\? - -/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}abc(xyz(?1))/8DZ - /[^\x{100}]abc(xyz(?1))/8DZ /[ab\x{100}]abc(xyz(?1))/8DZ @@ -243,17 +127,8 @@ can't tell the difference.) --/ /\w/8 \x{100}X -/a\x{1234}b/P8 - a\x{1234}b - /^\ሴ/8DZ -/\777/I - -/\777/8I - \x{1ff} - \777 - /\x{100}*\d/8DZ /\x{100}*\s/8DZ @@ -266,12 +141,6 @@ can't tell the difference.) --/ /\x{100}*\W/8DZ -/\x{100}+\x{200}/8DZ - -/\x{100}+X/8DZ - -/X+\x{200}/8DZ - /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() @@ -283,8 +152,6 @@ can't tell the difference.) --/ /^[\QÄ€\E-\QÅ\E]/BZ8 -/^[\QÄ€\E-\QÅ\E/BZ8 - /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK @@ -379,23 +246,6 @@ can't tell the difference.) --/ /.*$/8 \x{1ec5} -/-- This tests the stricter UTF-8 check according to RFC 3629. --/ - -/X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} - \x{d800} - \x{d800}\? - \x{da00} - \x{da00}\? - \x{dfff} - \x{dfff}\? - \x{110000} - \x{110000}\? - \x{2000000} - \x{2000000}\? - \x{7fffffff} - \x{7fffffff}\? - /a\Rb/I8 a\rb a\nb @@ -454,16 +304,10 @@ can't tell the difference.) --/ /(\x{de})\1/ \x{de}\x{de} - \x{123} /X/8f A\x{1ec5}ABCXYZ -/(*UTF8)\x{1234}/ - abcd\x{1234}pqr - -/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I - /Xa{2,4}b/8 X\P Xa\P @@ -745,53 +589,184 @@ can't tell the difference.) --/ /X\W{3}X/8 \PX -/\h/SI - -/\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/SI - -/\v/SI8 - ABC\x{0a} - ABC\x{0b} - ABC\x{0c} - ABC\x{0d} - ABC\x{85} - ABC\x{2028} - -/\R/SI - -/\R/SI8 - -/\h*A/SI8 - CDBABC - -/\v+A/SI8 - -/\s?xxx\s/8SI - /\sxxx\s/8T1 AB\x{85}xxx\x{a0}XYZ AB\x{a0}xxx\x{85}XYZ -/\sxxx\s/I8ST1 - AB\x{85}xxx\x{a0}XYZ - AB\x{a0}xxx\x{85}XYZ - /\S \S/8T1 \x{a2} \x{84} -/\S \S/I8ST1 - \x{a2} \x{84} - A Z +'A#хц'8xBZ + +'A#хц + PQ'8xBZ + +/a+#Ñ…aa + z#XX?/8xBZ + +/a+#Ñ…aa + z#Ñ…?/8xBZ + +/\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ + +/\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ + +/^\cÄ£/8 + +/(\R*)(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/(\R)*(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/[^\x{1234}]+/iS8I + +/[^\x{1234}]+?/iS8I + +/[^\x{1234}]++/iS8I + +/[^\x{1234}]{2}/iS8I + +// + +/f.*/ + \P\Pfor + +/f.*/s + \P\Pfor + +/f.*/8 + \P\Pfor + +/f.*/8s + \P\Pfor + +/\x{d7ff}\x{e000}/8 + +/\x{d800}/8 + +/\x{dfff}/8 + +/\h+/8 + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/[\h\x{e000}]+/8BZ + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/\H+/8 + \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} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/[\H\x{d7ff}]+/8BZ + \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} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/\v+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/[\v\x{e000}]+/8BZ + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/\V+/8 + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/[\V\x{d7ff}]+/8BZ + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/(..)\1/8 + ab\P + aba\P + abab\P + +/(..)\1/8i + ab\P + abA\P + aBAb\P + +/(..)\1{2,}/8 + ab\P + aba\P + abab\P + ababa\P + ababab\P + ababab\P\P + abababa\P + abababa\P\P + +/(..)\1{2,}/8i + ab\P + aBa\P + aBAb\P + AbaBA\P + abABAb\P + aBAbaB\P\P + abABabA\P + abaBABa\P\P + +/(..)\1{2,}?x/8i + ab\P + abA\P + aBAb\P + abaBA\P + abAbaB\P + abaBabA\P + abAbABaBx\P + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi + +/(?<=\x{1234}\x{1234})\bxy/I8 + +/(?8BZ + +/[\u0100-\u0200]/8BZ + +/\ud800/8 /-- End of testinput5 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput6 b/ext/pcre/pcrelib/testdata/testinput6 index 503a5bc764c..7010a0d2d12 100644 --- a/ext/pcre/pcrelib/testdata/testinput6 +++ b/ext/pcre/pcrelib/testdata/testinput6 @@ -655,6 +655,7 @@ A\x80 /^[\p{Arabic}]/8 + \x{604} \x{60e} \x{656} \x{657} @@ -670,7 +671,6 @@ \x{6ef} \x{6fa} ** Failers - \x{600} \x{650} \x{651} \x{652} @@ -688,7 +688,6 @@ \x{61f} \x{964} \x{965} - \x{970} /^\p{Inherited}/8 \x{64b} @@ -802,4 +801,18 @@ ** Failers a\xFCb +/â±¥/8i + â±¥ + Ⱥx + Ⱥ + +/[â±¥]/8i + â±¥ + Ⱥx + Ⱥ + +/Ⱥ/8i + Ⱥ + â±¥ + /-- End of testinput6 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput7 b/ext/pcre/pcrelib/testdata/testinput7 index 66748873c5a..6ef92303135 100644 --- a/ext/pcre/pcrelib/testdata/testinput7 +++ b/ext/pcre/pcrelib/testdata/testinput7 @@ -1,4610 +1,625 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ - -/abc/ - abc - -/ab*c/ - abc - abbbbc - ac - -/ab+c/ - abc - abbbbbbc - *** Failers - ac - ab - -/a*/ - a - aaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F - -/(a|abcd|african)/ - a - abcd - african - -/^abc/ - abcdef - *** Failers - xyzabc - xyz\nabc - -/^abc/m - abcdef - xyz\nabc - *** Failers - xyzabc - -/\Aabc/ - abcdef - *** Failers - xyzabc - xyz\nabc - -/\Aabc/m - abcdef - *** Failers - xyzabc - xyz\nabc - -/\Gabc/ - abcdef - xyzabc\>3 - *** Failers - xyzabc - xyzabc\>2 - -/x\dy\Dz/ - x9yzz - x0y+z - *** Failers - xyz - xxy0z - -/x\sy\Sz/ - x yzz - x y+z - *** Failers - xyz - xxyyz - -/x\wy\Wz/ - xxy+z - *** Failers - xxy0z - x+y+z - -/x.y/ - x+y - x-y - *** Failers - x\ny - -/x.y/s - x+y - x-y - x\ny +/-- These tests for Unicode property support test PCRE's API and show some of + the compiled code. They are not Perl-compatible. --/ -/(a.b(?s)c.d|x.y)p.q/ - a+bc+dp+q - a+bc\ndp+q - x\nyp+q - *** Failers - a\nbc\ndp+q - a+bc\ndp\nq - x\nyp\nq +/[\p{L}]/DZ -/a\d\z/ - ba0 - *** Failers - ba0\n - ba0\ncd +/[\p{^L}]/DZ -/a\d\z/m - ba0 - *** Failers - ba0\n - ba0\ncd +/[\P{L}]/DZ -/a\d\Z/ - ba0 - ba0\n - *** Failers - ba0\ncd +/[\P{^L}]/DZ -/a\d\Z/m - ba0 - ba0\n - *** Failers - ba0\ncd +/[abc\p{L}\x{0660}]/8DZ -/a\d$/ - ba0 - ba0\n - *** Failers - ba0\ncd +/[\p{Nd}]/8DZ + 1234 -/a\d$/m - ba0 - ba0\n - ba0\ncd - *** Failers +/[\p{Nd}+-]+/8DZ + 1234 + 12-34 + 12+\x{661}-34 + ** Failers + abcd -/abc/i - abc - aBc - ABC +/[\x{105}-\x{109}]/8iDZ + \x{104} + \x{105} + \x{109} + ** Failers + \x{100} + \x{10a} -/[^a]/ - abcd - -/ab?\w/ - abz - abbz - azz +/[z-\x{100}]/8iDZ + Z + z + \x{39c} + \x{178} + | + \x{80} + \x{ff} + \x{100} + \x{101} + ** Failers + \x{102} + Y + y -/x{0,3}yz/ - ayzq - axyzq - axxyz - axxxyzq - axxxxyzq - *** Failers - ax - axx - -/x{3}yz/ - axxxyzq - axxxxyzq - *** Failers - ax - axx - ayzq - axyzq - axxyz - -/x{2,3}yz/ - axxyz - axxxyzq - axxxxyzq - *** Failers - ax - axx - ayzq - axyzq - -/[^a]+/ - bac - bcdefax - *** Failers - aaaaa +/[z-\x{100}]/8DZi -/[^a]*/ - bac - bcdefax - *** Failers - aaaaa - -/[^a]{3,5}/ - xyz - awxyza - abcdefa - abcdefghijk - *** Failers - axya - axa - aaaaa +/(?:[\PPa*]*){8,}/ -/\d*/ - 1234b567 - xyz - -/\D*/ - a1234b567 - xyz - -/\d+/ - ab1234c56 - *** Failers - xyz - -/\D+/ - ab123c56 - *** Failers - 789 - -/\d?A/ - 045ABC - ABC - *** Failers - XYZ - -/\D?A/ - ABC - BAC - 9ABC - *** Failers +/[\P{Any}]/BZ -/a+/ - aaaa +/[\P{Any}\E]/BZ -/^.*xyz/ - xyz - ggggggggxyz - -/^.+xyz/ - abcdxyz - axyz - *** Failers - xyz - -/^.?xyz/ - xyz - cxyz +/(\P{Yi}+\277)/ -/^\d{2,3}X/ - 12X - 123X - *** Failers +/(\P{Yi}+\277)?/ + +/(?<=\P{Yi}{3}A)X/ + +/\p{Yi}+(\P{Yi}+)(?1)/ + +/(\P{Yi}{2}\277)?/ + +/[\P{Yi}A]/ + +/[\P{Yi}\P{Yi}\P{Yi}A]/ + +/[^\P{Yi}A]/ + +/[^\P{Yi}\P{Yi}\P{Yi}A]/ + +/(\P{Yi}*\277)*/ + +/(\P{Yi}*?\277)*/ + +/(\p{Yi}*+\277)*/ + +/(\P{Yi}?\277)*/ + +/(\P{Yi}??\277)*/ + +/(\p{Yi}?+\277)*/ + +/(\P{Yi}{0,3}\277)*/ + +/(\P{Yi}{0,3}?\277)*/ + +/(\p{Yi}{0,3}+\277)*/ + +/\p{Zl}{2,3}+/8BZ + \xe2\x80\xa8\xe2\x80\xa8 + \x{2028}\x{2028}\x{2028} + +/\p{Zl}/8BZ + +/\p{Lu}{3}+/8BZ + +/\pL{2}+/8BZ + +/\p{Cc}{2}+/8BZ + +/^\p{Cs}/8 + \?\x{dfff} + ** Failers + \x{09f} + +/^\p{Sc}+/8 + $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} + \x{9f2} + ** Failers X - 1X - 1234X + \x{2c2} + +/^\p{Zs}/8 + \ \ + \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. --/ + +/\p{^Lu}/8i + 1234 + ** Failers + ABC -/^[abcd]\d/ - a45 - b93 - c99z - d04 +/\P{Lu}/8i + 1234 + ** Failers + ABC + +/\p{Ll}/8i + a + Az + ** Failers + ABC + +/\p{Lu}/8i + A + a\x{10a0}B + ** Failers + a + \x{1d00} + +/[\x{c0}\x{391}]/8i + \x{c0} + \x{e0} + +/-- The next two are special cases where the lengths of the different cases of +the same character differ. The first went wrong with heap frame storage; the +second was broken in all cases. --/ + +/^\x{023a}+?(\x{0130}+)/8i + \x{023a}\x{2c65}\x{0130} + +/^\x{023a}+([^X])/8i + \x{023a}\x{2c65}X + +/\x{c0}+\x{116}+/8i + \x{c0}\x{e0}\x{116}\x{117} + +/[\x{c0}\x{116}]+/8i + \x{c0}\x{e0}\x{116}\x{117} + +/(\x{de})\1/8i + \x{de}\x{de} + \x{de}\x{fe} + \x{fe}\x{fe} + \x{fe}\x{de} + +/^\x{c0}$/8i + \x{c0} + \x{e0} + +/^\x{e0}$/8i + \x{c0} + \x{e0} + +/-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE +will match it only with UCP support, because without that it has no notion +of case for anything other than the ASCII letters. --/ + +/((?i)[\x{c0}])/8 + \x{c0} + \x{e0} + +/(?i:[\x{c0}])/8 + \x{c0} + \x{e0} + +/-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 + +/^\X/8 + A + A\x{300}BC + A\x{300}\x{301}\x{302}BC *** Failers - e45 - abcd - abcd1234 - 1234 + \x{300} + +/-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ -/^[abcd]*\d/ - a45 - b93 - c99z - d04 - abcd1234 - 1234 - *** Failers - e45 - abcd +/^\p{Xan}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + ** Failers + _ABC -/^[abcd]+\d/ - a45 - b93 - c99z - d04 - abcd1234 - *** Failers - 1234 - e45 - abcd +/^\p{Xan}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + ** Failers + _ABC -/^a+X/ - aX - aaX +/^\p{Xan}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ -/^[abcd]?\d/ - a45 - b93 - c99z - d04 - 1234 - *** Failers - abcd1234 - e45 +/^\p{Xan}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xan}{2,9}/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xan}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^[\p{Xan}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + ** Failers + _ABC + +/^[\p{Xan}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + ** Failers + _ABC -/^[abcd]{2,3}\d/ - ab45 - bcd93 - *** Failers - 1234 - a36 - abcd1234 - ee45 +/^>\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} -/^(abc)*\d/ - abc45 - abcabcabc45 - 42xyz - *** Failers +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^(abc)+\d/ - abc45 - abcabcabc45 - *** Failers - 42xyz +/^>\p{Xsp}+?/8 + >\x{1680}\x{2028}\x{0b} -/^(abc)?\d/ - abc45 - 42xyz - *** Failers - abcabcabc45 +/^>\p{Xsp}*/8 + > \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} + +/^>\p{Xsp}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^(abc){2,3}\d/ - abcabc45 - abcabcabc45 - *** Failers - abcabcabcabc45 - abc45 - 42xyz +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} -/1(abc|xyz)2(?1)3/ - 1abc2abc3456 - 1abc2xyz3456 +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^(a*\w|ab)=(a*\w|ab)/ - ab=ab +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} -/^(a*\w|ab)=(?1)/ - ab=ab +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/^([^()]|\((?1)*\))*$/ +/^\p{Xwd}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_B12\x{6ca}\x{a6c}\x{10a7} + +/^\p{Xwd}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^[\p{Xwd}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/-- A check not in UTF-8 mode --/ + +/^[\p{Xwd}]+/ + ABCD1234_ + +/-- Some negative checks --/ + +/^[\P{Xwd}]+/8 + !.+\x{019}\x{35a}AB + +/^[\p{^Xwd}]+/8 + !.+\x{019}\x{35a}AB + +/[\D]/WBZ8 + 1\x{3c8}2 + +/[\d]/WBZ8 + >\x{6f4}< + +/[\S]/WBZ8 + \x{1680}\x{6f4}\x{1680} + +/[\s]/WBZ8 + >\x{1680}< + +/[\W]/WBZ8 + A\x{1712}B + +/[\w]/WBZ8 + >\x{1723}< + +/\D/WBZ8 + 1\x{3c8}2 + +/\d/WBZ8 + >\x{6f4}< + +/\S/WBZ8 + \x{1680}\x{6f4}\x{1680} + +/\s/WBZ8 + >\x{1680}> + +/\W/WBZ8 + A\x{1712}B + +/\w/WBZ8 + >\x{1723}< + +/[[:alpha:]]/WBZ + +/[[:lower:]]/WBZ + +/[[:upper:]]/WBZ + +/[[:alnum:]]/WBZ + +/[[:ascii:]]/WBZ + +/[[:cntrl:]]/WBZ + +/[[:digit:]]/WBZ + +/[[:graph:]]/WBZ + +/[[:print:]]/WBZ + +/[[:punct:]]/WBZ + +/[[:space:]]/WBZ + +/[[:word:]]/WBZ + +/[[:xdigit:]]/WBZ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Some of these are silly, but they check various combinations --/ + +/[[:^alpha:][:^cntrl:]]+/8WBZ + 123 + abc + +/[[:^cntrl:][:^alpha:]]+/8WBZ + 123 + abc + +/[[:alpha:]]+/8WBZ abc - a(b)c - a(b(c))d - *** Failers) - a(b(c)d -/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)a*)\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 - *** Failers - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x - <> - - hij> - hij> - def> - - *** Failers - + aX41z *** Failers - xyz\Z + aAz -/\Gabc/ - abcdef - defabcxyz\>3 - *** Failers - defabcxyz +/(?<=ab\Cde)X/8 -/^abcdef/ - ab\P - abcde\P - abcdef\P - *** Failers - abx\P +/\X/ + a\P + a\P\P -/^a{2,4}\d+z/ +/\Xa/ + aa\P + aa\P\P + +/\X{2}/ + aa\P + aa\P\P + +/\X+a/ a\P aa\P - aa2\P - aaa\P - aaa23\P - aaaa12345\P - aa0z\P - aaaa4444444444444z\P - *** Failers - az\P - aaaaa\P - a56\P - -/^abcdef/ - abc\P - def\R - -/(?<=foo)bar/ - xyzfo\P - foob\P\>2 - foobar...\R\P\>4 - xyzfo\P - foobar\>2 - *** Failers - xyzfo\P - obar\R - -/(ab*(cd|ef))+X/ - adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z - lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z - cdabbbbbbbb\P\R\B\Z - efabbbbbbbbbbbbbbbb\P\R\B\Z - bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z - -/(a|b)/SF>testsavedregex ->>aaabxyzpqrrrabbxyyyypqAzz - >aaaabxyzpqrrrabbxyyyypqAzz - >>>>abcxyzpqrrrabbxyyyypqAzz - *** Failers - abxyzpqrrabbxyyyypqAzz - abxyzpqrrrrabbxyyyypqAzz - abxyzpqrrrabxyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyypqAzz - aaabcxyzpqrrrabbxyyyypqqqqqqqAzz - -/^(abc){1,2}zz/ - abczz - abcabczz - *** Failers - zz - abcabcabczz - >>abczz - -/^(b+?|a){1,2}?c/ - bc - bbc - bbbc - bac - bbac - aac - abbbbbbbbbbbc - bbbbbbbbbbbac - *** Failers - aaac - abbbbbbbbbbbac - -/^(b+|a){1,2}c/ - bc - bbc - bbbc - bac - bbac - aac - abbbbbbbbbbbc - bbbbbbbbbbbac - *** Failers - aaac - abbbbbbbbbbbac - -/^(b+|a){1,2}?bc/ - bbc - -/^(b*|ba){1,2}?bc/ - babc - bbabc - bababc - *** Failers - bababbc - babababc - -/^(ba|b*){1,2}?bc/ - babc - bbabc - bababc - *** Failers - bababbc - babababc - -/^\ca\cA\c[\c{\c:/ - \x01\x01\e;z - -/^[ab\]cde]/ - athing - bthing - ]thing - cthing - dthing - ething - *** Failers - fthing - [thing - \\thing - -/^[]cde]/ - ]thing - cthing - dthing - ething - *** Failers - athing - fthing - -/^[^ab\]cde]/ - fthing - [thing - \\thing - *** Failers - athing - bthing - ]thing - cthing - dthing - ething - -/^[^]cde]/ - athing - fthing - *** Failers - ]thing - cthing - dthing - ething - -/^\/ - - -/^ÿ/ - ÿ - -/^[0-9]+$/ - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 100 - *** Failers - abc - -/^.*nter/ - enter - inter - uponter - -/^xxx[0-9]+$/ - xxx0 - xxx1234 - *** Failers - xxx - -/^.+[0-9][0-9][0-9]$/ - x123 - xx123 - 123456 - *** Failers - 123 - x1234 - -/^.+?[0-9][0-9][0-9]$/ - x123 - xx123 - 123456 - *** Failers - 123 - x1234 - -/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ - abc!pqr=apquxz.ixr.zzz.ac.uk - *** Failers - !pqr=apquxz.ixr.zzz.ac.uk - abc!=apquxz.ixr.zzz.ac.uk - abc!pqr=apquxz:ixr.zzz.ac.uk - abc!pqr=apquxz.ixr.zzz.ac.ukk - -/:/ - Well, we need a colon: somewhere - *** Fail if we don't - -/([\da-f:]+)$/i - 0abc - abc - fed - E - :: - 5f03:12C0::932e - fed def - Any old stuff - *** Failers - 0zzz - gzzz - fed\x20 - Any old rubbish - -/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ - .1.2.3 - A.12.123.0 - *** Failers - .1.2.3333 - 1.2.3 - 1234.2.3 - -/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ - 1 IN SOA non-sp1 non-sp2( - 1 IN SOA non-sp1 non-sp2 ( - *** Failers - 1IN SOA non-sp1 non-sp2( - -/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ - a. - Z. - 2. - ab-c.pq-r. - sxk.zzz.ac.uk. - x-.y-. - *** Failers - -abc.peq. - -/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ - *.a - *.b0-a - *.c3-b.c - *.c-a.b-c - *** Failers - *.0 - *.a- - *.a-b.c- - *.c-a.0-c - -/^(?=ab(de))(abd)(e)/ - abde - -/^(?!(ab)de|x)(abd)(f)/ - abdf - -/^(?=(ab(cd)))(ab)/ - abcd - -/^[\da-f](\.[\da-f])*$/i - a.b.c.d - A.B.C.D - a.b.c.1.2.3.C - -/^\".*\"\s*(;.*)?$/ - \"1234\" - \"abcd\" ; - \"\" ; rhubarb - *** Failers - \"1234\" : things - -/^$/ - \ - *** Failers - -/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x - ab c - *** Failers - abc - ab cde - -/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ - ab c - *** Failers - abc - ab cde - -/^ a\ b[c ]d $/x - a bcd - a b d - *** Failers - abcd - ab d - -/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ - abcdefhijklm - -/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ - abcdefhijklm - -/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ - a+ Z0+\x08\n\x1d\x12 - -/^[.^$|()*+?{,}]+/ - .^\$(*+)|{?,?} - -/^a*\w/ - z - az - aaaz - a - aa - aaaa - a+ - aa+ - -/^a*?\w/ - z - az - aaaz - a - aa - aaaa - a+ - aa+ - -/^a+\w/ - az - aaaz - aa - aaaa - aa+ - -/^a+?\w/ - az - aaaz - aa - aaaa - aa+ - -/^\d{8}\w{2,}/ - 1234567890 - 12345678ab - 12345678__ - *** Failers - 1234567 - -/^[aeiou\d]{4,5}$/ - uoie - 1234 - 12345 - aaaaa - *** Failers - 123456 - -/^[aeiou\d]{4,5}?/ - uoie - 1234 - 12345 - aaaaa - 123456 - -/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ - From abcd Mon Sep 01 12:33:02 1997 - -/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ - From abcd Mon Sep 01 12:33:02 1997 - From abcd Mon Sep 1 12:33:02 1997 - *** Failers - From abcd Sep 01 12:33:02 1997 - -/^12.34/s - 12\n34 - 12\r34 - -/\w+(?=\t)/ - the quick brown\t fox - -/foo(?!bar)(.*)/ - foobar is foolish see? - -/(?:(?!foo)...|^.{0,2})bar(.*)/ - foobar crowbar etc - barrel - 2barrel - A barrel - -/^(\D*)(?=\d)(?!123)/ - abc456 - *** Failers - abc123 - -/^1234(?# test newlines - inside)/ - 1234 - -/^1234 #comment in extended re - /x - 1234 - -/#rhubarb - abcd/x - abcd - -/^abcd#rhubarb/x - abcd - -/(?!^)abc/ - the abc - *** Failers - abc - -/(?=^)abc/ - abc - *** Failers - the abc - -/^[ab]{1,3}(ab*|b)/ - aabbbbb - -/^[ab]{1,3}?(ab*|b)/ - aabbbbb - -/^[ab]{1,3}?(ab*?|b)/ - aabbbbb - -/^[ab]{1,3}(ab*?|b)/ - aabbbbb - -/ (?: [\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 -/x - Alan Other - - user\@dom.ain - \"A. Other\" (a comment) - A. Other (a comment) - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - A missing angle @,;:".\\\[\]\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# 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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -# leading word -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces -(?: -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -| -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -) # "special" comment or quoted string -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" -)* -< -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# < -(?: -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -(?: , -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -)* # additional domains -: -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)? # 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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address spec -> # > -# name and address -) -/x - Alan Other - - user\@dom.ain - \"A. Other\" (a comment) - A. Other (a comment) - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - A missing angle - a\rb - *** Failers - a\nb - -/abc$/ - abc - abc\n - *** Failers - abc\ndef - -/(abc)\123/ - abc\x53 - -/(abc)\223/ - abc\x93 - -/(abc)\323/ - abc\xd3 - -/(abc)\100/ - abc\x40 - abc\100 - -/(abc)\1000/ - abc\x400 - abc\x40\x30 - abc\1000 - abc\100\x30 - abc\100\060 - abc\100\60 - -/abc\81/ - abc\081 - abc\0\x38\x31 - -/abc\91/ - abc\091 - abc\0\x39\x31 - -/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ - abcdefghijk\12S - -/ab\idef/ - abidef - -/a{0}bc/ - bc - -/(a|(bc)){0,0}?xyz/ - xyz - -/abc[\10]de/ - abc\010de - -/abc[\1]de/ - abc\1de - -/(abc)[\1]de/ - abc\1de - -/(?s)a.b/ - a\nb - -/^([^a])([^\b])([^c]*)([^d]{3,4})/ - baNOTccccd - baNOTcccd - baNOTccd - bacccd - *** Failers - anything - b\bc - baccd - -/[^a]/ - Abc - -/[^a]/i - Abc - -/[^a]+/ - AAAaAbc - -/[^a]+/i - AAAaAbc - -/[^a]+/ - bbb\nccc - -/[^k]$/ - abc - *** Failers - abk - -/[^k]{2,3}$/ - abc - kbc - kabc - *** Failers - abk - akb - akk - -/^\d{8,}\@.+[^k]$/ - 12345678\@a.b.c.d - 123456789\@x.y.z - *** Failers - 12345678\@x.y.uk - 1234567\@a.b.c.d - -/[^a]/ - aaaabcd - aaAabcd - -/[^a]/i - aaaabcd - aaAabcd - -/[^az]/ - aaaabcd - aaAabcd - -/[^az]/i - aaaabcd - aaAabcd - -/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ - \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 - -/P[^*]TAIRE[^*]{1,6}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - -/P[^*]TAIRE[^*]{1,}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - -/(\.\d\d[1-9]?)\d+/ - 1.230003938 - 1.875000282 - 1.235 - -/(\.\d\d((?=0)|\d(?=\d)))/ - 1.230003938 - 1.875000282 - *** Failers - 1.235 - -/a(?)b/ - ab - -/\b(foo)\s+(\w+)/i - Food is on the foo table - -/foo(.*)bar/ - The food is under the bar in the barn. - -/foo(.*?)bar/ - The food is under the bar in the barn. - -/(.*)(\d*)/ - I have 2 numbers: 53147 - -/(.*)(\d+)/ - I have 2 numbers: 53147 - -/(.*?)(\d*)/ - I have 2 numbers: 53147 - -/(.*?)(\d+)/ - I have 2 numbers: 53147 - -/(.*)(\d+)$/ - I have 2 numbers: 53147 - -/(.*?)(\d+)$/ - I have 2 numbers: 53147 - -/(.*)\b(\d+)$/ - I have 2 numbers: 53147 - -/(.*\D)(\d+)$/ - I have 2 numbers: 53147 - -/^\D*(?!123)/ - ABC123 - -/^(\D*)(?=\d)(?!123)/ - ABC445 - *** Failers - ABC123 - -/^[W-]46]/ - W46]789 - -46]789 - *** Failers - Wall - Zebra - 42 - [abcd] - ]abcd[ - -/^[W-\]46]/ - W46]789 - Wall - Zebra - Xylophone - 42 - [abcd] - ]abcd[ - \\backslash - *** Failers - -46]789 - well - -/\d\d\/\d\d\/\d\d\d\d/ - 01/01/2000 - -/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark - -/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope - -/^(a){0,0}/ - bcd - abc - aab - -/^(a){0,1}/ - bcd - abc - aab - -/^(a){0,2}/ - bcd - abc - aab - -/^(a){0,3}/ - bcd - abc - aab - aaa - -/^(a){0,}/ - bcd - abc - aab - aaa - aaaaaaaa - -/^(a){1,1}/ - bcd - abc - aab - -/^(a){1,2}/ - bcd - abc - aab - -/^(a){1,3}/ - bcd - abc - aab - aaa - -/^(a){1,}/ - bcd - abc - aab - aaa - aaaaaaaa - -/.*\.gif/ - borfle\nbib.gif\nno - -/.{0,}\.gif/ - borfle\nbib.gif\nno - -/.*\.gif/m - borfle\nbib.gif\nno - -/.*\.gif/s - borfle\nbib.gif\nno - -/.*\.gif/ms - borfle\nbib.gif\nno - -/.*$/ - borfle\nbib.gif\nno - -/.*$/m - borfle\nbib.gif\nno - -/.*$/s - borfle\nbib.gif\nno - -/.*$/ms - borfle\nbib.gif\nno - -/.*$/ - borfle\nbib.gif\nno\n - -/.*$/m - borfle\nbib.gif\nno\n - -/.*$/s - borfle\nbib.gif\nno\n - -/.*$/ms - borfle\nbib.gif\nno\n - -/(.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(.*X|^B)/m - abcde\n1234Xyz - BarFoo - abcde\nBar - -/(.*X|^B)/s - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(.*X|^B)/ms - abcde\n1234Xyz - BarFoo - abcde\nBar - -/(?s)(.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(?s:.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/^.*B/ - **** Failers - abc\nB - -/(?s)^.*B/ - abc\nB - -/(?m)^.*B/ - abc\nB - -/(?ms)^.*B/ - abc\nB - -/(?ms)^B/ - abc\nB - -/(?s)B$/ - B\n - -/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ - 123456654321 - -/^\d\d\d\d\d\d\d\d\d\d\d\d/ - 123456654321 - -/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ - 123456654321 - -/^[abc]{12}/ - abcabcabcabc - -/^[a-c]{12}/ - abcabcabcabc - -/^(a|b|c){12}/ - abcabcabcabc - -/^[abcdefghijklmnopqrstuvwxy0123456789]/ - n - *** Failers - z - -/abcde{0,0}/ - abcd - *** Failers - abce - -/ab[cd]{0,0}e/ - abe - *** Failers - abcde - -/ab(c){0,0}d/ - abd - *** Failers - abcd - -/a(b*)/ - a - ab - abbbb - *** Failers - bbbbb - -/ab\d{0}e/ - abe - *** Failers - ab1e - -/"([^\\"]+|\\.)*"/ - the \"quick\" brown fox - \"the \\\"quick\\\" brown fox\" - -/.*?/g+ - abc - -/\b/g+ - abc - -/\b/+g - abc - -//g - abc - -/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is - 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide - -/a[^a]b/ - acb - a\nb - -/a.b/ - acb - *** Failers - a\nb - -/a[^a]b/s - acb - a\nb - -/a.b/s - acb - a\nb - -/^(b+?|a){1,2}?c/ - bac - bbac - bbbac - bbbbac - bbbbbac - -/^(b+|a){1,2}?c/ - bac - bbac - bbbac - bbbbac - bbbbbac - -/(?!\A)x/m - x\nb\n - a\bx\n - -/\x0{ab}/ - \0{ab} - -/(A|B)*?CD/ - CD - -/(A|B)*CD/ - CD - -/(?.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ - -"(?>.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - -/(?>(\.\d\d[1-9]?))\d+/ - 1.230003938 - 1.875000282 - *** Failers - 1.235 - -/^((?>\w+)|(?>\s+))*$/ - now is the time for all good men to come to the aid of the party - *** Failers - this is not a line with only words and spaces! - -/(\d+)(\w)/ - 12345a - 12345+ - -/((?>\d+))(\w)/ - 12345a - *** Failers - 12345+ - -/(?>a+)b/ - aaab - -/((?>a+)b)/ - aaab - -/(?>(a+))b/ - aaab - -/(?>b)+/ - aaabbbccc - -/(?>a+|b+|c+)*c/ - aaabbbbccccd - -/(a+|b+|c+)*c/ - aaabbbbccccd - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - -/\(((?>[^()]+)|\([^()]+\))+\)/ - (abc) - (abc(def)xyz) - *** Failers - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/a(?-i)b/i - ab - Ab - *** Failers - aB - AB - -/(a (?x)b c)d e/ - a bcd e - *** Failers - a b cd e - abcd e - a bcde - -/(a b(?x)c d (?-x)e f)/ - a bcde f - *** Failers - abcdef - -/(a(?i)b)c/ - abc - aBc - *** Failers - abC - aBC - Abc - ABc - ABC - AbC - -/a(?i:b)c/ - abc - aBc - *** Failers - ABC - abC - aBC - -/a(?i:b)*c/ - aBc - aBBc - *** Failers - aBC - aBBC - -/a(?=b(?i)c)\w\wd/ - abcd - abCd - *** Failers - aBCd - abcD - -/(?s-i:more.*than).*million/i - more than million - more than MILLION - more \n than Million - *** Failers - MORE THAN MILLION - more \n than \n million - -/(?:(?s-i)more.*than).*million/i - more than million - more than MILLION - more \n than Million - *** Failers - MORE THAN MILLION - more \n than \n million - -/(?>a(?i)b+)+c/ - abc - aBbc - aBBc - *** Failers - Abc - abAb - abbC - -/(?=a(?i)b)\w\wc/ - abc - aBc - *** Failers - Ab - abC - aBC - -/(?<=a(?i)b)(\w\w)c/ - abxxc - aBxxc - *** Failers - Abxxc - ABxxc - abxxC - -/^(?(?=abc)\w{3}:|\d\d)$/ - abc: - 12 - *** Failers - 123 - xyz - -/^(?(?!abc)\d\d|\w{3}:)$/ - abc: - 12 - *** Failers - 123 - xyz - -/(?(?<=foo)bar|cat)/ - foobar - cat - fcat - focat - *** Failers - foocat - -/(?(?a*)*/ - a - aa - aaaa - -/(abc|)+/ - abc - abcabc - abcabcabc - xyz - -/([a]*)*/ - a - aaaaa - -/([ab]*)*/ - a - b - ababab - aaaabcde - bbbb - -/([^a]*)*/ - b - bbbb - aaa - -/([^ab]*)*/ - cccc - abab - -/([a]*?)*/ - a - aaaa - -/([ab]*?)*/ - a - b - abab - baba - -/([^a]*?)*/ - b - bbbb - aaa - -/([^ab]*?)*/ - c - cccc - baba - -/(?>a*)*/ - a - aaabcde - -/((?>a*))*/ - aaaaa - aabbaa - -/((?>a*?))*/ - aaaaa - aabbaa - -/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x - 12-sep-98 - 12-09-98 - *** Failers - sep-12-98 - -/(?i:saturday|sunday)/ - saturday - sunday - Saturday - Sunday - SATURDAY - SUNDAY - SunDay - -/(a(?i)bc|BB)x/ - abcx - aBCx - bbx - BBx - *** Failers - abcX - aBCX - bbX - BBX - -/^([ab](?i)[cd]|[ef])/ - ac - aC - bD - elephant - Europe - frog - France - *** Failers - Africa - -/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ - ab - aBd - xy - xY - zebra - Zambesi - *** Failers - aCD - XY - -/(?<=foo\n)^bar/m - foo\nbar - *** Failers - bar - baz\nbar - -/(?<=(?]&/ - <&OUT - -/(?:(f)(o)(o)|(b)(a)(r))*/ - foobar - -/(?<=a)b/ - ab - *** Failers - cb - b - -/(?a+)ab/ - -/(?>a+)b/ - aaab - -/([[:]+)/ - a:[b]: - -/([[=]+)/ - a=[b]= - -/([[.]+)/ - a.[b]. - -/((?>a+)b)/ - aaab - -/(?>(a+))b/ - aaab - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - -/a\Z/ - *** Failers - aaab - a\nb\n - -/b\Z/ - a\nb\n - -/b\z/ - -/b\Z/ - a\nb - -/b\z/ - a\nb - *** Failers - -/(?>.*)(?<=(abcd|wxyz))/ - alphabetabcd - endingwxyz - *** Failers - a rather long string that doesn't end with one of them - -/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark - -/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope - -/(?<=\d{3}(?!999))foo/ - 999foo - 123999foo - *** Failers - 123abcfoo - -/(?<=(?!...999)\d{3})foo/ - 999foo - 123999foo - *** Failers - 123abcfoo - -/(?<=\d{3}(?!999)...)foo/ - 123abcfoo - 123456foo - *** Failers - 123999foo - -/(?<=\d{3}...)(?Z)+|A)*/ - ZABCDEFG - -/((?>)+|A)*/ - ZABCDEFG - -/a*/g - abbab - -/^[a-\d]/ - abcde - -things - 0digit - *** Failers - bcdef - -/^[\d-a]/ - abcde - -things - 0digit - *** Failers - bcdef - -/[[:space:]]+/ - > \x09\x0a\x0c\x0d\x0b< - -/[[:blank:]]+/ - > \x09\x0a\x0c\x0d\x0b< - -/[\s]+/ - > \x09\x0a\x0c\x0d\x0b< - -/\s+/ - > \x09\x0a\x0c\x0d\x0b< - -/a b/x - ab - -/(?!\A)x/m - a\nxb\n - -/(?!^)x/m - a\nxb\n - -/abc\Qabc\Eabc/ - abcabcabc - -/abc\Q(*+|\Eabc/ - abc(*+|abc - -/ abc\Q abc\Eabc/x - abc abcabc - *** Failers - abcabcabc - -/abc#comment - \Q#not comment - literal\E/x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal/x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal\E #more comment - /x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal\E #more comment/x - abc#not comment\n literal - -/\Qabc\$xyz\E/ - abc\\\$xyz - -/\Qabc\E\$\Qxyz\E/ - abc\$xyz - -/\Gabc/ - abc - *** Failers - xyzabc - -/\Gabc./g - abc1abc2xyzabc3 - -/abc./g - abc1abc2xyzabc3 - -/a(?x: b c )d/ - XabcdY - *** Failers - Xa b c d Y - -/((?x)x y z | a b c)/ - XabcY - AxyzB - -/(?i)AB(?-i)C/ - XabCY - *** Failers - XabcY - -/((?i)AB(?-i)C|D)E/ - abCE - DE - *** Failers - abcE - abCe - dE - De - -/[z\Qa-d]\E]/ - z - a - - - d - ] - *** Failers - b - -/[\z\C]/ - z - C - -/\M/ - M - -/(a+)*b/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ - REGular - regulaer - Regex - regulär - -/Åæåä[à-ÿÀ-ß]+/ - Åæåäà - Åæåäÿ - ÅæåäÀ - Åæåäß - -/(?<=Z)X./ - \x84XAZXB - -/^(?(2)a|(1)(2))+$/ - 123a - -/(?<=a|bbbb)c/ - ac - bbbbc - -/abc/>testsavedregex -testsavedregex -testsavedregex -testsavedregex - - xyz\r\nabc\ - xyz\rabc\ - xyz\r\nabc\ - ** Failers - xyz\nabc\ - xyz\r\nabc\ - xyz\nabc\ - xyz\rabc\ - xyz\rabc\ - -/abc$/m - xyzabc - xyzabc\n - xyzabc\npqr - xyzabc\r\ - xyzabc\rpqr\ - xyzabc\r\n\ - xyzabc\r\npqr\ - ** Failers - xyzabc\r - xyzabc\rpqr - xyzabc\r\n - xyzabc\r\npqr - -/^abc/m - xyz\rabcdef - xyz\nabcdef\ - ** Failers - xyz\nabcdef - -/^abc/m - xyz\nabcdef - xyz\rabcdef\ - ** Failers - xyz\rabcdef - -/^abc/m - xyz\r\nabcdef - xyz\rabcdef\ - ** Failers - xyz\rabcdef - -/.*/ - abc\ndef - abc\rdef - abc\r\ndef - \abc\ndef - \abc\rdef - \abc\r\ndef - \abc\ndef - \abc\rdef - \abc\r\ndef - -/\w+(.)(.)?def/s - abc\ndef - abc\rdef - abc\r\ndef - -/^\w+=.*(\\\n.*)*/ - abc=xyz\\\npqr - -/^(a()*)*/ - aaaa - -/^(?:a(?:(?:))*)*/ - aaaa - -/^(a()+)+/ - aaaa - -/^(?:a(?:(?:))+)+/ - aaaa - -/(a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?>a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?:a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/^a.b/ - a\rb - a\nb\ - ** Failers - a\nb - a\nb\ - a\rb\ - a\rb\ - -/^abc./mgx - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK - -/abc.$/mgx - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 - -/^a\Rb/ - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - ** Failers - a\n\rb - -/^a\R*b/ - ab - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - a\n\rb - a\n\r\x85\x0cb - -/^a\R+b/ - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - a\n\rb - a\n\r\x85\x0cb - ** Failers - ab - -/^a\R{1,3}b/ - a\nb - a\n\rb - a\n\r\x85b - a\r\n\r\nb - a\r\n\r\n\r\nb - a\n\r\n\rb - a\n\n\r\nb - ** Failers - a\n\n\n\rb - a\r - -/^a[\R]b/ - aRb - ** Failers - a\nb - -/.+foo/ - afoo - ** Failers - \r\nfoo - \nfoo - -/.+foo/ - afoo - \nfoo - ** Failers - \r\nfoo - -/.+foo/ - afoo - ** Failers - \nfoo - \r\nfoo - -/.+foo/s - afoo - \r\nfoo - \nfoo - -/^$/mg - abc\r\rxyz - abc\n\rxyz - ** Failers - abc\r\nxyz - -/^X/m - XABC - ** Failers - XABC\B - -/(?m)^$/g+ - abc\r\n\r\n - -/(?m)^$|^\r\n/g+ - abc\r\n\r\n - -/(?m)$/g+ - abc\r\n\r\n - -/(?|(abc)|(xyz))/ - >abc< - >xyz< - -/(x)(?|(abc)|(xyz))(x)/ - xabcx - xxyzx - -/(x)(?|(abc)(pqr)|(xyz))(x)/ - xabcpqrx - xxyzx - -/(?|(abc)|(xyz))(?1)/ - abcabc - xyzabc - ** Failers - xyzxyz - -/\H\h\V\v/ - X X\x0a - X\x09X\x0b - ** Failers - \xa0 X\x0a - -/\H*\h+\V?\v{3,4}/ - \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c - ** Failers - \x09\x20\xa0\x0a\x0b - -/\H{3,4}/ - XY ABCDE - XY PQR ST - -/.\h{3,4}./ - XY AB PQRS - -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - > X NYQZ - ** Failers - >XYZ - > X NY Z - -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - -/.+A/ - \r\nA - -/\nA/ - \r\nA - -/[\r\n]A/ - \r\nA - -/(\r|\n)A/ - \r\nA - -/a\Rb/I - a\rb - a\nb - a\r\nb - ** Failers - a\x85b - a\x0bb - -/a\Rb/I - a\rb - a\nb - a\r\nb - a\x85b - a\x0bb - ** Failers - a\x85b\ - a\x0bb\ - -/a\R?b/I - a\rb - a\nb - a\r\nb - ** Failers - a\x85b - a\x0bb - -/a\R?b/I - a\rb - a\nb - a\r\nb - a\x85b - a\x0bb - ** Failers - a\x85b\ - a\x0bb\ - -/a\R{2,4}b/I - a\r\n\nb - a\n\r\rb - a\r\n\r\n\r\n\r\nb - ** Failers - a\x85\85b - a\x0b\0bb - -/a\R{2,4}b/I - a\r\rb - a\n\n\nb - a\r\n\n\r\rb - a\x85\85b - a\x0b\0bb - ** Failers - a\r\r\r\r\rb - a\x85\85b\ - a\x0b\0bb\ - -/a(?!)|\wbc/ - abc - -/a[]b/ - ** Failers - ab - -/a[]+b/ - ** Failers - ab - -/a[]*+b/ - ** Failers - ab - -/a[^]b/ - aXb - a\nb - ** Failers - ab - -/a[^]+b/ - aXb - a\nX\nXb - ** Failers - ab - -/X$/E - X - ** Failers - X\n - -/X$/ - X - X\n - -/xyz/C - xyz - abcxyz - abcxyz\Y - ** Failers - abc - abc\Y - abcxypqr - abcxypqr\Y - -/(*NO_START_OPT)xyz/C - abcxyz - -/(?C)ab/ - ab - \C-ab - -/ab/C - ab - \C-ab - -/^"((?(?=[a])[^"])|b)*"$/C - "ab" - \C-"ab" - -/\d+X|9+Y/ - ++++123999\P - ++++123999Y\P - -/Z(*F)/ - Z\P - ZA\P - -/Z(?!)/ - Z\P - ZA\P - -/dog(sbody)?/ - dogs\P - dogs\P\P - -/dog(sbody)??/ - dogs\P - dogs\P\P - -/dog|dogsbody/ - dogs\P - dogs\P\P - -/dogsbody|dog/ - dogs\P - dogs\P\P - -/Z(*F)Q|ZXY/ - Z\P - ZA\P - X\P - -/\bthe cat\b/ - the cat\P - the cat\P\P - -/dog(sbody)?/ - dogs\D\P - body\D\R - -/dog(sbody)?/ - dogs\D\P\P - body\D\R - -/abc/ - abc\P - abc\P\P - -/abc\K123/ - xyzabc123pqr - -/(?<=abc)123/ - xyzabc123pqr - xyzabc12\P - xyzabc12\P\P - -/\babc\b/ - +++abc+++ - +++ab\P - +++ab\P\P - -/(?=C)/g+ - ABCDECBA - -/(abc|def|xyz)/I - terhjk;abcdaadsfe - the quick xyz brown fox - \Yterhjk;abcdaadsfe - \Ythe quick xyz brown fox - ** Failers - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - -/(abc|def|xyz)/SI - terhjk;abcdaadsfe - the quick xyz brown fox - \Yterhjk;abcdaadsfe - \Ythe quick xyz brown fox - ** Failers - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - -/abcd*/+ - xxxxabcd\P - xxxxabcd\P\P - dddxxx\R - xxxxabcd\P\P - xxx\R - -/abcd*/i - xxxxabcd\P - xxxxabcd\P\P - XXXXABCD\P - XXXXABCD\P\P - -/abc\d*/ - xxxxabc1\P - xxxxabc1\P\P - -/abc[de]*/ - xxxxabcde\P - xxxxabcde\P\P - -/(?:(?1)|B)(A(*F)|C)/ - ABCD - CCD - ** Failers - CAD - -/^(?:(?1)|B)(A(*F)|C)/ - CCD - BCD - ** Failers - ABCD - CAD - BAD - -/^(?!a(*SKIP)b)/ - ac - -/^(?=a(*SKIP)b|ac)/ - ** Failers - ac - -/^(?=a(*THEN)b|ac)/ - ac - -/^(?=a(*PRUNE)b)/ - ab - ** Failers - ac - -/^(?(?!a(*SKIP)b))/ - ac - -/(?<=abc)def/ - abc\P\P - -/abc$/ - abc - abc\P - abc\P\P - -/abc$/m - abc - abc\n - abc\P\P - abc\n\P\P - abc\P - abc\n\P - -/abc\z/ - abc - abc\P - abc\P\P - -/abc\Z/ - abc - abc\P - abc\P\P - -/abc\b/ - abc - abc\P - abc\P\P - -/abc\B/ - abc - abc\P - abc\P\P - -/.+/ - abc\>0 - abc\>1 - abc\>2 - abc\>3 - abc\>4 - abc\>-4 + aa\P\P + +/\X+?a/ + a\P + ab\P + aa\P + aa\P\P + aba\P + +/-- These Unicode 6.1.0 scripts are not known to Perl. --/ + +/\p{Chakma}\d/8W + \x{11100}\x{1113c} + +/\p{Takri}\d/8W + \x{11680}\x{116c0} + +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P /-- End of testinput7 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput8 b/ext/pcre/pcrelib/testdata/testinput8 index 55d2fd3c068..e235445e01a 100644 --- a/ext/pcre/pcrelib/testdata/testinput8 +++ b/ext/pcre/pcrelib/testdata/testinput8 @@ -1,590 +1,4199 @@ -/-- 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. --/ - -/\x{100}ab/8 - \x{100}ab - -/a\x{100}*b/8 - ab - a\x{100}b - a\x{100}\x{100}b - -/a\x{100}+b/8 - a\x{100}b - a\x{100}\x{100}b - *** Failers - ab +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). + The -dfa flag must be used with pcretest when running it. --/ -/\bX/8 - Xoanon - +Xoanon - \x{300}Xoanon +/abc/ + abc + +/ab*c/ + abc + abbbbc + ac + +/ab+c/ + abc + abbbbbbc *** Failers - YXoanon + ac + ab -/\BX/8 - YXoanon - *** Failers - Xoanon - +Xoanon - \x{300}Xoanon - -/X\b/8 - X+oanon - ZX\x{300}oanon - FAX - *** Failers - Xoanon +/a*/ + a + aaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F -/X\B/8 - Xoanon - *** Failers - X+oanon - ZX\x{300}oanon - FAX - -/[^a]/8 +/(a|abcd|african)/ + a abcd - a\x{100} - -/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 - ab99 - \x{123}\x{123}45 - \x{400}\x{401}\x{402}6 - *** Failers - d99 - \x{123}\x{122}4 - \x{400}\x{403}6 - \x{400}\x{401}\x{402}\x{402}6 - -/abc/8 - Ã] - à - ÃÃà - ÃÃÃ\? - \xe1\x88 - \P\xe1\x88 - \P\P\xe1\x88 - -/a.b/8 - acb - a\x7fb - a\x{100}b - *** Failers - a\nb - -/a(.{3})b/8 - a\x{4000}xyb - a\x{4000}\x7fyb - a\x{4000}\x{100}yb - *** Failers - a\x{4000}b - ac\ncb - -/a(.*?)(.)/ - a\xc0\x88b - -/a(.*?)(.)/8 - a\x{100}b - -/a(.*)(.)/ - a\xc0\x88b - -/a(.*)(.)/8 - a\x{100}b - -/a(.)(.)/ - a\xc0\x92bcd - -/a(.)(.)/8 - a\x{240}bcd - -/a(.?)(.)/ - a\xc0\x92bcd - -/a(.?)(.)/8 - a\x{240}bcd - -/a(.??)(.)/ - a\xc0\x92bcd - -/a(.??)(.)/8 - a\x{240}bcd - -/a(.{3})b/8 - a\x{1234}xyb - a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - *** Failers - a\x{1234}b - ac\ncb - -/a(.{3,})b/8 - a\x{1234}xyb - a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - a\x{1234}\x{4321}\x{3412}\x{3421}b - *** Failers - a\x{1234}b - -/a(.{3,}?)b/8 - a\x{1234}xyb - a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - a\x{1234}\x{4321}\x{3412}\x{3421}b - *** Failers - a\x{1234}b - -/a(.{3,5})b/8 - a\x{1234}xyb - a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - axxxxxbcdefghijb - *** Failers - a\x{1234}b - axxxxxxbcdefghijb - -/a(.{3,5}?)b/8 - a\x{1234}xyb - a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - axxxxxbcdefghijb - *** Failers - a\x{1234}b - axxxxxxbcdefghijb - -/^[a\x{c0}]/8 - *** Failers - \x{100} - -/(?<=aXb)cd/8 - aXbcd - -/(?<=a\x{100}b)cd/8 - a\x{100}bcd - -/(?<=a\x{100000}b)cd/8 - a\x{100000}bcd + african -/(?:\x{100}){3}b/8 - \x{100}\x{100}\x{100}b +/^abc/ + abcdef + *** Failers + xyzabc + xyz\nabc + +/^abc/m + abcdef + xyz\nabc + *** Failers + xyzabc + +/\Aabc/ + abcdef + *** Failers + xyzabc + xyz\nabc + +/\Aabc/m + abcdef + *** Failers + xyzabc + xyz\nabc + +/\Gabc/ + abcdef + xyzabc\>3 + *** Failers + xyzabc + xyzabc\>2 + +/x\dy\Dz/ + x9yzz + x0y+z + *** Failers + xyz + xxy0z + +/x\sy\Sz/ + x yzz + x y+z + *** Failers + xyz + xxyyz + +/x\wy\Wz/ + xxy+z + *** Failers + xxy0z + x+y+z + +/x.y/ + x+y + x-y + *** Failers + x\ny + +/x.y/s + x+y + x-y + x\ny + +/(a.b(?s)c.d|x.y)p.q/ + a+bc+dp+q + a+bc\ndp+q + x\nyp+q *** Failers - \x{100}\x{100}b + a\nbc\ndp+q + a+bc\ndp\nq + x\nyp\nq -/\x{ab}/8 - \x{ab} - \xc2\xab - *** Failers - \x00{ab} - -/(?<=(.))X/8 - WXYZ - \x{256}XYZ +/a\d\z/ + ba0 *** Failers - XYZ + ba0\n + ba0\ncd -/[^a]+/8g - bcd - \x{100}aY\x{256}Z - -/^[^a]{2}/8 - \x{100}bc - -/^[^a]{2,}/8 - \x{100}bcAa - -/^[^a]{2,}?/8 - \x{100}bca - -/[^a]+/8ig - bcd - \x{100}aY\x{256}Z - -/^[^a]{2}/8i - \x{100}bc - -/^[^a]{2,}/8i - \x{100}bcAa - -/^[^a]{2,}?/8i - \x{100}bca - -/\x{100}{0,0}/8 - abcd - -/\x{100}?/8 - abcd - \x{100}\x{100} - -/\x{100}{0,3}/8 - \x{100}\x{100} - \x{100}\x{100}\x{100}\x{100} - -/\x{100}*/8 - abce - \x{100}\x{100}\x{100}\x{100} - -/\x{100}{1,1}/8 - abcd\x{100}\x{100}\x{100}\x{100} - -/\x{100}{1,3}/8 - abcd\x{100}\x{100}\x{100}\x{100} - -/\x{100}+/8 - abcd\x{100}\x{100}\x{100}\x{100} - -/\x{100}{3}/8 - abcd\x{100}\x{100}\x{100}XX - -/\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 - 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 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/\D*/8 - \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 - 1X2 - 1\x{100}2 - -/>\S/8 - > >X Y - > >\x{100} Y - -/\d/8 - \x{100}3 - -/\s/8 - \x{100} X - -/\D+/8 - 12abcd34 +/a\d\z/m + ba0 *** Failers + ba0\n + ba0\ncd + +/a\d\Z/ + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d\Z/m + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d$/ + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d$/m + ba0 + ba0\n + ba0\ncd + *** Failers + +/abc/i + abc + aBc + ABC + +/[^a]/ + abcd + +/ab?\w/ + abz + abbz + azz + +/x{0,3}yz/ + ayzq + axyzq + axxyz + axxxyzq + axxxxyzq + *** Failers + ax + axx + +/x{3}yz/ + axxxyzq + axxxxyzq + *** Failers + ax + axx + ayzq + axyzq + axxyz + +/x{2,3}yz/ + axxyz + axxxyzq + axxxxyzq + *** Failers + ax + axx + ayzq + axyzq + +/[^a]+/ + bac + bcdefax + *** Failers + aaaaa + +/[^a]*/ + bac + bcdefax + *** Failers + aaaaa + +/[^a]{3,5}/ + xyz + awxyza + abcdefa + abcdefghijk + *** Failers + axya + axa + aaaaa + +/\d*/ + 1234b567 + xyz + +/\D*/ + a1234b567 + xyz + +/\d+/ + ab1234c56 + *** Failers + xyz + +/\D+/ + ab123c56 + *** Failers + 789 + +/\d?A/ + 045ABC + ABC + *** Failers + XYZ + +/\D?A/ + ABC + BAC + 9ABC + *** Failers + +/a+/ + aaaa + +/^.*xyz/ + xyz + ggggggggxyz + +/^.+xyz/ + abcdxyz + axyz + *** Failers + xyz + +/^.?xyz/ + xyz + cxyz + +/^\d{2,3}X/ + 12X + 123X + *** Failers + X + 1X + 1234X + +/^[abcd]\d/ + a45 + b93 + c99z + d04 + *** Failers + e45 + abcd + abcd1234 1234 -/\D{2,3}/8 - 12abcd34 - 12ab34 - *** Failers - 1234 - 12a34 +/^[abcd]*\d/ + a45 + b93 + c99z + d04 + abcd1234 + 1234 + *** Failers + e45 + abcd -/\D{2,3}?/8 - 12abcd34 - 12ab34 - *** Failers - 1234 - 12a34 +/^[abcd]+\d/ + a45 + b93 + c99z + d04 + abcd1234 + *** Failers + 1234 + e45 + abcd -/\d+/8 - 12abcd34 +/^a+X/ + aX + aaX + +/^[abcd]?\d/ + a45 + b93 + c99z + d04 + 1234 + *** Failers + abcd1234 + e45 + +/^[abcd]{2,3}\d/ + ab45 + bcd93 + *** Failers + 1234 + a36 + abcd1234 + ee45 + +/^(abc)*\d/ + abc45 + abcabcabc45 + 42xyz *** Failers -/\d{2,3}/8 - 12abcd34 - 1234abcd - *** Failers - 1.4 - -/\d{2,3}?/8 - 12abcd34 - 1234abcd - *** Failers - 1.4 - -/\S+/8 - 12abcd34 +/^(abc)+\d/ + abc45 + abcabcabc45 *** Failers - \ \ + 42xyz -/\S{2,3}/8 - 12abcd34 - 1234abcd +/^(abc)?\d/ + abc45 + 42xyz *** Failers - \ \ + abcabcabc45 -/\S{2,3}?/8 - 12abcd34 - 1234abcd +/^(abc){2,3}\d/ + abcabc45 + abcabcabc45 *** Failers - \ \ + abcabcabcabc45 + abc45 + 42xyz -/>\s+ <34 - *** Failers +/1(abc|xyz)2(?1)3/ + 1abc2abc3456 + 1abc2xyz3456 -/>\s{2,3} \s{2,3}? abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)a*)\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 *** Failers + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -/[Z\x{100}]/8 - Z\x{100} - \x{100} - \x{100}Z +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x + <> + + hij> + hij> + def> + + *** Failers + 3 *** Failers + defabcxyz -/[\x{100}\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - *** Failers - -/[\x{100}-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - *** Failers - -/[z-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - abzcd - ab|cd - *** Failers - -/[Q\x{100}\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - Q? - *** Failers - -/[Q\x{100}-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - Q? - *** Failers - -/[Qz-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - abzcd - ab|cd - Q? - *** Failers - -/[\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers - -/[\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers - -/[Q\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers - -/[Q\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers - -/(?<=[\x{100}\x{200}])X/8 - abc\x{200}X - abc\x{100}X +/^abcdef/ + ab\P + abcde\P + abcdef\P *** Failers - X + abx\P -/(?<=[Q\x{100}\x{200}])X/8 - abc\x{200}X - abc\x{100}X - abQX +/^a{2,4}\d+z/ + a\P + aa\P + aa2\P + aaa\P + aaa23\P + aaaa12345\P + aa0z\P + aaaa4444444444444z\P *** Failers - X + az\P + aaaaa\P + a56\P -/(?<=[\x{100}\x{200}]{3})X/8 - abc\x{100}\x{200}\x{100}X +/^abcdef/ + abc\P + def\R + +/(?<=foo)bar/ + xyzfo\P + foob\P\>2 + foobar...\R\P\>4 + xyzfo\P + foobar\>2 + *** Failers + xyzfo\P + obar\R + +/(ab*(cd|ef))+X/ + adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z + lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z + cdabbbbbbbb\P\R\B\Z + efabbbbbbbbbbbbbbbb\P\R\B\Z + bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z + +/(a|b)/SF>testsavedregex +>>aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz *** Failers - abc\x{200}X - X + abxyzpqrrabbxyyyypqAzz + abxyzpqrrrrabbxyyyypqAzz + abxyzpqrrrabxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyypqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz -/[^\x{100}\x{200}]X/8 - AX - \x{150}X - \x{500}X +/^(abc){1,2}zz/ + abczz + abcabczz *** Failers - \x{100}X - \x{200}X + zz + abcabcabczz + >>abczz -/[^Q\x{100}\x{200}]X/8 - AX - \x{150}X - \x{500}X +/^(b+?|a){1,2}?c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac *** Failers - \x{100}X - \x{200}X - QX + aaac + abbbbbbbbbbbac -/[^\x{100}-\x{200}]X/8 - AX - \x{500}X +/^(b+|a){1,2}c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac *** Failers - \x{100}X - \x{150}X - \x{200}X + aaac + abbbbbbbbbbbac -/[z-\x{100}]/8i +/^(b+|a){1,2}?bc/ + bbc + +/^(b*|ba){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^(ba|b*){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + +/^[ab\]cde]/ + athing + bthing + ]thing + cthing + dthing + ething + *** Failers + fthing + [thing + \\thing + +/^[]cde]/ + ]thing + cthing + dthing + ething + *** Failers + athing + fthing + +/^[^ab\]cde]/ + fthing + [thing + \\thing + *** Failers + athing + bthing + ]thing + cthing + dthing + ething + +/^[^]cde]/ + athing + fthing + *** Failers + ]thing + cthing + dthing + ething + +/^\/ + + +/^ÿ/ + ÿ + +/^[0-9]+$/ + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + *** Failers + abc + +/^.*nter/ + enter + inter + uponter + +/^xxx[0-9]+$/ + xxx0 + xxx1234 + *** Failers + xxx + +/^.+[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + *** Failers + !pqr=apquxz.ixr.zzz.ac.uk + abc!=apquxz.ixr.zzz.ac.uk + abc!pqr=apquxz:ixr.zzz.ac.uk + abc!pqr=apquxz.ixr.zzz.ac.ukk + +/:/ + Well, we need a colon: somewhere + *** Fail if we don't + +/([\da-f:]+)$/i + 0abc + abc + fed + E + :: + 5f03:12C0::932e + fed def + Any old stuff + *** Failers + 0zzz + gzzz + fed\x20 + Any old rubbish + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + A.12.123.0 + *** Failers + .1.2.3333 + 1.2.3 + 1234.2.3 + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 1 IN SOA non-sp1 non-sp2 ( + *** Failers + 1IN SOA non-sp1 non-sp2( + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + Z. + 2. + ab-c.pq-r. + sxk.zzz.ac.uk. + x-.y-. + *** Failers + -abc.peq. + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + *.b0-a + *.c3-b.c + *.c-a.b-c + *** Failers + *.0 + *.a- + *.a-b.c- + *.c-a.0-c + +/^(?=ab(de))(abd)(e)/ + abde + +/^(?!(ab)de|x)(abd)(f)/ + abdf + +/^(?=(ab(cd)))(ab)/ + abcd + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + A.B.C.D + a.b.c.1.2.3.C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + \"abcd\" ; + \"\" ; rhubarb + *** Failers + \"1234\" : things + +/^$/ + \ + *** Failers + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + *** Failers + abc + ab cde + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + *** Failers + abc + ab cde + +/^ a\ b[c ]d $/x + a bcd + a b d + *** Failers + abcd + ab d + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + +/^a*\w/ z - Z - \x{100} + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a*?\w/ + z + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a+\w/ + az + aaaz + aa + aaaa + aa+ + +/^a+?\w/ + az + aaaz + aa + aaaa + aa+ + +/^\d{8}\w{2,}/ + 1234567890 + 12345678ab + 12345678__ *** Failers - \x{102} - y + 1234567 -/[\xFF]/ - >\xff< +/^[aeiou\d]{4,5}$/ + uoie + 1234 + 12345 + aaaaa + *** Failers + 123456 -/[\xff]/8 - >\x{ff}< +/^[aeiou\d]{4,5}?/ + uoie + 1234 + 12345 + aaaaa + 123456 -/[^\xFF]/ - XYZ +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 -/[^\xff]/8 - XYZ - \x{123} +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + From abcd Mon Sep 1 12:33:02 1997 + *** Failers + From abcd Sep 01 12:33:02 1997 -/^[ac]*b/8 - xb +/^12.34/s + 12\n34 + 12\r34 -/^[ac\x{100}]*b/8 - xb +/\w+(?=\t)/ + the quick brown\t fox -/^[^x]*b/8i - xb +/foo(?!bar)(.*)/ + foobar is foolish see? -/^[^x]*b/8 - xb +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + barrel + 2barrel + A barrel + +/^(\D*)(?=\d)(?!123)/ + abc456 + *** Failers + abc123 + +/^1234(?# test newlines + inside)/ + 1234 + +/^1234 #comment in extended re + /x + 1234 + +/#rhubarb + abcd/x + abcd + +/^abcd#rhubarb/x + abcd + +/(?!^)abc/ + the abc + *** Failers + abc + +/(?=^)abc/ + abc + *** Failers + the abc + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + +/ (?: [\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 +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle @,;:".\\\[\]\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# 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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # 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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle + a\rb + *** Failers + a\nb + +/abc$/ + abc + abc\n + *** Failers + abc\ndef + +/(abc)\123/ + abc\x53 + +/(abc)\223/ + abc\x93 + +/(abc)\323/ + abc\xd3 + +/(abc)\100/ + abc\x40 + abc\100 + +/(abc)\1000/ + abc\x400 + abc\x40\x30 + abc\1000 + abc\100\x30 + abc\100\060 + abc\100\60 + +/abc\81/ + abc\081 + abc\0\x38\x31 + +/abc\91/ + abc\091 + abc\0\x39\x31 + +/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ + abcdefghijk\12S + +/ab\idef/ + abidef + +/a{0}bc/ + bc + +/(a|(bc)){0,0}?xyz/ + xyz + +/abc[\10]de/ + abc\010de + +/abc[\1]de/ + abc\1de + +/(abc)[\1]de/ + abc\1de + +/(?s)a.b/ + a\nb + +/^([^a])([^\b])([^c]*)([^d]{3,4})/ + baNOTccccd + baNOTcccd + baNOTccd + bacccd + *** Failers + anything + b\bc + baccd + +/[^a]/ + Abc -/^\d*b/8 - xb +/[^a]/i + Abc -/(|a)/g8 - catac - a\x{256}a +/[^a]+/ + AAAaAbc + +/[^a]+/i + AAAaAbc -/^\x{85}$/8i - \x{85} +/[^a]+/ + bbb\nccc + +/[^k]$/ + abc + *** Failers + abk + +/[^k]{2,3}$/ + abc + kbc + kabc + *** Failers + abk + akb + akk -/^abc./mgx8 - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK +/^\d{8,}\@.+[^k]$/ + 12345678\@a.b.c.d + 123456789\@x.y.z + *** Failers + 12345678\@x.y.uk + 1234567\@a.b.c.d -/abc.$/mgx8 - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 +/[^a]/ + aaaabcd + aaAabcd -/^a\Rb/8 +/[^a]/i + aaaabcd + aaAabcd + +/[^az]/ + aaaabcd + aaAabcd + +/[^az]/i + aaaabcd + aaAabcd + +/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ + \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 + +/P[^*]TAIRE[^*]{1,6}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + +/P[^*]TAIRE[^*]{1,}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + +/(\.\d\d[1-9]?)\d+/ + 1.230003938 + 1.875000282 + 1.235 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 1.875000282 + *** Failers + 1.235 + +/a(?)b/ + ab + +/\b(foo)\s+(\w+)/i + Food is on the foo table + +/foo(.*)bar/ + The food is under the bar in the barn. + +/foo(.*?)bar/ + The food is under the bar in the barn. + +/(.*)(\d*)/ + I have 2 numbers: 53147 + +/(.*)(\d+)/ + I have 2 numbers: 53147 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 + +/(.*?)(\d+)/ + I have 2 numbers: 53147 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + +/^\D*(?!123)/ + ABC123 + +/^(\D*)(?=\d)(?!123)/ + ABC445 + *** Failers + ABC123 + +/^[W-]46]/ + W46]789 + -46]789 + *** Failers + Wall + Zebra + 42 + [abcd] + ]abcd[ + +/^[W-\]46]/ + W46]789 + Wall + Zebra + Xylophone + 42 + [abcd] + ]abcd[ + \\backslash + *** Failers + -46]789 + well + +/\d\d\/\d\d\/\d\d\d\d/ + 01/01/2000 + +/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/^(a){0,0}/ + bcd + abc + aab + +/^(a){0,1}/ + bcd + abc + aab + +/^(a){0,2}/ + bcd + abc + aab + +/^(a){0,3}/ + bcd + abc + aab + aaa + +/^(a){0,}/ + bcd + abc + aab + aaa + aaaaaaaa + +/^(a){1,1}/ + bcd + abc + aab + +/^(a){1,2}/ + bcd + abc + aab + +/^(a){1,3}/ + bcd + abc + aab + aaa + +/^(a){1,}/ + bcd + abc + aab + aaa + aaaaaaaa + +/.*\.gif/ + borfle\nbib.gif\nno + +/.{0,}\.gif/ + borfle\nbib.gif\nno + +/.*\.gif/m + borfle\nbib.gif\nno + +/.*\.gif/s + borfle\nbib.gif\nno + +/.*\.gif/ms + borfle\nbib.gif\nno + +/.*$/ + borfle\nbib.gif\nno + +/.*$/m + borfle\nbib.gif\nno + +/.*$/s + borfle\nbib.gif\nno + +/.*$/ms + borfle\nbib.gif\nno + +/.*$/ + borfle\nbib.gif\nno\n + +/.*$/m + borfle\nbib.gif\nno\n + +/.*$/s + borfle\nbib.gif\nno\n + +/.*$/ms + borfle\nbib.gif\nno\n + +/(.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(.*X|^B)/m + abcde\n1234Xyz + BarFoo + abcde\nBar + +/(.*X|^B)/s + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(.*X|^B)/ms + abcde\n1234Xyz + BarFoo + abcde\nBar + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(?s:.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/^.*B/ + **** Failers + abc\nB + +/(?s)^.*B/ + abc\nB + +/(?m)^.*B/ + abc\nB + +/(?ms)^.*B/ + abc\nB + +/(?ms)^B/ + abc\nB + +/(?s)B$/ + B\n + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + +/^\d\d\d\d\d\d\d\d\d\d\d\d/ + 123456654321 + +/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ + 123456654321 + +/^[abc]{12}/ + abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + *** Failers + z + +/abcde{0,0}/ + abcd + *** Failers + abce + +/ab[cd]{0,0}e/ + abe + *** Failers + abcde + +/ab(c){0,0}d/ + abd + *** Failers + abcd + +/a(b*)/ + a + ab + abbbb + *** Failers + bbbbb + +/ab\d{0}e/ + abe + *** Failers + ab1e + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + \"the \\\"quick\\\" brown fox\" + +/.*?/g+ + abc + +/\b/g+ + abc + +/\b/+g + abc + +//g + abc + +/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide + +/a[^a]b/ + acb + a\nb + +/a.b/ + acb + *** Failers + a\nb + +/a[^a]b/s + acb + a\nb + +/a.b/s + acb + a\nb + +/^(b+?|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/^(b+|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/(?!\A)x/m + x\nb\n + a\bx\n + +/\x0{ab}/ + \0{ab} + +/(A|B)*?CD/ + CD + +/(A|B)*CD/ + CD + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\d\d[1-9]?))\d+/ + 1.230003938 + 1.875000282 + *** Failers + 1.235 + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d+)(\w)/ + 12345a + 12345+ + +/((?>\d+))(\w)/ + 12345a + *** Failers + 12345+ + +/(?>a+)b/ + aaab + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/(?>b)+/ + aaabbbccc + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + +/(a+|b+|c+)*c/ + aaabbbbccccd + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/a(?-i)b/i + ab + Ab + *** Failers + aB + AB + +/(a (?x)b c)d e/ + a bcd e + *** Failers + a b cd e + abcd e + a bcde + +/(a b(?x)c d (?-x)e f)/ + a bcde f + *** Failers + abcdef + +/(a(?i)b)c/ + abc + aBc + *** Failers + abC + aBC + Abc + ABc + ABC + AbC + +/a(?i:b)c/ + abc + aBc + *** Failers + ABC + abC + aBC + +/a(?i:b)*c/ + aBc + aBBc + *** Failers + aBC + aBBC + +/a(?=b(?i)c)\w\wd/ + abcd + abCd + *** Failers + aBCd + abcD + +/(?s-i:more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?:(?s-i)more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?>a(?i)b+)+c/ + abc + aBbc + aBBc + *** Failers + Abc + abAb + abbC + +/(?=a(?i)b)\w\wc/ + abc + aBc + *** Failers + Ab + abC + aBC + +/(?<=a(?i)b)(\w\w)c/ + abxxc + aBxxc + *** Failers + Abxxc + ABxxc + abxxC + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 12 + *** Failers + 123 + xyz + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 12 + *** Failers + 123 + xyz + +/(?(?<=foo)bar|cat)/ + foobar + cat + fcat + focat + *** Failers + foocat + +/(?(?a*)*/ + a + aa + aaaa + +/(abc|)+/ + abc + abcabc + abcabcabc + xyz + +/([a]*)*/ + a + aaaaa + +/([ab]*)*/ + a + b + ababab + aaaabcde + bbbb + +/([^a]*)*/ + b + bbbb + aaa + +/([^ab]*)*/ + cccc + abab + +/([a]*?)*/ + a + aaaa + +/([ab]*?)*/ + a + b + abab + baba + +/([^a]*?)*/ + b + bbbb + aaa + +/([^ab]*?)*/ + c + cccc + baba + +/(?>a*)*/ + a + aaabcde + +/((?>a*))*/ + aaaaa + aabbaa + +/((?>a*?))*/ + aaaaa + aabbaa + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 12-09-98 + *** Failers + sep-12-98 + +/(?i:saturday|sunday)/ + saturday + sunday + Saturday + Sunday + SATURDAY + SUNDAY + SunDay + +/(a(?i)bc|BB)x/ + abcx + aBCx + bbx + BBx + *** Failers + abcX + aBCX + bbX + BBX + +/^([ab](?i)[cd]|[ef])/ + ac + aC + bD + elephant + Europe + frog + France + *** Failers + Africa + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + aBd + xy + xY + zebra + Zambesi + *** Failers + aCD + XY + +/(?<=foo\n)^bar/m + foo\nbar + *** Failers + bar + baz\nbar + +/(?<=(?]&/ + <&OUT + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + +/(?<=a)b/ + ab + *** Failers + cb + b + +/(?a+)ab/ + +/(?>a+)b/ + aaab + +/([[:]+)/ + a:[b]: + +/([[=]+)/ + a=[b]= + +/([[.]+)/ + a.[b]. + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/a\Z/ + *** Failers + aaab + a\nb\n + +/b\Z/ + a\nb\n + +/b\z/ + +/b\Z/ + a\nb + +/b\z/ + a\nb + *** Failers + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + endingwxyz + *** Failers + a rather long string that doesn't end with one of them + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/(?<=\d{3}(?!999))foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=(?!...999)\d{3})foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 123456foo + *** Failers + 123999foo + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + +/((?>)+|A)*/ + ZABCDEFG + +/a*/g + abbab + +/^[a-\d]/ + abcde + -things + 0digit + *** Failers + bcdef + +/^[\d-a]/ + abcde + -things + 0digit + *** Failers + bcdef + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + +/a b/x + ab + +/(?!\A)x/m + a\nxb\n + +/(?!^)x/m + a\nxb\n + +/abc\Qabc\Eabc/ + abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + *** Failers + abcabcabc + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + +/\Gabc/ + abc + *** Failers + xyzabc + +/\Gabc./g + abc1abc2xyzabc3 + +/abc./g + abc1abc2xyzabc3 + +/a(?x: b c )d/ + XabcdY + *** Failers + Xa b c d Y + +/((?x)x y z | a b c)/ + XabcY + AxyzB + +/(?i)AB(?-i)C/ + XabCY + *** Failers + XabcY + +/((?i)AB(?-i)C|D)E/ + abCE + DE + *** Failers + abcE + abCe + dE + De + +/[z\Qa-d]\E]/ + z + a + - + d + ] + *** Failers + b + +/[\z\C]/ + z + C + +/\M/ + M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + regulaer + Regex + regulär + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + Åæåäÿ + ÅæåäÀ + Åæåäß + +/(?<=Z)X./ + \x84XAZXB + +/^(?(2)a|(1)(2))+$/ + 123a + +/(?<=a|bbbb)c/ + ac + bbbbc + +/abc/SS>testsavedregex +testsavedregex +testsavedregex +testsavedregex + + xyz\r\nabc\ + xyz\rabc\ + xyz\r\nabc\ + ** Failers + xyz\nabc\ + xyz\r\nabc\ + xyz\nabc\ + xyz\rabc\ + xyz\rabc\ + +/abc$/m + xyzabc + xyzabc\n + xyzabc\npqr + xyzabc\r\ + xyzabc\rpqr\ + xyzabc\r\n\ + xyzabc\r\npqr\ + ** Failers + xyzabc\r + xyzabc\rpqr + xyzabc\r\n + xyzabc\r\npqr + +/^abc/m + xyz\rabcdef + xyz\nabcdef\ + ** Failers + xyz\nabcdef + +/^abc/m + xyz\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/^abc/m + xyz\r\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/.*/ + abc\ndef + abc\rdef + abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + +/\w+(.)(.)?def/s + abc\ndef + abc\rdef + abc\r\ndef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + +/^(a()*)*/ + aaaa + +/^(?:a(?:(?:))*)*/ + aaaa + +/^(a()+)+/ + aaaa + +/^(?:a(?:(?:))+)+/ + aaaa + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/^a.b/ + a\rb + a\nb\ + ** Failers + a\nb + a\nb\ + a\rb\ + a\rb\ + +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + +/^a\Rb/ a\nb a\rb a\r\nb a\x0bb a\x0cb - a\x{85}b - a\x{2028}b - a\x{2029}b + a\x85b ** Failers a\n\rb -/^a\R*b/8 +/^a\R*b/ ab a\nb a\rb a\r\nb a\x0bb - a\x0c\x{2028}\x{2029}b - a\x{85}b + a\x0cb + a\x85b a\n\rb - a\n\r\x{85}\x0cb + a\n\r\x85\x0cb -/^a\R+b/8 +/^a\R+b/ a\nb a\rb a\r\nb a\x0bb - a\x0c\x{2028}\x{2029}b - a\x{85}b + a\x0cb + a\x85b a\n\rb - a\n\r\x{85}\x0cb + a\n\r\x85\x0cb ** Failers ab - -/^a\R{1,3}b/8 + +/^a\R{1,3}b/ a\nb a\n\rb - a\n\r\x{85}b + a\n\r\x85b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb @@ -593,111 +4202,600 @@ a\n\n\n\rb a\r -/\h+\V?\v{3,4}/8 - \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a +/^a[\R]b/ + aRb + ** Failers + a\nb -/\V?\v{3,4}/8 - \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a +/.+foo/ + afoo + ** Failers + \r\nfoo + \nfoo -/\h+\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< +/.+foo/ + afoo + \nfoo + ** Failers + \r\nfoo -/\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< +/.+foo/ + afoo + ** Failers + \nfoo + \r\nfoo -/\H\h\V\v/8 +/.+foo/s + afoo + \r\nfoo + \nfoo + +/^$/mg + abc\r\rxyz + abc\n\rxyz + ** Failers + abc\r\nxyz + +/^X/m + XABC + ** Failers + XABC\B + +/(?m)^$/g+ + abc\r\n\r\n + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + +/(?m)$/g+ + abc\r\n\r\n + +/(?|(abc)|(xyz))/ + >abc< + >xyz< + +/(x)(?|(abc)|(xyz))(x)/ + xabcx + xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + xyzabc + ** Failers + xyzxyz + +/\H\h\V\v/ X X\x0a X\x09X\x0b ** Failers - \x{a0} X\x0a + \xa0 X\x0a -/\H*\h+\V?\v{3,4}/8 - \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 +/\H*\h+\V?\v{3,4}/ + \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c ** Failers - \x09\x20\x{a0}\x0a\x0b + \x09\x20\xa0\x0a\x0b -/\H\h\V\v/8 - \x{3001}\x{3000}\x{2030}\x{2028} - X\x{180e}X\x{85} +/\H{3,4}/ + XY ABCDE + XY PQR ST + +/.\h{3,4}./ + XY AB PQRS + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + > X NYQZ ** Failers - \x{2009} X\x0a + >XYZ + > X NY Z + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA -/\H*\h+\V?\v{3,4}/8 - \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 - ** Failers - \x09\x{200a}\x{a0}\x{2028}\x0b - -/a\Rb/I8 +/\nA/ + \r\nA + +/[\r\n]A/ + \r\nA + +/(\r|\n)A/ + \r\nA + +/a\Rb/I a\rb a\nb a\r\nb ** Failers - a\x{85}b + a\x85b a\x0bb -/a\Rb/I8 +/a\Rb/I a\rb a\nb a\r\nb - a\x{85}b + a\x85b a\x0bb ** Failers - a\x{85}b\ + a\x85b\ a\x0bb\ -/a\R?b/I8 +/a\R?b/I a\rb a\nb a\r\nb ** Failers - a\x{85}b + a\x85b a\x0bb -/a\R?b/I8 +/a\R?b/I a\rb a\nb a\r\nb - a\x{85}b + a\x85b a\x0bb ** Failers - a\x{85}b\ + a\x85b\ a\x0bb\ + +/a\R{2,4}b/I + a\r\n\nb + a\n\r\rb + a\r\n\r\n\r\n\r\nb + ** Failers + a\x85\85b + a\x0b\0bb + +/a\R{2,4}b/I + a\r\rb + a\n\n\nb + a\r\n\n\r\rb + a\x85\85b + a\x0b\0bb + ** Failers + a\r\r\r\r\rb + a\x85\85b\ + a\x0b\0bb\ + +/a(?!)|\wbc/ + abc + +/a[]b/ + ** Failers + ab + +/a[]+b/ + ** Failers + ab + +/a[]*+b/ + ** Failers + ab + +/a[^]b/ + aXb + a\nb + ** Failers + ab + +/a[^]+b/ + aXb + a\nX\nXb + ** Failers + ab + +/X$/E + X + ** Failers + X\n + +/X$/ + X + X\n + +/xyz/C + xyz + abcxyz + abcxyz\Y + ** Failers + abc + abc\Y + abcxypqr + abcxypqr\Y + +/(*NO_START_OPT)xyz/C + abcxyz + +/(?C)ab/ + ab + \C-ab + +/ab/C + ab + \C-ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" + \C-"ab" + +/\d+X|9+Y/ + ++++123999\P + ++++123999Y\P + +/Z(*F)/ + Z\P + ZA\P + +/Z(?!)/ + Z\P + ZA\P + +/dog(sbody)?/ + dogs\P + dogs\P\P + +/dog(sbody)??/ + dogs\P + dogs\P\P + +/dog|dogsbody/ + dogs\P + dogs\P\P -/X/8f - A\x{1ec5}ABCXYZ +/dogsbody|dog/ + dogs\P + dogs\P\P -/abcd*/8 +/Z(*F)Q|ZXY/ + Z\P + ZA\P + X\P + +/\bthe cat\b/ + the cat\P + the cat\P\P + +/dog(sbody)?/ + dogs\D\P + body\D\R + +/dog(sbody)?/ + dogs\D\P\P + body\D\R + +/abc/ + abc\P + abc\P\P + +/abc\K123/ + xyzabc123pqr + +/(?<=abc)123/ + xyzabc123pqr + xyzabc12\P + xyzabc12\P\P + +/\babc\b/ + +++abc+++ + +++ab\P + +++ab\P\P + +/(?=C)/g+ + ABCDECBA + +/(abc|def|xyz)/I + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + +/(abc|def|xyz)/SI + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + +/abcd*/+ xxxxabcd\P xxxxabcd\P\P + dddxxx\R + xxxxabcd\P\P + xxx\R -/abcd*/i8 +/abcd*/i xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P -/abc\d*/8 +/abc\d*/ xxxxabc1\P xxxxabc1\P\P -/abc[de]*/8 +/abc[de]*/ xxxxabcde\P xxxxabcde\P\P -/\bthe cat\b/8 - the cat\P - the cat\P\P +/(?:(?1)|B)(A(*F)|C)/ + ABCD + CCD + ** Failers + CAD -/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 +/^(?:(?1)|B)(A(*F)|C)/ + CCD + BCD + ** Failers + ABCD + CAD + BAD -/-- End of testinput8 --/ +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?(?!a(*SKIP)b))/ + ac + +/(?<=abc)def/ + abc\P\P + +/abc$/ + abc + abc\P + abc\P\P + +/abc$/m + abc + abc\n + abc\P\P + abc\n\P\P + abc\P + abc\n\P + +/abc\z/ + abc + abc\P + abc\P\P + +/abc\Z/ + abc + abc\P + abc\P\P + +/abc\b/ + abc + abc\P + abc\P\P + +/abc\B/ + abc + abc\P + abc\P\P + +/.+/ + abc\>0 + abc\>1 + abc\>2 + abc\>3 + abc\>4 + abc\>-4 + +/^(?:a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(?:aa|(?:a)++\w)/ + aaaab + aaaa + ** Failers + bbb + +/^(?:a)*+\w/ + aaaab + bbb + ** Failers + aaaa + +/^(a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(a|)++\w/ + aaaab + ** Failers + aaaa + bbb + +/(?=abc){3}abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)+abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)++abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc){0}xyz/ + xyz + +/(?=abc){1}xyz/ + ** Failers + xyz + +/(?=(a))?./ + ab + bc + +/(?=(a))??./ + ab + bc + +/^(?=(a)){0}b(?1)/ + backgammon + +/^(?=(?1))?[az]([abc])d/ + abd + zcdxx + +/^(?!a){0}\w+/ + aaaaa + +/(?<=(abc))?xyz/ + abcxyz + pqrxyz + +/((?2))((?1))/ + abc + +/(?(R)a+|(?R)b)/ + aaaabcde + +/(?(R)a+|((?R))b)/ + aaaabcde + +/((?(R)a+|(?1)b))/ + aaaabcde + +/((?(R2)a+|(?1)b))/ + aaaabcde + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde + +/(a+)/ + \O6aaaa + \O8aaaa + +/ab\Cde/ + abXde + +/(?<=ab\Cde)X/ + abZdeX + +/^\R/ + \r\P + \r\P\P + +/^\R{2,3}x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R{2,3}?x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R?x/ + \r\P + \r\P\P + x + \rx + +/^\R+x/ + \r\P + \r\P\P + \r\n\P + \r\n\P\P + \rx + +/^a$/ + a\r\P + a\r\P\P + +/^a$/m + a\r\P + a\r\P\P + +/^(a$|a\r)/ + a\r\P + a\r\P\P + +/^(a$|a\r)/m + a\r\P + a\r\P\P + +/./ + \r\P + \r\P\P + +/.{2,3}/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + xx\xa0xabcd + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + xx\xa0xxxxxabcd + +/-- End of testinput8 --/ diff --git a/ext/pcre/pcrelib/testdata/testinput9 b/ext/pcre/pcrelib/testdata/testinput9 index 8d312e02875..766c9c0fb6f 100644 --- a/ext/pcre/pcrelib/testdata/testinput9 +++ b/ext/pcre/pcrelib/testdata/testinput9 @@ -1,989 +1,717 @@ -/-- This set of tests check Unicode property support with the DFA matching - functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest - when running it. --/ +/-- 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. --/ -/\pL\P{Nd}/8 - AB +/\x{100}ab/8 + \x{100}ab + +/a\x{100}*b/8 + ab + a\x{100}b + a\x{100}\x{100}b + +/a\x{100}+b/8 + a\x{100}b + a\x{100}\x{100}b + *** Failers + ab + +/\bX/8 + Xoanon + +Xoanon + \x{300}Xoanon + *** Failers + YXoanon + +/\BX/8 + YXoanon *** Failers - A0 - 00 + Xoanon + +Xoanon + \x{300}Xoanon -/\X./8 - AB - A\x{300}BC - A\x{300}\x{301}\x{302}BC +/X\b/8 + X+oanon + ZX\x{300}oanon + FAX + *** Failers + Xoanon + +/X\B/8 + Xoanon *** Failers - \x{300} - -/\X\X/8 - ABC - A\x{300}B\x{300}\x{301}C - A\x{300}\x{301}\x{302}BC - *** Failers - \x{300} - -/^\pL+/8 + X+oanon + ZX\x{300}oanon + FAX + +/[^a]/8 abcd - a - *** Failers + a\x{100} -/^\PL+/8 - 1234 - = +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + \x{123}\x{123}45 + \x{400}\x{401}\x{402}6 + *** Failers + d99 + \x{123}\x{122}4 + \x{400}\x{403}6 + \x{400}\x{401}\x{402}\x{402}6 + +/a.b/8 + acb + a\x7fb + a\x{100}b + *** Failers + a\nb + +/a(.{3})b/8 + a\x{4000}xyb + a\x{4000}\x7fyb + a\x{4000}\x{100}yb + *** Failers + a\x{4000}b + ac\ncb + +/a(.*?)(.)/ + a\xc0\x88b + +/a(.*?)(.)/8 + a\x{100}b + +/a(.*)(.)/ + a\xc0\x88b + +/a(.*)(.)/8 + a\x{100}b + +/a(.)(.)/ + a\xc0\x92bcd + +/a(.)(.)/8 + a\x{240}bcd + +/a(.?)(.)/ + a\xc0\x92bcd + +/a(.?)(.)/8 + a\x{240}bcd + +/a(.??)(.)/ + a\xc0\x92bcd + +/a(.??)(.)/8 + a\x{240}bcd + +/a(.{3})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + *** Failers + a\x{1234}b + ac\ncb + +/a(.{3,})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,5})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/a(.{3,5}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/^[a\x{c0}]/8 + *** Failers + \x{100} + +/(?<=aXb)cd/8 + aXbcd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b *** Failers + \x{100}\x{100}b + +/\x{ab}/8 + \x{ab} + \xc2\xab + *** Failers + \x00{ab} + +/(?<=(.))X/8 + WXYZ + \x{256}XYZ + *** Failers + XYZ + +/[^a]+/8g + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + +/^[^a]{2,}/8 + \x{100}bcAa + +/^[^a]{2,}?/8 + \x{100}bca + +/[^a]+/8ig + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + +/^[^a]{2,}/8i + \x{100}bcAa + +/^[^a]{2,}?/8i + \x{100}bca + +/\x{100}{0,0}/8 + abcd + +/\x{100}?/8 + abcd + \x{100}\x{100} + +/\x{100}{0,3}/8 + \x{100}\x{100} + \x{100}\x{100}\x{100}\x{100} + +/\x{100}*/8 + abce + \x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,1}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{1,3}/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}+/8 + abcd\x{100}\x{100}\x{100}\x{100} + +/\x{100}{3}/8 + abcd\x{100}\x{100}\x{100}XX + +/\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 + 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 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 + 1X2 + 1\x{100}2 + +/>\S/8 + > >X Y + > >\x{100} Y + +/\d/8 + \x{100}3 + +/\s/8 + \x{100} X + +/\D+/8 + 12abcd34 + *** Failers + 1234 + +/\D{2,3}/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\D{2,3}?/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 + +/\d+/8 + 12abcd34 + *** Failers + +/\d{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\d{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 + +/\S+/8 + 12abcd34 + *** Failers + \ \ + +/\S{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/\S{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + \ \ + +/>\s+ <34 + *** Failers + +/>\s{2,3} \s{2,3}? \xff< -/^(\X*)C/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C +/[\xff]/8 + >\x{ff}< -/^(\X*?)C/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C - -/^(\X*)(.)/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C - -/^(\X*?)(.)/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C - -/^\X(.)/8 - *** Failers - A\x{300}\x{301}\x{302} - -/^\X{2,3}(.)/8 - A\x{300}\x{301}B\x{300}X - A\x{300}\x{301}B\x{300}C\x{300}\x{301} - A\x{300}\x{301}B\x{300}C\x{300}\x{301}X - A\x{300}\x{301}B\x{300}C\x{300}\x{301}DA\x{300}X - -/^\X{2,3}?(.)/8 - A\x{300}\x{301}B\x{300}X - A\x{300}\x{301}B\x{300}C\x{300}\x{301} - A\x{300}\x{301}B\x{300}C\x{300}\x{301}X - A\x{300}\x{301}B\x{300}C\x{300}\x{301}DA\x{300}X - -/^\pN{2,3}X/ - 12X - 123X - *** Failers - X - 1X - 1234X - -/\x{100}/i8 - \x{100} - \x{101} - -/^\p{Han}+/8 - \x{2e81}\x{3007}\x{2f804}\x{31a0} - ** Failers - \x{2e7f} - -/^\P{Katakana}+/8 - \x{3105} - ** Failers - \x{30ff} - -/^[\p{Arabic}]/8 - \x{06e9} - \x{060b} - ** Failers - X\x{06e9} - -/^[\P{Yi}]/8 - \x{2f800} - ** Failers - \x{a014} - \x{a4c6} - -/^\p{Any}X/8 - AXYZ - \x{1234}XYZ - ** Failers - X - -/^\P{Any}X/8 - ** Failers - AX - -/^\p{Any}?X/8 - XYZ - AXYZ - \x{1234}XYZ - ** Failers - ABXYZ - -/^\P{Any}?X/8 - XYZ - ** Failers - AXYZ - \x{1234}XYZ - ABXYZ - -/^\p{Any}+X/8 - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - ** Failers +/[^\xFF]/ XYZ -/^\P{Any}+X/8 - ** Failers - AXYZ - \x{1234}XYZ - A\x{1234}XYZ +/[^\xff]/8 XYZ + \x{123} -/^\p{Any}*X/8 - XYZ - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - ** Failers +/^[ac]*b/8 + xb -/^\P{Any}*X/8 - XYZ - ** Failers - AXYZ - \x{1234}XYZ - A\x{1234}XYZ +/^[ac\x{100}]*b/8 + xb -/^[\p{Any}]X/8 - AXYZ - \x{1234}XYZ - ** Failers - X - -/^[\P{Any}]X/8 - ** Failers - AX - -/^[\p{Any}]?X/8 - XYZ - AXYZ - \x{1234}XYZ - ** Failers - ABXYZ +/^[^x]*b/8i + xb -/^[\P{Any}]?X/8 - XYZ - ** Failers - AXYZ - \x{1234}XYZ - ABXYZ - -/^[\p{Any}]+X/8 - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - ** Failers - XYZ - -/^[\P{Any}]+X/8 - ** Failers - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - XYZ - -/^[\p{Any}]*X/8 - XYZ - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - ** Failers - -/^[\P{Any}]*X/8 - XYZ - ** Failers - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - -/^\p{Any}{3,5}?/8 - abcdefgh - \x{1234}\n\r\x{3456}xyz - -/^\p{Any}{3,5}/8 - abcdefgh - \x{1234}\n\r\x{3456}xyz - -/^\P{Any}{3,5}?/8 - ** Failers - abcdefgh - \x{1234}\n\r\x{3456}xyz - -/^\p{L&}X/8 - AXY - aXY - \x{1c5}XY - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]X/8 - AXY - aXY - \x{1c5}XY - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\p{L&}+X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]+X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\p{L&}+?X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]+?X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\P{L&}X/8 - !XY - \x{1bb}XY - \x{2b0}XY - ** Failers - \x{1c5}XY - AXY - -/^[\P{L&}]X/8 - !XY - \x{1bb}XY - \x{2b0}XY - ** Failers - \x{1c5}XY - AXY - -/^\x{023a}+?(\x{0130}+)/8i - \x{023a}\x{2c65}\x{0130} +/^[^x]*b/8 + xb -/^\x{023a}+([^X])/8i - \x{023a}\x{2c65}X - -/\x{c0}+\x{116}+/8i - \x{c0}\x{e0}\x{116}\x{117} +/^\d*b/8 + xb -/[\x{c0}\x{116}]+/8i - \x{c0}\x{e0}\x{116}\x{117} +/(|a)/g8 + catac + a\x{256}a -/Check property support in non-UTF-8 mode/ - -/\p{L}{4}/ - 123abcdefg - 123abc\xc4\xc5zz +/^\x{85}$/8i + \x{85} -/\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}/8 - \x{102A4}\x{AA52}\x{A91D}\x{1C46}\x{10283}\x{1092E}\x{1C6B}\x{A93B}\x{A8BF}\x{1BA0}\x{A50A}==== +/^abc./mgx8 + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK -/\x{a77d}\x{1d79}/8i - \x{a77d}\x{1d79} - \x{1d79}\x{a77d} +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 -/\x{a77d}\x{1d79}/8 - \x{a77d}\x{1d79} +/^a\Rb/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x{85}b + a\x{2028}b + a\x{2029}b + ** Failers + a\n\rb + +/^a\R*b/8 + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + +/^a\R+b/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb + ** Failers + ab + +/^a\R{1,3}b/8 + a\nb + a\n\rb + a\n\r\x{85}b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb + ** Failers + a\n\n\n\rb + a\r + +/\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + +/\V?\v{3,4}/8 + \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + +/\h+\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + +/\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + +/\H\h\V\v/8 + X X\x0a + X\x09X\x0b + ** Failers + \x{a0} X\x0a + +/\H*\h+\V?\v{3,4}/8 + \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 ** Failers - \x{1d79}\x{a77d} - -/^\p{Xan}/8 - ABCD - 1234 - \x{6ca} - \x{a6c} - \x{10a7} + \x09\x20\x{a0}\x0a\x0b + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} ** Failers - _ABC - -/^\p{Xan}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - ** Failers - _ABC - -/^\p{Xan}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + \x{2009} X\x0a -/^\p{Xan}{2,9}/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^[\p{Xan}]/8 - ABCD1234_ - 1234abcd_ - \x{6ca} - \x{a6c} - \x{10a7} - ** Failers - _ABC - -/^[\p{Xan}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - ** Failers - _ABC - -/^>\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} - ** Failers - \x{0b} - -/^>\p{Xsp}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}*/8 - > \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} - -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xsp}]+/8 - > \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} - >\x{a0} - ** Failers - \x{0b} - -/^>\p{Xps}+/8 - > \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} - -/^>\p{Xps}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>[\p{Xps}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xps}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^\p{Xwd}/8 - ABCD - 1234 - \x{6ca} - \x{a6c} - \x{10a7} - _ABC - ** Failers - [] - -/^\p{Xwd}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}{2,9}/8 - A_12\x{6ca}\x{a6c}\x{10a7} - -/^[\p{Xwd}]/8 - ABCD1234_ - 1234abcd_ - \x{6ca} - \x{a6c} - \x{10a7} - _ABC - ** Failers - [] - -/^[\p{Xwd}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/-- Unicode properties for \b abd \B --/ - -/\b...\B/8W - abc_ - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ - -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ - -/\b...\B/8 - abc_ +/\H*\h+\V?\v{3,4}/8 + \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 ** Failers - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ + \x09\x{200a}\x{a0}\x{2028}\x0b + +/a\Rb/I8 + a\rb + a\nb + a\r\nb + ** Failers + a\x{85}b + a\x0bb -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ +/a\Rb/I8 + a\rb + a\nb + a\r\nb + a\x{85}b + a\x0bb + ** Failers + a\x{85}b\ + a\x0bb\ + +/a\R?b/I8 + a\rb + a\nb + a\r\nb + ** Failers + a\x{85}b + a\x0bb -/\b...\B/W - abc_ - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ +/a\R?b/I8 + a\rb + a\nb + a\r\nb + a\x{85}b + a\x0bb + ** Failers + a\x{85}b\ + a\x0bb\ + +/X/8f + A\x{1ec5}ABCXYZ + +/abcd*/8 + xxxxabcd\P + xxxxabcd\P\P + +/abcd*/i8 + xxxxabcd\P + xxxxabcd\P\P + XXXXABCD\P + XXXXABCD\P\P + +/abc\d*/8 + xxxxabc1\P + xxxxabc1\P\P + +/abc[de]*/8 + xxxxabcde\P + xxxxabcde\P\P + +/\bthe cat\b/8 + the cat\P + the cat\P\P + +/ab\Cde/8 + abXde + +/(?<=ab\Cde)X/8 + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/[^\x{100}]/8 + \x{100}\x{101}X + +/[^\x{100}]+/8 + \x{100}\x{101}X /-- End of testinput9 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput1 b/ext/pcre/pcrelib/testdata/testoutput1 index 6ab67a7254e..99c0ebbc3c9 100644 --- a/ext/pcre/pcrelib/testdata/testoutput1 +++ b/ext/pcre/pcrelib/testdata/testoutput1 @@ -1,5 +1,6 @@ /-- This set of tests is for features that are compatible with all versions of - Perl 5, in non-UTF-8 mode. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and + 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox @@ -6666,4 +6667,2070 @@ No match ? 0: ? +/(abc)\1/i + abc +No match + +/(abc)\1/ + abc +No match + +/[^a]*/i + 12abc + 0: 12 + 12ABC + 0: 12 + +/[^a]*+/i + 12abc + 0: 12 + 12ABC + 0: 12 + +/[^a]*?X/i + ** Failers +No match + 12abc +No match + 12ABC +No match + +/[^a]+?X/i + ** Failers +No match + 12abc +No match + 12ABC +No match + +/[^a]?X/i + 12aXbcX + 0: X + 12AXBCX + 0: X + BCX + 0: CX + +/[^a]??X/i + 12aXbcX + 0: X + 12AXBCX + 0: X + BCX + 0: CX + +/[^a]?+X/i + 12aXbcX + 0: cX + 12AXBCX + 0: CX + BCX + 0: CX + +/[^a]{2,3}/i + abcdef + 0: bcd + ABCDEF + 0: BCD + +/[^a]{2,3}?/i + abcdef + 0: bc + ABCDEF + 0: BC + +/[^a]{2,3}+/i + abcdef + 0: bcd + ABCDEF + 0: BCD + +/((a|)+)+Z/ + Z + 0: Z + 1: + 2: + +/(a)b|(a)c/ + ac + 0: ac + 1: + 2: a + +/(?>(a))b|(a)c/ + ac + 0: ac + 1: + 2: a + +/(?=(a))ab|(a)c/ + ac + 0: ac + 1: + 2: a + +/((?>(a))b|(a)c)/ + ac + 0: ac + 1: ac + 2: + 3: a + +/((?>(a))b|(a)c)++/ + ac + 0: ac + 1: ac + 2: + 3: a + +/(?:(?>(a))b|(a)c)++/ + ac + 0: ac + 1: + 2: a + +/(?=(?>(a))b|(a)c)(..)/ + ac + 0: ac + 1: + 2: a + 3: ac + +/(?>(?>(a))b|(a)c)/ + ac + 0: ac + 1: + 2: a + +/(?:(?>([ab])))+a=/+ + =ba= + 0: ba= + 0+ + 1: b + +/(?>([ab]))+a=/+ + =ba= + 0: ba= + 0+ + 1: b + +/((?>(a+)b)+(aabab))/ + aaaabaaabaabab + 0: aaaabaaabaabab + 1: aaaabaaabaabab + 2: aaa + 3: aabab + +/(?>a+|ab)+?c/ + aabc +No match + +/(?>a+|ab)+c/ + aabc +No match + +/(?:a+|ab)+c/ + aabc + 0: aabc + +/(?(?=(a))a)/ + a + 0: a + 1: a + +/(?(?=(a))a)(b)/ + ab + 0: ab + 1: a + 2: b + +/^(?:a|ab)++c/ + aaaabc +No match + +/^(?>a|ab)++c/ + aaaabc +No match + +/^(?:a|ab)+c/ + aaaabc + 0: aaaabc + +/(?=abc){3}abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)+abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)++abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc){0}xyz/ + xyz + 0: xyz + +/(?=abc){1}xyz/ + ** Failers +No match + xyz +No match + +/(?=(a))?./ + ab + 0: a + 1: a + bc + 0: b + +/(?=(a))??./ + ab + 0: a + bc + 0: b + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/^(?=(?1))?[az]([abc])d/ + abd + 0: abd + 1: b + zcdxx + 0: zcd + 1: c + +/^(?!a){0}\w+/ + aaaaa + 0: aaaaa + +/(?<=(abc))?xyz/ + abcxyz + 0: xyz + 1: abc + pqrxyz + 0: xyz + +/^[\g]+/ + ggg<<>> + 0: ggg<<>> + ** Failers +No match + \\ga +No match + +/^[\ga]+/ + gggagagaxyz + 0: gggagaga + +/^[:a[:digit:]]+/ + aaaa444:::Z + 0: aaaa444::: + +/^[:a[:digit:]:b]+/ + aaaa444:::bbbZ + 0: aaaa444:::bbb + +/[:a]xxx[b:]/ + :xxx: + 0: :xxx: + +/(?<=a{2})b/i + xaabc + 0: b + ** Failers +No match + xabc +No match + +/(?XNNNYZ + 0: XNNNYZ + > X NYQZ + 0: X NYQZ + ** Failers +No match + >XYZ +No match + > X NY Z +No match + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + 0: XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/(foo)\Kbar/ + foobar + 0: bar + 1: foo + +/(foo)(\Kbar|baz)/ + foobar + 0: bar + 1: foo + 2: bar + foobaz + 0: foobaz + 1: foo + 2: baz + +/(foo\Kbar)baz/ + foobarbaz + 0: barbaz + 1: foobar + +/abc\K|def\K/g+ + Xabcdefghi + 0: + 0+ defghi + 0: + 0+ ghi + +/ab\Kc|de\Kf/g+ + Xabcdefghi + 0: c + 0+ defghi + 0: f + 0+ ghi + +/(?=C)/g+ + ABCDECBA + 0: + 0+ CDECBA + 0: + 0+ CBA + +/^abc\K/+ + abcdef + 0: + 0+ def + ** Failers +No match + defabcxyz +No match + +/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ + ababababbbabZXXXX + 0: ababababbbabZ + 1: ab + 2: b + +/(?tom|bon)-\g{A}/ + tom-tom + 0: tom-tom + 1: tom + bon-bon + 0: bon-bon + 1: bon + +/(^(a|b\g{-1}))/ + bacxxx +No match + +/(?|(abc)|(xyz))\1/ + abcabc + 0: abcabc + 1: abc + xyzxyz + 0: xyzxyz + 1: xyz + ** Failers +No match + abcxyz +No match + xyzabc +No match + +/(?|(abc)|(xyz))(?1)/ + abcabc + 0: abcabc + 1: abc + xyzabc + 0: xyzabc + 1: xyz + ** Failers +No match + xyzxyz +No match + +/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: c + 4: d + 5: Y + +/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: + 4: + 5: c + 6: d + 7: Y + +/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: + 4: + 5: c + 6: d + 7: Y + +/(?'abc'\w+):\k{2}/ + a:aaxyz + 0: a:aa + 1: a + ab:ababxyz + 0: ab:abab + 1: ab + ** Failers +No match + a:axyz +No match + ab:abxyz +No match + +/(?'abc'\w+):\g{abc}{2}/ + a:aaxyz + 0: a:aa + 1: a + ab:ababxyz + 0: ab:abab + 1: ab + ** Failers +No match + a:axyz +No match + ab:abxyz +No match + +/^(?a)? (?()b|c) (?('ab')d|e)/x + abd + 0: abd + 1: a + ce + 0: ce + +/^(a.)\g-1Z/ + aXaXZ + 0: aXaXZ + 1: aX + +/^(a.)\g{-1}Z/ + aXaXZ + 0: aXaXZ + 1: aX + +/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x + abcd + 0: ab + +/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) + (?(DEFINE) + (?[a-z]+) + (?\d+) + )/x + metcalfe 33 + 0: metcalfe 33 + 1: metcalfe + 2: 33 + +/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ + 1.2.3.4 + 0: 1.2.3.4 + 1: + 2: .4 + 131.111.10.206 + 0: 131.111.10.206 + 1: + 2: .206 + 10.0.0.0 + 0: 10.0.0.0 + 1: + 2: .0 + ** Failers +No match + 10.6 +No match + 455.3.4.5 +No match + +/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ + 1.2.3.4 + 0: 1.2.3.4 + 1: .4 + 131.111.10.206 + 0: 131.111.10.206 + 1: .206 + 10.0.0.0 + 0: 10.0.0.0 + 1: .0 + ** Failers +No match + 10.6 +No match + 455.3.4.5 +No match + +/^(\w++|\s++)*$/ + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + 1: party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d++)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: a + *** Failers +No match + 12345+ +No match + +/a++b/ + aaab + 0: aaab + +/(a++b)/ + aaab + 0: aaab + 1: aaab + +/(a++)b/ + aaab + 0: aaab + 1: aaa + +/([^()]++|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/\(([^()]++|\([^()]+\))+\)/ + (abc) + 0: (abc) + 1: abc + (abc(def)xyz) + 0: (abc(def)xyz) + 1: xyz + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/^([^()]|\((?1)*\))*$/ + abc + 0: abc + 1: c + a(b)c + 0: a(b)c + 1: c + a(b(c))d + 0: a(b(c))d + 1: d + *** Failers) +No match + a(b(c)d +No match + +/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) + 2: + 3: Satanoscillatemymetallicsonatas + 4: S + AmanaplanacanalPanama + 0: AmanaplanacanalPanama + 1: + 2: + 3: AmanaplanacanalPanama + 4: A + AblewasIereIsawElba + 0: AblewasIereIsawElba + 1: + 2: + 3: AblewasIereIsawElba + 4: A + *** Failers +No match + Thequickbrownfox +No match + +/^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ + 12 + 0: 12 + 1: 12 + (((2+2)*-3)-7) + 0: (((2+2)*-3)-7) + 1: (((2+2)*-3)-7) + 2: - + -12 + 0: -12 + 1: -12 + *** Failers +No match + ((2+2)*-3)-7) +No match + +/^(x(y|(?1){2})z)/ + xyz + 0: xyz + 1: xyz + 2: y + xxyzxyzz + 0: xxyzxyzz + 1: xxyzxyzz + 2: xyzxyz + *** Failers +No match + xxyzz +No match + xxyzxyzxyzz +No match + +/((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x + <> + 0: <> + 1: <> + 2: <> + + 0: + 1: + 2: + hij> + 0: hij> + 1: hij> + 2: hij> + hij> + 0: + 1: + 2: + def> + 0: def> + 1: def> + 2: def> + + 0: <> + 1: <> + 2: <> + *** Failers +No match + + 2: + 3: Satan, oscillate my metallic sonatas + 4: S + A man, a plan, a canal: Panama! + 0: A man, a plan, a canal: Panama! + 1: + 2: + 3: A man, a plan, a canal: Panama + 4: A + Able was I ere I saw Elba. + 0: Able was I ere I saw Elba. + 1: + 2: + 3: Able was I ere I saw Elba + 4: A + *** Failers +No match + The quick brown fox +No match + +/^((.)(?1)\2|.)$/ + a + 0: a + 1: a + aba + 0: aba + 1: aba + 2: a + aabaa + 0: aabaa + 1: aabaa + 2: a + abcdcba + 0: abcdcba + 1: abcdcba + 2: a + pqaabaaqp + 0: pqaabaaqp + 1: pqaabaaqp + 2: p + ablewasiereisawelba + 0: ablewasiereisawelba + 1: ablewasiereisawelba + 2: a + rhubarb +No match + the quick brown fox +No match + +/(a)(?<=b(?1))/ + baz + 0: a + 1: a + ** Failers +No match + caz +No match + +/(?<=b(?1))(a)/ + zbaaz + 0: a + 1: a + ** Failers +No match + aaa +No match + +/(?a)(?<=b(?&X))/ + baz + 0: a + 1: a + +/^(?|(abc)|(def))\1/ + abcabc + 0: abcabc + 1: abc + defdef + 0: defdef + 1: def + ** Failers +No match + abcdef +No match + defabc +No match + +/^(?|(abc)|(def))(?1)/ + abcabc + 0: abcabc + 1: abc + defabc + 0: defabc + 1: def + ** Failers +No match + defdef +No match + abcdef +No match + +/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ + a\"aaaaa + 0: a"aaaaa + 1: " + 2: + 3: " + b\"aaaaa + 0: b"aaaaa + 1: + 2: + 3: + 4: " + 5: + 6: " + ** Failers +No match + b\"11111 +No match + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + 0: BC + 1: C + CCD + 0: CC + 1: C + ** Failers +No match + CAD +No match + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + 0: CC + 1: C + BCD + 0: BC + 1: C + ** Failers +No match + ABCD +No match + CAD +No match + BAD +No match + +/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ + AAD + 0: AA + 1: A + ACD + 0: ACD + 1: C + BAD + 0: BA + 1: A + BCD + 0: BCD + 1: C + BAX + 0: BA + 1: A + ** Failers +No match + ACX +No match + ABC +No match + +/(?(DEFINE)(A))B(?1)C/ + BAC + 0: BAC + +/(?(DEFINE)((A)\2))B(?1)C/ + BAAC + 0: BAAC + +/(? \( ( [^()]++ | (?&pn) )* \) )/x + (ab(cd)ef) + 0: (ab(cd)ef) + 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: + ** Failers +No match + ac +No match + +/^(?=a(*ACCEPT)b)/ + ac + 0: + +/^(?(?!a(*SKIP)b))/ + ac + 0: + +/(?>a\Kb)/ + ab + 0: b + +/((?>a\Kb))/ + ab + 0: b + 1: ab + +/(a\Kb)/ + ab + 0: b + 1: ab + +/^a\Kcz|ac/ + ac + 0: ac + +/(?>a\Kbz|ab)/ + ab + 0: ab + +/^(?&t)(?(DEFINE)(?a\Kb))$/ + ab + 0: b + +/^([^()]|\((?1)*\))*$/ + a(b)c + 0: a(b)c + 1: c + a(b(c)d)e + 0: a(b(c)d)e + 1: e + +/(?P(?P0)(?P>L1)|(?P>L2))/ + 0 + 0: 0 + 1: 0 + 00 + 0: 00 + 1: 00 + 2: 0 + 0000 + 0: 0000 + 1: 0000 + 2: 0 + +/(?P(?P0)|(?P>L2)(?P>L1))/ + 0 + 0: 0 + 1: 0 + 2: 0 + 00 + 0: 0 + 1: 0 + 2: 0 + 0000 + 0: 0 + 1: 0 + 2: 0 + +/--- This one does fail, as expected, in Perl. It needs the complex item at the + end of the pattern. A single letter instead of (B|D) makes it not fail, + which I think is a Perl bug. --- / + +/A(*COMMIT)(B|D)/ + ACABX +No match + +/--- Check the use of names for failure ---/ + +/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K + ** Failers +No match + AC +No match, mark = A + CB +No match, mark = B + +/--- Force no study, otherwise mark is not seen. The studied version is in + test 2 because it isn't Perl-compatible. ---/ + +/(*MARK:A)(*SKIP:B)(C|X)/KSS + C + 0: C + 1: C +MK: A + D +No match, mark = A + +/^(A(*THEN:A)B|C(*THEN:B)D)/K + ** Failers +No match + CB +No match, mark = B + +/^(?:A(*THEN:A)B|C(*THEN:B)D)/K + CB +No match, mark = B + +/^(?>A(*THEN:A)B|C(*THEN:B)D)/K + CB +No match, mark = B + +/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note +that we have to have something complicated such as (B|Z) at the end because, +for Perl, a simple character somehow causes an unwanted optimization to mess +with the handling of backtracking verbs. ---/ + +/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Test skipping over a non-matching mark. ---/ + +/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Check shorthand for MARK ---/ + +/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Don't loop! Force no study, otherwise mark is not seen. ---/ + +/(*:A)A+(*SKIP:A)(B|Z)/KSS + AAAC +No match, mark = A + +/--- This should succeed, as a non-existent skip name disables the skip ---/ + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + 0: AC + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK + AAAC + 0: AC +MK: B + +/--- COMMIT at the start of a pattern should act like an anchor. Again, +however, we need the complication for Perl. ---/ + +/(*COMMIT)(A|P)(B|P)(C|P)/ + ABCDEFG + 0: ABC + 1: A + 2: B + 3: C + ** Failers +No match + DEFGABC +No match + +/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ + +/(\w+)(?>b(*COMMIT))\w{2}/ + abbb + 0: abbb + 1: a + +/(\w+)b(*COMMIT)\w{2}/ + abbb +No match + +/--- Check opening parens in comment when seeking forward reference. ---/ + +/(?&t)(?#()(?(DEFINE)(?a))/ + bac + 0: a + +/--- COMMIT should override THEN ---/ + +/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ + yes +No match + +/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ + yes +No match + +/b?(*SKIP)c/ + bc + 0: bc + abc + 0: bc + +/(*SKIP)bc/ + a +No match + +/(*SKIP)b/ + a +No match + +/(?P(?P=abn)xxx|)+/ + xxx + 0: + 1: + +/(?i:([^b]))(?1)/ + aa + 0: aa + 1: a + aA + 0: aA + 1: a + ** Failers + 0: ** + 1: * + ab +No match + aB +No match + Ba +No match + ba +No match + +/^(?&t)*+(?(DEFINE)(?a))\w$/ + aaaaaaX + 0: aaaaaaX + ** Failers +No match + aaaaaa +No match + +/^(?&t)*(?(DEFINE)(?a))\w$/ + aaaaaaX + 0: aaaaaaX + aaaaaa + 0: aaaaaa + +/^(a)*+(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + YZ + 0: Y + 1: + 2: Y + ** Failers +No match + aaaa +No match + +/^(?:a)*+(\w)/ + aaaaX + 0: aaaaX + 1: X + YZ + 0: Y + 1: Y + ** Failers +No match + aaaa +No match + +/^(a)++(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaaa +No match + YZ +No match + +/^(?:a)++(\w)/ + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaaa +No match + YZ +No match + +/^(a)?+(\w)/ + aaaaX + 0: aa + 1: a + 2: a + YZ + 0: Y + 1: + 2: Y + +/^(?:a)?+(\w)/ + aaaaX + 0: aa + 1: a + YZ + 0: Y + 1: Y + +/^(a){2,}+(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaa +No match + YZ +No match + +/^(?:a){2,}+(\w)/ + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaa +No match + YZ +No match + +/(a|)*(?1)b/ + b + 0: b + 1: + ab + 0: ab + 1: + aab + 0: aab + 1: + +/(a)++(?1)b/ + ** Failers +No match + ab +No match + aab +No match + +/(a)*+(?1)b/ + ** Failers +No match + ab +No match + aab +No match + +/(?1)(?:(b)){0}/ + b + 0: b + +/(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x + foo(bar(baz)+baz(bop)) + 0: foo(bar(baz)+baz(bop)) + 1: foo(bar(baz)+baz(bop)) + 2: (bar(baz)+baz(bop)) + 3: bar(baz)+baz(bop) + +/(A (A|B(*ACCEPT)|C) D)(E)/x + AB + 0: AB + 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 + +/(?:(b))++/ + beetle + 0: b + 1: b + +/(?(?=(a(*ACCEPT)z))a)/ + a + 0: a + 1: a + +/^(a)(?1)+ab/ + aaaab + 0: aaaab + 1: a + +/^(a)(?1)++ab/ + aaaab +No match + +/^(?=a(*:M))aZ/K + aZbc + 0: aZ +MK: M + +/^(?!(*:M)b)aZ/K + aZbc + 0: aZ + +/(?(DEFINE)(a))?b(?1)/ + backgammon + 0: ba + +/^\N+/ + abc\ndef + 0: abc + +/^\N{1,}/ + abc\ndef + 0: abc + +/(?(R)a+|(?R)b)/ + aaaabcde + 0: aaaab + +/(?(R)a+|((?R))b)/ + aaaabcde + 0: aaaab + 1: aaaa + +/((?(R)a+|(?1)b))/ + aaaabcde + 0: aaaab + 1: aaaab + +/((?(R1)a+|(?1)b))/ + aaaabcde + 0: aaaab + 1: aaaab + +/a(*:any +name)/K + abc + 0: a +MK: any \x0aname + +/(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ + a + 0: a + ba + 0: a + bba + 0: a + +/--- Checking revised (*THEN) handling ---/ + +/--- Capture ---/ + +/^.*? (a(*THEN)b) c/x + aabc +No match + +/^.*? (a(*THEN)b|(*F)) c/x + aabc + 0: aabc + 1: ab + +/^.*? ( (a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + 1: ab + 2: ab + +/^.*? ( (a(*THEN)b) ) c/x + aabc +No match + +/--- Non-capture ---/ + +/^.*? (?:a(*THEN)b) c/x + aabc +No match + +/^.*? (?:a(*THEN)b|(*F)) c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b) ) c/x + aabc +No match + +/--- Atomic ---/ + +/^.*? (?>a(*THEN)b) c/x + aabc +No match + +/^.*? (?>a(*THEN)b|(*F)) c/x + aabc + 0: aabc + +/^.*? (?> (?>a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + +/^.*? (?> (?>a(*THEN)b) ) c/x + aabc +No match + +/--- Possessive capture ---/ + +/^.*? (a(*THEN)b)++ c/x + aabc +No match + +/^.*? (a(*THEN)b|(*F))++ c/x + aabc + 0: aabc + 1: ab + +/^.*? ( (a(*THEN)b)++ | (*F) )++ c/x + aabc + 0: aabc + 1: ab + 2: ab + +/^.*? ( (a(*THEN)b)++ )++ c/x + aabc +No match + +/--- Possessive non-capture ---/ + +/^.*? (?:a(*THEN)b)++ c/x + aabc +No match + +/^.*? (?:a(*THEN)b|(*F))++ c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b)++ )++ c/x + aabc +No match + +/--- Condition assertion ---/ + +/^(?(?=a(*THEN)b)ab|ac)/ + ac + 0: ac + +/--- Condition ---/ + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba +No match + +/^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ + ba + 0: ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac +No match + +/--- Assertion ---/ + +/^.*(?=a(*THEN)b)/ + aabc + 0: a + +/------------------------------/ + +/(?>a(*:m))/imsxSK + a + 0: a +MK: m + +/(?>(a)(*:m))/imsxSK + a + 0: a + 1: a +MK: m + +/(?<=a(*ACCEPT)b)c/ + xacd + 0: c + +/(?<=(a(*ACCEPT)b))c/ + xacd + 0: c + 1: a + +/(?<=(a(*COMMIT)b))c/ + xabcd + 0: c + 1: ab + ** Failers +No match + xacd +No match + +/(? + 2: + +/(another)?(\1+)test/ + hello world test +No match + +/(a(*COMMIT)b){0}a(?1)|aac/ + aac + 0: aac + +/(?!a(*COMMIT)b)ac|cd/ + ac + 0: ac + +/((?:a?)*)*c/ + aac + 0: aac + 1: + +/((?>a?)*)*c/ + aac + 0: aac + 1: + /-- End of testinput1 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput10 b/ext/pcre/pcrelib/testdata/testoutput10 index b88474c7ba0..5009d5dfe22 100644 --- a/ext/pcre/pcrelib/testdata/testoutput10 +++ b/ext/pcre/pcrelib/testdata/testoutput10 @@ -1,739 +1,2103 @@ -/-- 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. --/ +/-- This set of tests check Unicode property support with the DFA matching + functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest + when running it. --/ -/((?i)b)/BM -Memory allocation (code space): 21 ------------------------------------------------------------------- - 0 17 Bra - 3 9 CBra 1 - 8 01 Opt - 10 NC b - 12 9 Ket - 15 00 Opt - 17 17 Ket - 20 End ------------------------------------------------------------------- +/\pL\P{Nd}/8 + AB + 0: AB + *** Failers + 0: Fa + A0 +No match + 00 +No match -/(?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 ------------------------------------------------------------------- +/\X./8 + AB + 0: AB + A\x{300}BC + 0: A\x{300}B + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302}B + *** Failers + 0: ** + \x{300} +No match -/(?s:.*X|^B)/BM -Memory allocation (code space): 29 ------------------------------------------------------------------- - 0 25 Bra - 3 9 Bra - 6 04 Opt - 8 AllAny* - 10 X - 12 8 Alt - 15 04 Opt - 17 ^ - 18 B - 20 17 Ket - 23 00 Opt - 25 25 Ket - 28 End ------------------------------------------------------------------- +/\X\X/8 + ABC + 0: AB + A\x{300}B\x{300}\x{301}C + 0: A\x{300}B\x{300}\x{301} + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302}B + *** Failers + 0: ** + \x{300} +No match -/^[[:alnum:]]/BM -Memory allocation (code space): 41 ------------------------------------------------------------------- - 0 37 Bra - 3 ^ - 4 [0-9A-Za-z] - 37 37 Ket - 40 End ------------------------------------------------------------------- +/^\pL+/8 + abcd + 0: abcd + 1: abc + 2: ab + 3: a + a + 0: a + *** Failers +No match -/#/IxMD -Memory allocation (code space): 7 ------------------------------------------------------------------- - 0 3 Bra - 3 3 Ket - 6 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: extended -No first char -No need char +/^\PL+/8 + 1234 + 0: 1234 + 1: 123 + 2: 12 + 3: 1 + = + 0: = + *** Failers + 0: *** + 1: *** + 2: ** + 3: * + abcd +No match -/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+/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} +No match -/x?+/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 x?+ - 5 5 Ket - 8 End ------------------------------------------------------------------- +/\X?abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}abc + \x{300}abc + 0: abc + *** Failers +No match -/x++/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 x++ - 5 5 Ket - 8 End ------------------------------------------------------------------- +/^\X?abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + *** Failers +No match + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz +No match + \x{300}abc +No match -/x{1,3}+/BM -Memory allocation (code space): 19 ------------------------------------------------------------------- - 0 15 Bra - 3 9 Once - 6 x - 8 x{0,2} - 12 9 Ket - 15 15 Ket - 18 End ------------------------------------------------------------------- +/\X*abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc + \x{300}abc + 0: abc + *** Failers +No match -/(x)*+/BM -Memory allocation (code space): 24 ------------------------------------------------------------------- - 0 20 Bra - 3 14 Once - 6 Brazero - 7 7 CBra 1 - 12 x - 14 7 KetRmax - 17 14 Ket - 20 20 Ket - 23 End ------------------------------------------------------------------- +/^\X*abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc + *** Failers +No match + \x{300}abc +No match -/^((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 ------------------------------------------------------------------- +/^\pL?=./8 + A=b + 0: A=b + =c + 0: =c + *** Failers +No match + 1=2 +No match + AAAA=b +No match -|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\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[KDDqmj;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 ------------------------------------------------------------------- +/^\pL*=./8 + AAAA=b + 0: AAAA=b + =c + 0: =c + *** Failers +No match + 1=2 +No match -|\$\<\.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\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[KDDqmj;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 ------------------------------------------------------------------- +/^\X{2,3}X/8 + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + *** Failers +No match + X +No match + A\x{300}\x{301}\x{302}X +No match + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X +No match -/(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 Ket - 19 b - 21 18 Ket - 24 24 Ket - 27 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(?Pb|c)d(?Pe)/BM -Memory allocation (code space): 42 ------------------------------------------------------------------- - 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(?Pc(?Pd)))(?Pa)/BM -Memory allocation (code space): 54 ------------------------------------------------------------------- - 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 ------------------------------------------------------------------- - -/(?Pa)...(?P=a)bbb(?P>a)d/BM -Memory allocation (code space): 43 ------------------------------------------------------------------- - 0 36 Bra - 3 7 CBra 1 - 8 a - 10 7 Ket - 13 Any - 14 Any - 15 Any - 16 \1 - 19 bbb - 25 6 Once - 28 3 Recurse - 31 6 Ket - 34 d - 36 36 Ket - 39 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{1000000}/8BM -Memory allocation (code space): 13 ------------------------------------------------------------------- - 0 9 Bra - 3 \x{1000000} - 9 9 Ket - 12 End ------------------------------------------------------------------- - -/\x{4000000}/8BM -Memory allocation (code space): 14 ------------------------------------------------------------------- - 0 10 Bra - 3 \x{4000000} - 10 10 Ket - 13 End ------------------------------------------------------------------- - -/\x{7fffFFFF}/8BM -Memory allocation (code space): 14 ------------------------------------------------------------------- - 0 10 Bra - 3 \x{7fffffff} - 10 10 Ket - 13 End ------------------------------------------------------------------- - -/[\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): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\x{100}] - 11 11 Ket - 14 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: utf8 -First char = 'A' -Need char = '.' +/^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + ** Failers +No match + \x{0b} +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} + 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 + > \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: > + +/^>\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} + 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} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\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} + 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{Xps}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} + ** Failers +No match + \x{0b} +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} + 0: >\x{1680}\x{2028}\x{0b} + 1: >\x{1680}\x{2028} + 2: >\x{1680} + +/^>\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} + 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}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\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 + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers +No match + [] +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_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers +No match + [] +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 --/ + +/\b...\B/8W + abc_ + 0: abc + \x{37e}abc\x{376} + 0: abc + \x{37e}\x{376}\x{371}\x{393}\x{394} + 0: \x{376}\x{371}\x{393} + !\x{c0}++\x{c1}\x{c2} + 0: ++\x{c1} + !\x{c0}+++++ + 0: \x{c0}++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + 0: abc + ** Failers + 0: Fai + \x{37e}abc\x{376} +No match + \x{37e}\x{376}\x{371}\x{393}\x{394} +No match + !\x{c0}++\x{c1}\x{c2} +No match + !\x{c0}+++++ +No match + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + 0: abc + !\x{c0}++\x{c1}\x{c2} + 0: ++\xc1 + !\x{c0}+++++ + 0: \xc0++ + +/-- Caseless single negated characters > 127 need UCP support --/ + +/[^\x{100}]/8i + \x{100}\x{101}X + 0: X + +/[^\x{100}]+/8i + \x{100}\x{101}XX + 0: XX + 1: X + +/^\X/8 + A\P + 0: A + A\P\P +Partial match: A + A\x{300}\x{301}\P + 0: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{301}\P + 0: A\x{301} + A\x{301}\P\P +Partial match: A\x{301} + +/^\X{2,3}/8 + A\P +Partial match: A + A\P\P +Partial match: A + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} + +/^\X{2}/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +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 + +/^\X+?Z/8 + AA\P +Partial match: AA + AA\P\P +Partial match: AA + +/-- End of testinput10 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput2 b/ext/pcre/pcrelib/testdata/testoutput2 index 531d617f007..77b108c8094 100644 --- a/ext/pcre/pcrelib/testdata/testoutput2 +++ b/ext/pcre/pcrelib/testdata/testoutput2 @@ -3,12 +3,11 @@ It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl - bug. --/ + bug. + + 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. --/ -/-- Originally, the Perl >= 5.10 things were in here too, but now I have - separated many (most?) of them out into test 11. However, there may still - be some that were overlooked. --/ - /(a)b|/I Capturing subpattern count = 1 No options @@ -377,61 +376,6 @@ No need char 2: 3: def -/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 - /)/ Failed: unmatched parentheses at offset 0 @@ -507,6 +451,7 @@ Capturing subpattern count = 0 No options First char = 'f' Need char = 'o' +Max lookbehind = 6 foo 0: foo catfoo @@ -632,10 +577,8 @@ Need char = 'h' (caseless) ------------------------------------------------------------------ Bra CBra 1 - 01 Opt - NC b + /i b Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -716,6 +659,7 @@ Capturing subpattern count = 0 No options No first char No need char +Max lookbehind = 3 Subject length lower bound = 1 Starting byte set: a b @@ -724,6 +668,7 @@ Capturing subpattern count = 1 No options No first char Need char = 'a' +Max lookbehind = 3 Subject length lower bound = 5 Starting byte set: a o @@ -741,6 +686,7 @@ Contains explicit CR or LF match Options: multiline No first char Need char = 'r' +Max lookbehind = 4 foo\nbarbar 0: bar ***Failers @@ -758,6 +704,7 @@ 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 @@ -799,6 +746,7 @@ Capturing subpattern count = 0 No options First char = '-' Need char = 't' +Max lookbehind = 7 the bullock-cart 0: -cart a donkey-cart race @@ -815,12 +763,14 @@ Capturing subpattern count = 0 No options No first char No need char +Max lookbehind = 3 /(?>.*)(?<=(abcd)|(xyz))/I Capturing subpattern count = 2 No options First char at start or follows newline No need char +Max lookbehind = 4 alphabetabcd 0: alphabetabcd 1: abcd @@ -834,6 +784,7 @@ Capturing subpattern count = 0 No options First char = 'Z' Need char = 'Z' +Max lookbehind = 4 abxyZZ 0: ZZ abXyZZ @@ -862,6 +813,7 @@ Capturing subpattern count = 1 No options First char = 'b' Need char = 'r' +Max lookbehind = 4 bar 0: bar foobbar @@ -1033,9 +985,6 @@ Failed: numbers out of order in {} quantifier at offset 7 /abc/\ Failed: \ at end of pattern at offset 4 -/abc/\P -Failed: POSIX code 9: bad escape sequence at offset 4 - /abc/\i Failed: \ at end of pattern at offset 4 @@ -1151,7 +1100,7 @@ No first char No need char abc\00def\L\C0 0: abc\x00def - 0C abc (7) + 0C abc\x00def (7) 0L abc /word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ @@ -1247,15 +1196,12 @@ No need char ------------------------------------------------------------------ Bra Bra - 04 Opt AllAny* X Alt - 04 Opt ^ B Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -1269,11 +1215,7 @@ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' - Mississippi - 0: iss - 0+ issippi - -/\Biss\B/I+P +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1294,6 +1236,7 @@ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1303,6 +1246,7 @@ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1318,6 +1262,7 @@ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1329,6 +1274,7 @@ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1407,7 +1353,7 @@ Capturing subpattern count = 0 Contains explicit CR or LF match Options: multiline First char at start or follows newline -Need char = 10 +Need char = \x0a ab\nab\ncd 0: ab\x0a 0+ ab\x0acd @@ -1509,6 +1455,7 @@ Capturing subpattern count = 0 No options No first char No need char +Max lookbehind = 3 /abc(?!pqr)/I Capturing subpattern count = 0 @@ -1694,33 +1641,6 @@ No need char \Nabc No match -/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 - /^.?abcd/IS Capturing subpattern count = 0 Options: anchored @@ -2764,8 +2684,7 @@ No need char ------------------------------------------------------------------ Bra a - 01 Opt - NC b + /i b Ket End ------------------------------------------------------------------ @@ -2787,10 +2706,8 @@ No match Bra CBra 1 a - 01 Opt - NC b + /i b Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -2812,7 +2729,7 @@ No match / (?i)abc/IxDZ ------------------------------------------------------------------ Bra - NC abc + /i abc Ket End ------------------------------------------------------------------ @@ -2825,7 +2742,7 @@ Need char = 'c' (caseless) (?i)abc/IxDZ ------------------------------------------------------------------ Bra - NC abc + /i abc Ket End ------------------------------------------------------------------ @@ -2998,12 +2915,10 @@ No need char /(x)*+/DZ ------------------------------------------------------------------ Bra - Once - Brazero - CBra 1 + Braposzero + CBraPos 1 x - KetRmax - Ket + KetRpos Ket End ------------------------------------------------------------------ @@ -3321,6 +3236,7 @@ Capturing subpattern count = 0 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\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 ------------------------------------------------------------------ @@ -3334,6 +3250,7 @@ Capturing subpattern count = 0 No options First char = '$' Need char = 'X' +Max lookbehind = 1 /(.*)\d+\1/I Capturing subpattern count = 1 @@ -3590,7 +3507,27 @@ Need char = 'f' 1 ^ ^ f 0: abcdef -/(?C1)\dabc(?C2)def/I +/(?C1)\dabc(?C2)def/IS +Capturing subpattern count = 0 +No options +No first char +Need char = 'f' +Subject length lower bound = 7 +Starting byte set: 0 1 2 3 4 5 6 7 8 9 + 1234abcdef +--->1234abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 2 ^ ^ d + 0: 4abcdef + *** Failers +No match + abcdef +No match + +/(?C1)\dabc(?C2)def/ISS Capturing subpattern count = 0 No options No first char @@ -3829,6 +3766,7 @@ Capturing subpattern count = 1 No options First char = 'x' Need char = 'z' +Max lookbehind = 3 abcxyz\C+ Callout 0: last capture = 1 0: @@ -3994,9 +3932,7 @@ Need char = '<' Bra CBra 1 a - Once Recurse - Ket b Ket Ket @@ -4217,9 +4153,7 @@ Need char = 'a' Any \1 bbb - Once Recurse - Ket d Ket End @@ -4591,9 +4525,7 @@ Need char = ']' a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4613,9 +4545,7 @@ No need char a CBra 2 b - Once Recurse - Ket c Ket KetRmax @@ -4636,9 +4566,7 @@ No need char a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4647,9 +4575,7 @@ No need char a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4788,7 +4714,51 @@ Need char = 'e' +4 ^ ^ e No match -/a*b/ICDZ +/a*b/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 2 + a*+ + Callout 255 2 1 + b + Callout 255 3 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +No first char +Need char = 'b' +Subject length lower bound = 1 +Starting byte set: a b + ab +--->ab + +0 ^ a* + +2 ^^ b + +3 ^ ^ + 0: ab + aaaab +--->aaaab + +0 ^ a* + +2 ^ ^ b + +3 ^ ^ + 0: aaaab + aaaacb +--->aaaacb + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^^ b + +0 ^ a* + +2 ^ b + +3 ^^ + 0: b + +/a*b/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 2 @@ -4871,7 +4841,83 @@ Need char = 'b' +2 ^^ b No match -/(abc|def)x/ICDZ +/(abc|def)x/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 9 + CBra 1 + Callout 255 1 1 + a + Callout 255 2 1 + b + Callout 255 3 1 + c + Callout 255 4 0 + Alt + Callout 255 5 1 + d + Callout 255 6 1 + e + Callout 255 7 1 + f + Callout 255 8 0 + Ket + Callout 255 9 1 + x + Callout 255 10 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: a d + abcx +--->abcx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x ++10 ^ ^ + 0: abcx + 1: abc + defx +--->defx + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x ++10 ^ ^ + 0: defx + 1: def + ** Failers +No match + abcdefzx +--->abcdefzx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x +No match + +/(abc|def)x/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 9 @@ -4925,6 +4971,8 @@ Need char = 'x' +10 ^ ^ 0: defx 1: def + ** Failers +No match abcdefzx --->abcdefzx +0 ^ (abc|def) @@ -5025,7 +5073,58 @@ No need char 0: abcdcdcd 1: cd -/([ab]{,4}c|xy)/ICDZ +/([ab]{,4}c|xy)/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 14 + CBra 1 + Callout 255 1 4 + [ab] + Callout 255 5 1 + { + Callout 255 6 1 + , + Callout 255 7 1 + 4 + Callout 255 8 1 + } + Callout 255 9 1 + c + Callout 255 10 0 + Alt + Callout 255 11 1 + x + Callout 255 12 1 + y + Callout 255 13 0 + Ket + Callout 255 14 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b x + Note: that { does NOT introduce a quantifier +--->Note: that { does NOT introduce a quantifier + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x +No match + +/([ab]{,4}c|xy)/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 14 @@ -5315,6 +5414,7 @@ Capturing subpattern count = 0 No options No first char No need char +Max lookbehind = 1 ab cd\>1 0: cd @@ -5323,6 +5423,7 @@ Capturing subpattern count = 0 Options: dotall No first char No need char +Max lookbehind = 1 ab cd\>1 0: cd @@ -5477,14 +5578,33 @@ No match 123456\P No match -/abc/I>testsavedregex +/abc/IS>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' -Compiled regex written to testsavedregex +Subject length lower bound = 3 +No set of starting bytes +Compiled pattern written to testsavedregex +Study data written to testsavedregex testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Compiled pattern written to testsavedregex +testsavedregex +/abc/IFS>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' -Compiled regex written to testsavedregex +Subject length lower bound = 3 +No set of starting bytes +Compiled pattern written to testsavedregex +Study data written to testsavedregex testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Compiled pattern written to testsavedregex +testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Compiled pattern written to testsavedregex +testsavedregex Capturing subpattern count = 1 No options @@ -5537,10 +5694,10 @@ No first char No need char Subject length lower bound = 1 Starting byte set: a b -Compiled regex written to testsavedregex +Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Compiled pattern written to testsavedregex +(.)*~smgI Capturing subpattern count = 3 Max back reference = 1 Options: multiline dotall First char = '<' Need char = '>' - \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n 0: \x0a\x0aPartner der LCO\x0ade\x0aPartner der LINEAS Consulting\x0aGmbH\x0aLINEAS Consulting GmbH Hamburg\x0aPartnerfirmen\x0a30 days\x0aindex,follow\x0a\x0aja\x0a3\x0aPartner\x0a\x0a\x0aLCO\x0aLINEAS Consulting\x0a15.10.2003\x0a\x0a\x0a\x0a\x0aDie Partnerfirmen der LINEAS Consulting\x0aGmbH\x0a\x0a\x0a \x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a 1: seite 2: \x0a @@ -5606,24 +5781,6 @@ No match line one\nthis is a line\nbreak in the second line No match -/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 - /(?i)(?-i)AbCd/I Capturing subpattern count = 0 No options @@ -5916,21 +6073,10 @@ No need char ((this)) 0: ((this)) -/a(b)c/PN - abc -Matched with REG_NOSUB - -/a(?Pb)c/PN - abc -Matched with REG_NOSUB - -/\x{100}/I -Failed: character value in \x{...} sequence is too large at offset 6 - /\x{0000ff}/I Capturing subpattern count = 0 No options -First char = 255 +First char = \xff No need char /^((?Pa1)|(?Pa2)b)/I @@ -6040,7 +6186,7 @@ no parentheses with name "Z" 0: a1 1: a1 2: a1 -copy substring Z failed -7 +get substring Z failed -7 G a1 (2) A /^(?Pa)(?Pb)/IJ @@ -6072,7 +6218,7 @@ No need char G a (1) A cd\GA 0: cd -copy substring A failed -7 +get substring A failed -7 /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ Capturing subpattern count = 4 @@ -6240,9 +6386,6 @@ No need char 9: 10: Y -/\777/I -Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3 - /\s*,\s*/IS Capturing subpattern count = 0 No options @@ -6674,8 +6817,8 @@ No match ------------------------------------------------------------------ Bra ^ - a* - NC A + /i a* + /i A \d Ket End @@ -7303,8 +7446,8 @@ Matched, but too many substrings /[^a]+a/BZi ------------------------------------------------------------------ Bra - [^A]++ - NC a + /i [^a]++ + /i a Ket End ------------------------------------------------------------------ @@ -7312,8 +7455,8 @@ Matched, but too many substrings /[^a]+A/BZi ------------------------------------------------------------------ Bra - [^A]++ - NC A + /i [^a]++ + /i A Ket End ------------------------------------------------------------------ @@ -7508,9 +7651,7 @@ No match ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket [()] CBra 1 Ket @@ -7544,9 +7685,7 @@ No match ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket () CBra 1 Ket @@ -7558,9 +7697,7 @@ No match ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket [(\]a] CBra 1 Ket @@ -7573,9 +7710,7 @@ No match ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket CBra 1 Ket Ket @@ -7707,9 +7842,6 @@ Options: extended First char = 'x' Need char = 'z' -/(?(DEFINE) abc){3} xyz/x -Failed: repeating a DEFINE group is not allowed at offset 17 - /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match @@ -8027,10 +8159,8 @@ No match Alt c Ket - Once Recurse Ket - Ket End ------------------------------------------------------------------ abc @@ -8041,9 +8171,7 @@ No match ------------------------------------------------------------------ Bra xy - Once Recurse - Ket CBra 1 abc Ket @@ -8273,66 +8401,6 @@ Failed: syntax error in subpattern name (missing terminator) at offset 4 3: 4: x -/[\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 ------------------------------------------------------------------- - /\H++X/BZ ------------------------------------------------------------------ Bra @@ -8524,7 +8592,7 @@ No match ------------------------------------------------------------------ /\( (?: [^()]* | (?R) )* \)/x -(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) +\J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) 0: (0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ @@ -8706,8 +8774,13 @@ Failed: number is too big at offset 19 /\g6666666666/ Failed: number is too big at offset 11 -/[\g6666666666]/ -Failed: number is too big at offset 12 +/[\g6666666666]/BZ +------------------------------------------------------------------ + Bra + [6g] + Ket + End +------------------------------------------------------------------ /(?1)\c[/ Failed: reference to non-existent subpattern at offset 3 @@ -9013,6 +9086,12 @@ Failed: subpattern name expected at offset 3 /\k{}/ Failed: subpattern name expected at offset 3 +/\k/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2 + +/\kabc/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5 + /(?P=)/ Failed: subpattern name expected at offset 4 @@ -9234,14 +9313,6 @@ No options First char at start or follows newline No need char -/a?|b?/P - abc - 0: a - ** Failers - 0: - ddd\N -No match: POSIX code 17: match failed - /xyz/C xyz --->xyz @@ -9636,14 +9707,6 @@ Partial match: the cat abc\P\P 0: abc -/\w+A/P - CDAAAAB - 0: CDAAAA - -/\w+A/PU - CDAAAAB - 0: CDA - /abc\K123/ xyzabc123pqr 0: 123 @@ -9671,12 +9734,8 @@ Partial match: +ab /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra - Once Recurse - Ket - Once Recurse - Ket Cond Cond def CBra 1 @@ -9697,12 +9756,8 @@ Partial match: +ab /(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra - Once Recurse - Ket - Once Recurse - Ket Cond Cond def CBra 1 @@ -10044,210 +10099,6 @@ Need char = ':' Subject length lower bound = 22 No set of starting bytes -/ (?: [\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 - /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS Capturing subpattern count = 11 Options: caseless dotall @@ -10443,12 +10294,10 @@ No match Cond nrecurse 1 $ Alt - Once Recurse Ket Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 4 @@ -10586,11 +10435,9 @@ Starting byte set: i /(?i)a(?-i)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 00 Opt + /i a b Alt - 00 Opt c Ket End @@ -10609,12 +10456,9 @@ No match /(?i)a(?s)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 05 Opt - NC b + /i ab Alt - 05 Opt - NC c + /i c Ket End ------------------------------------------------------------------ @@ -10622,11 +10466,9 @@ No match /(?i)a(?s-i)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 04 Opt + /i a b Alt - 04 Opt c Ket End @@ -10673,12 +10515,10 @@ No match ------------------------------------------------------------------ Bra ^ - Once - Brazero - Once + Braposzero + SBraPos Recurse - KetRmax - Ket + KetRpos Cond Cond def CBra 1 @@ -10767,152 +10607,22 @@ No match AC No match -/--- A whole lot of tests of verbs with arguments are here rather than in test - 11 because Perl doesn't seem to follow its specification entirely - correctly. ---/ - -/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is - not clear how Perl defines "involved in the failure of the match". ---/ - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match - CB -No match, mark = B - -/--- Check the use of names for success and failure. PCRE doesn't show these -names for success, though Perl does, contrary to its spec. ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match, mark = A - CB -No match, mark = B - -/--- An empty name does not pass back an empty string. It is the same as if no -name were given. ---/ - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - -/--- PRUNE goes to next bumpalong; COMMIT does not. ---/ - -/A(*PRUNE:A)B/K - ACAB - 0: AB - -/(*MARK:A)(*PRUNE:B)(C|X)/K - C - 0: C - 1: C -MK: A - D -No match, mark = B - -/(*MARK:A)(*THEN:B)(C|X)/K - C - 0: C - 1: C -MK: A - D -No match, mark = B - -/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/ - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK - AAAC -No match - -/--- Same --/ - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK - AAAC -No match - /--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. ---/ + PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC -No match +No match, mark = A -/A(*:A)A+(*SKIP)(B|Z) | AC/xK - AAAC -No match +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ -/--- This should fail, as a null name is the same as no name ---/ - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK - AAAC -No match - -/--- This fails in PCRE, and I think that is in accordance with Perl's - documentation, though in Perl it succeeds. ---/ - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK - AAAC -No match - -/--- Mark names can be duplicated ---/ - -/A(*:A)B|X(*:A)Y/K - AABC - 0: AB -MK: A - XXYZ - 0: XY -MK: A - /^A(*:A)B|^X(*:A)Y/K ** Failers No match XAQQ No match, mark = A -/--- A check on what happens after hitting a mark and them bumping along to -something that does not even start. Perl reports tags after the failures here, -though it does not when the individual letters are made into something -more complicated. ---/ - -/A(*:A)B|XX(*:B)Y/K - AABC - 0: AB -MK: A - XXYZ - 0: XXY -MK: B - ** Failers -No match - XAQQ -No match - XAQQXZZ -No match - AXQQQ -No match - AXXQQQ -No match - /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ @@ -10925,126 +10635,6 @@ No match DEFGABC\Y No match -/--- Repeat some tests with added studying. ---/ - -/A(*COMMIT)B/+KS - ACABX -No match - -/A(*THEN)B|A(*THEN)C/KS - AC - 0: AC - -/A(*PRUNE)B|A(*PRUNE)C/KS - AC -No match - -/^(A(*THEN:A)B|C(*THEN:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match - CB -No match, mark = B - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match, mark = A - CB -No match, mark = B - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - -/A(*PRUNE:A)B/KS - ACAB - 0: AB - -/(*MARK:A)(*PRUNE:B)(C|X)/KS - C - 0: C - 1: C -MK: A - D -No match - -/(*MARK:A)(*THEN:B)(C|X)/KS - C - 0: C - 1: C -MK: A - D -No match - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS - AAAC -No match - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS - AAAC -No match - -/A(*:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS - AAAC -No match - -/A(*:A)B|XX(*:B)Y/KS - AABC - 0: AB -MK: A - XXYZ - 0: XXY -MK: B - ** Failers -No match - XAQQ -No match - XAQQXZZ -No match - AXQQQ -No match - AXXQQQ -No match - -/(*COMMIT)ABC/ - ABCDEFG - 0: ABC - ** Failers -No match - DEFGABC\Y -No match - /^(ab (c+(*THEN)cd) | xyz)/x abcccd No match @@ -11165,11 +10755,76 @@ No match /\s*\R/BZ ------------------------------------------------------------------ Bra - \s*+ + \s* \R Ket End ------------------------------------------------------------------ + \x20\x0a + 0: \x0a + \x20\x0d + 0: \x0d + \x20\x0d\x0a + 0: \x0d\x0a + +/\S*\R/BZ +------------------------------------------------------------------ + Bra + \S*+ + \R + Ket + End +------------------------------------------------------------------ + a\x0a + 0: a\x0a + +/X\h*\R/BZ +------------------------------------------------------------------ + Bra + X + \h*+ + \R + Ket + End +------------------------------------------------------------------ + X\x20\x0a + 0: X \x0a + +/X\H*\R/BZ +------------------------------------------------------------------ + Bra + X + \H* + \R + Ket + End +------------------------------------------------------------------ + X\x0d\x0a + 0: X\x0d\x0a + +/X\H+\R/BZ +------------------------------------------------------------------ + Bra + X + \H+ + \R + Ket + End +------------------------------------------------------------------ + X\x0d\x0a + 0: X\x0d\x0a + +/X\H++\R/BZ +------------------------------------------------------------------ + Bra + X + \H++ + \R + Ket + End +------------------------------------------------------------------ + X\x0d\x0a +No match /-- Perl treats this one differently, not failing the second string. I believe that is a bug in Perl. --/ @@ -11251,9 +10906,9 @@ Partial match: abc abc\>3 No match abc\>4 -Error -24 +Error -24 (bad offset value) abc\>-4 -Error -24 +Error -24 (bad offset value) /^\cÄ£/ Failed: \c must be followed by an ASCII character at offset 3 @@ -11305,4 +10960,1405 @@ Failed: reference to non-existent subpattern at offset 15 End ------------------------------------------------------------------ +/-- These tests are here because Perl gets the first one wrong. --/ + +/(\R*)(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + +/(\R)*(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0a + 2: \x0d + +/((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + +/-- --/ + +/^abc$/BZ +------------------------------------------------------------------ + Bra + ^ + abc + $ + Ket + End +------------------------------------------------------------------ + +/^abc$/BZm +------------------------------------------------------------------ + Bra + /m ^ + abc + /m $ + Ket + End +------------------------------------------------------------------ + +/^(a)*+(\w)/S + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaaa +No match + +/^(?:a)*+(\w)/S + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaaa +No match + +/(a)++1234/SDZ +------------------------------------------------------------------ + Bra + CBraPos 1 + a + KetRpos + 1234 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = '4' +Subject length lower bound = 5 +No set of starting bytes + +/([abc])++1234/SI +Capturing subpattern count = 1 +No options +No first char +Need char = '4' +Subject length lower bound = 5 +Starting byte set: a b c + +/(?<=(abc)+)X/ +Failed: lookbehind assertion is not fixed length at offset 10 + +/(^ab)/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab)++/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab|^)+/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab|^)++/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(?:^ab)/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab)++/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab|^)+/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab|^)++/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(.*ab)/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +Need char = 'b' + +/(.*ab)++/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +Need char = 'b' + +/(.*ab|.*)+/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(.*ab|.*)++/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(?:.*ab)/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/(?:.*ab)++/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/(?:.*ab|.*)+/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +No need char + +/(?:.*ab|.*)++/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +No need char + +/(?=a)[bcd]/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/((?=a))[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/((?=a))+[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/((?=a))++[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(?=a+)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a+?)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a++)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a{3})[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +Need char = 'a' (caseless) + +/(abc)\1+/S + +/-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ + +/(?1)(?:(b(*ACCEPT))){0}/ + b + 0: b + +/(?1)(?:(b(*ACCEPT))){0}c/ + bc + 0: bc + ** Failers +No match + b +No match + +/(?1)(?:((*ACCEPT))){0}c/ + c + 0: c + c\N + 0: c + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba +No match + +/^.*?(?(?=a)a|bc)/ + ba + 0: ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac +No match + +/^.*?(?(?=a)a(*THEN)b)c/ + ac +No match + +/^.*?(a(*THEN)b)c/ + aabc +No match + +/^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x + aabc + 0: aabc + +/^.*?(a(*THEN)b|z)c/ + aabc + 0: aabc + 1: ab + +/^.*?(z|a(*THEN)b)c/ + aabc + 0: aabc + 1: ab + +/-- --/ + +/-- These studied versions are here because they are not Perl-compatible; the + studying means the mark is not seen. --/ + +/(*MARK:A)(*SKIP:B)(C|X)/KS + C + 0: C + 1: C +MK: A + D +No match, mark = A + +/(*:A)A+(*SKIP:A)(B|Z)/KS + AAAC +No match, mark = A + +/-- --/ + +"(?=a*(*ACCEPT)b)c" + c + 0: c + c\N + 0: c + +/(?1)c(?(DEFINE)((*ACCEPT)b))/ + c + 0: c + c\N + 0: c + +/(?>(*ACCEPT)b)c/ + c + 0: + c\N +No match + +/(?:(?>(a)))+a%/++ + %aa% + 0: aa% + 0+ + 1: a + 1+ a% + +/(a)b|ac/++SS + ac\O3 +Matched, but too many substrings + 0: ac + 0+ + +/(a)(b)x|abc/++ + abc\O6 + 0: abc + 0+ + +/(a)bc|(a)(b)\2/ + \O3abc +Matched, but too many substrings + 0: abc + \O4abc +Matched, but too many substrings + 0: abc + +/(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a b + +/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 4 +Starting byte set: a b + +/(abc)(?1)/SI +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'c' +Subject length lower bound = 6 +No set of starting bytes + +/^(?>a)++/ + aa\M +Minimum match() limit = 5 +Minimum match() recursion limit = 2 + 0: aa + aaaaaaaaa\M +Minimum match() limit = 12 +Minimum match() recursion limit = 2 + 0: aaaaaaaaa + +/(a)(?1)++/ + aa\M +Minimum match() limit = 7 +Minimum match() recursion limit = 4 + 0: aa + 1: a + aaaaaaaaa\M +Minimum match() limit = 21 +Minimum match() recursion limit = 4 + 0: aaaaaaaaa + 1: a + +/(?:(foo)|(bar)|(baz))X/SS= + bazfooX + 0: fooX + 1: foo + 2: + 3: + foobazbarX + 0: barX + 1: + 2: bar + 3: + barfooX + 0: fooX + 1: foo + 2: + 3: + bazX + 0: bazX + 1: + 2: + 3: baz + foobarbazX + 0: bazX + 1: + 2: + 3: baz + bazfooX\O0 +Matched, but too many substrings + bazfooX\O2 +Matched, but too many substrings + 0: fooX + bazfooX\O4 +Matched, but too many substrings + 0: fooX + 1: + bazfooX\O6 +Matched, but too many substrings + 0: fooX + 1: foo + 2: + bazfooX\O8 +Matched, but too many substrings + 0: fooX + 1: foo + 2: + 3: + bazfooX\O10 + 0: fooX + 1: foo + 2: + 3: + +/(?=abc){3}abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc)+abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc)++abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc){0}xyz/BZ +------------------------------------------------------------------ + Bra + Skip zero + Assert + abc + Ket + xyz + Ket + End +------------------------------------------------------------------ + +/(?=(a))?./BZ +------------------------------------------------------------------ + Bra + Brazero + Assert + CBra 1 + a + Ket + Ket + Any + Ket + End +------------------------------------------------------------------ + +/(?=(a))??./BZ +------------------------------------------------------------------ + Bra + Braminzero + Assert + CBra 1 + a + Ket + Ket + Any + Ket + End +------------------------------------------------------------------ + +/^(?=(a)){0}b(?1)/BZ +------------------------------------------------------------------ + Bra + ^ + Skip zero + Assert + CBra 1 + a + Ket + Ket + b + Recurse + Ket + End +------------------------------------------------------------------ + +/(?(DEFINE)(a))?b(?1)/BZ +------------------------------------------------------------------ + Bra + Cond + Cond def + CBra 1 + a + Ket + Ket + b + Recurse + Ket + End +------------------------------------------------------------------ + +/^(?=(?1))?[az]([abc])d/BZ +------------------------------------------------------------------ + Bra + ^ + Brazero + Assert + Recurse + Ket + [az] + CBra 1 + [a-c] + Ket + d + Ket + End +------------------------------------------------------------------ + +/^(?!a){0}\w+/BZ +------------------------------------------------------------------ + Bra + ^ + Skip zero + Assert not + a + Ket + \w+ + Ket + End +------------------------------------------------------------------ + +/(?<=(abc))?xyz/BZ +------------------------------------------------------------------ + Bra + Brazero + AssertB + Reverse + CBra 1 + abc + Ket + Ket + xyz + Ket + End +------------------------------------------------------------------ + +/[:a[:abc]b:]/BZ +------------------------------------------------------------------ + Bra + [:[a-c] + b:] + Ket + End +------------------------------------------------------------------ + +/((?2))((?1))/SS + abc +Error -26 (nested recursion at the same subject position) + +/((?(R2)a+|(?1)b))/SS + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(?(R)a*(?1)|((?R))b)/SS + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(a+|(?R)b)/ +Failed: recursive call could loop indefinitely at offset 7 + +/^(a(*:A)(d|e(*:B))z|aeq)/C + adz +--->adz + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++10 ^ ^ | ++18 ^ ^ z ++19 ^ ^ | ++24 ^ ^ + 0: adz + 1: adz + 2: d + aez +--->aez + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++11 ^^ e ++12 ^ ^ (*:B) ++17 ^ ^ ) +Latest Mark: B ++18 ^ ^ z ++19 ^ ^ | ++24 ^ ^ + 0: aez + 1: aez + 2: e + aeqwerty +--->aeqwerty + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++11 ^^ e ++12 ^ ^ (*:B) ++17 ^ ^ ) +Latest Mark: B ++18 ^ ^ z ++20 ^ a ++21 ^^ e ++22 ^ ^ q ++23 ^ ^ ) ++24 ^ ^ + 0: aeq + 1: aeq + +/.(*F)/ + \P\Pabc +No match + +/\btype\b\W*?\btext\b\W*?\bjavascript\b/IS +Capturing subpattern count = 0 +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:|a+)(?>(z+))\w/BZ +------------------------------------------------------------------ + Bra + ^ + Once_NC + a+ + Ket + Once + CBra 1 + z+ + Ket + Ket + \w + Ket + End +------------------------------------------------------------------ + aaaazzzzb + 0: aaaazzzzb + 1: zzzz + ** Failers +No match + aazz +No match + +/(.)(\1|a(?2))/ + bab + 0: bab + 1: b + 2: ab + +/\1|(.)(?R)\1/ + cbbbc + 0: cbbbc + 1: c + +/(.)((?(1)c|a)|a(?2))/ + baa +No match + +/(?P(?P=abn)xxx)/BZ +------------------------------------------------------------------ + Bra + Once + CBra 1 + \1 + xxx + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/(a\1z)/BZ +------------------------------------------------------------------ + Bra + Once + CBra 1 + a + \1 + z + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + \Maabbccddee +Minimum match() limit = 12 +Minimum match() recursion limit = 3 + 0: aabbccddee + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + \Maabbccddee +Minimum match() limit = 22 +Minimum match() recursion limit = 21 + 0: aabbccddee + 1: aa + 2: bb + 3: cc + 4: dd + 5: ee + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + \Maabbccddee +Minimum match() limit = 18 +Minimum match() recursion limit = 13 + 0: aabbccddee + 1: aa + 2: cc + 3: ee + +/^a\x41z/ + aAz + 0: aAz + *** Failers +No match + ax41z +No match + +/^a[m\x41]z/ + aAz + 0: aAz + +/^a\x1z/ + ax1z + 0: ax1z + +/^a\u0041z/ + aAz + 0: aAz + *** Failers +No match + au0041z +No match + +/^a[m\u0041]z/ + aAz + 0: aAz + +/^a\u041z/ + au041z + 0: au041z + *** Failers +No match + aAz +No match + +/^a\U0041z/ + aU0041z + 0: aU0041z + *** Failers +No match + aAz +No match + +/(?(?=c)c|d)++Y/BZ +------------------------------------------------------------------ + Bra + BraPos + Cond + Assert + c + Ket + c + Alt + d + Ket + KetRpos + Y + Ket + End +------------------------------------------------------------------ + +/(?(?=c)c|d)*+Y/BZ +------------------------------------------------------------------ + Bra + Braposzero + BraPos + Cond + Assert + c + Ket + c + Alt + d + Ket + KetRpos + Y + Ket + End +------------------------------------------------------------------ + +/a[\NB]c/ +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 + +/(a)(?2){0,1999}?(b)/ + +/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ + +/--- This test, with something more complicated than individual letters, causes +different behaviour in Perl. Perhaps it disables some optimization; no tag is +passed back for the failures, whereas in PCRE there is a tag. ---/ + +/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK + AABC + 0: AB + 1: A + 2: B +MK: A + XXYZ + 0: XXY + 1: + 2: + 3: X + 4: X + 5: Y +MK: B + ** Failers +No match + XAQQ +No match, mark = A + XAQQXZZ +No match, mark = A + AXQQQ +No match, mark = A + AXXQQQ +No match, mark = B + +/-- Perl doesn't give marks for these, though it does if the alternatives are +replaced by single letters. --/ + +/(b|q)(*:m)f|a(*:n)w/K + aw + 0: aw +MK: n + ** Failers +No match, mark = n + abc +No match, mark = m + +/(q|b)(*:m)f|a(*:n)w/K + aw + 0: aw +MK: n + ** Failers +No match, mark = n + abc +No match, mark = m + +/-- After a partial match, the behaviour is as for a failure. --/ + +/^a(*:X)bcde/K + abc\P +Partial match, mark=X: abc + +/-- These are here because Perl doesn't return a mark, except for the first --/ + +/(?=(*:x))(q|)/K+ + abc + 0: + 0+ abc + 1: +MK: x + +/(?=(*:x))((*:y)q|)/K+ + abc + 0: + 0+ abc + 1: +MK: x + +/(?=(*:x))(?:(*:y)q|)/K+ + abc + 0: + 0+ abc +MK: x + +/(?=(*:x))(?>(*:y)q|)/K+ + abc + 0: + 0+ abc +MK: x + +/(?=a(*:x))(?!a(*:y)c)/K+ + ab + 0: + 0+ ab +MK: x + +/(?=a(*:x))(?=a(*:y)c|)/K+ + ab + 0: + 0+ ab +MK: x + +/(..)\1/ + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P + 0: abab + 1: ab + +/(..)\1/i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P + 0: aBAb + 1: aB + +/(..)\1{2,}/ + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P +Partial match: abab + ababa\P +Partial match: ababa + ababab\P + 0: ababab + 1: ab + ababab\P\P +Partial match: ababab + abababa\P + 0: ababab + 1: ab + abababa\P\P +Partial match: abababa + +/(..)\1{2,}/i + ab\P +Partial match: ab + aBa\P +Partial match: aBa + aBAb\P +Partial match: aBAb + AbaBA\P +Partial match: AbaBA + abABAb\P + 0: abABAb + 1: ab + aBAbaB\P\P +Partial match: aBAbaB + abABabA\P + 0: abABab + 1: ab + abaBABa\P\P +Partial match: abaBABa + +/(..)\1{2,}?x/i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P +Partial match: aBAb + abaBA\P +Partial match: abaBA + abAbaB\P +Partial match: abAbaB + abaBabA\P +Partial match: abaBabA + abAbABaBx\P + 0: abAbABaBx + 1: ab + +/^(..)\1/ + aba\P +Partial match: aba + +/^(..)\1{2,3}x/ + aba\P +Partial match: aba + ababa\P +Partial match: ababa + ababa\P\P +Partial match: ababa + abababx + 0: abababx + 1: ab + ababababx + 0: ababababx + 1: ab + +/^(..)\1{2,3}?x/ + aba\P +Partial match: aba + ababa\P +Partial match: ababa + ababa\P\P +Partial match: ababa + abababx + 0: abababx + 1: ab + ababababx + 0: ababababx + 1: ab + +/^(..)(\1{2,3})ab/ + abababab + 0: abababab + 1: ab + 2: abab + +/^\R/ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/^\R{2,3}x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R{2,3}?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + x + 0: x + \rx + 0: \x0dx + +/^\R+x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\n\P +Partial match: \x0d\x0a + \r\n\P\P +Partial match: \x0d\x0a + \rx + 0: \x0dx + +/^a$/ + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^a$/m + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/ + a\r\P + 0: a\x0d + 1: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/m + a\r\P + 0: a\x0d + 1: a\x0d + a\r\P\P +Partial match: a\x0d + +/./ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/.{2,3}/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/.{2,3}?/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \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: + 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 + /-- End of testinput2 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput4 b/ext/pcre/pcrelib/testdata/testoutput4 index 4591026d404..2082721c563 100644 --- a/ext/pcre/pcrelib/testdata/testoutput4 +++ b/ext/pcre/pcrelib/testdata/testoutput4 @@ -1,5 +1,6 @@ -/-- This set of tests if for UTF-8 support, excluding Unicode properties. It is - compatible with all versions of Perl 5. --/ +/-- 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. --/ /a.b/8 acb @@ -255,46 +256,6 @@ No match XYZ No match -/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]+/8g bcd 0: bcd @@ -791,22 +752,6 @@ No match \x{200}X No match -/a\Cb/ - aXb - 0: aXb - a\nb - 0: a\x0ab - -/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 - /[z-\x{100}]/8i z 0: z @@ -1128,4 +1073,22 @@ No match 0: AA 0: +/(abc)\1/8i + abc +No match + +/(abc)\1/8 + abc +No match + +/a(*:a\x{1234}b)/8K + abc + 0: a +MK: a\x{1234}b + +/a(*:a£b)/8K + abc + 0: a +MK: a\x{a3}b + /-- End of testinput4 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput5 b/ext/pcre/pcrelib/testdata/testoutput5 index b3ce48a0dd8..c4f9a0c9a71 100644 --- a/ext/pcre/pcrelib/testdata/testoutput5 +++ b/ext/pcre/pcrelib/testdata/testoutput5 @@ -1,113 +1,9 @@ -/-- This set of tests checks the API, internals, and non-Perl stuff for UTF-8 - support, excluding Unicode properties. --/ +/-- 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). --/ -/\x{100}/8DZ ------------------------------------------------------------------- - Bra - \x{100} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - -/\x{1000}/8DZ ------------------------------------------------------------------- - Bra - \x{1000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 225 -Need char = 128 - -/\x{10000}/8DZ ------------------------------------------------------------------- - Bra - \x{10000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 240 -Need char = 128 - -/\x{100000}/8DZ ------------------------------------------------------------------- - Bra - \x{100000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 244 -Need char = 128 - -/\x{1000000}/8DZ ------------------------------------------------------------------- - Bra - \x{1000000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 249 -Need char = 128 - -/\x{4000000}/8DZ ------------------------------------------------------------------- - Bra - \x{4000000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 252 -Need char = 128 - -/\x{7fffFFFF}/8DZ ------------------------------------------------------------------- - Bra - \x{7fffffff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 253 -Need char = 191 - -/[\x{ff}]/8DZ ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - -/[\x{100}]/8DZ ------------------------------------------------------------------- - Bra - [\x{100}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char +/\x{110000}/8DZ +Failed: character value in \x{...} sequence is too large at offset 9 /\x{ffffffff}/8 Failed: character value in \x{...} sequence is too large at offset 11 @@ -115,34 +11,20 @@ Failed: character value in \x{...} sequence is too large at offset 11 /\x{100000000}/8 Failed: character value in \x{...} sequence is too large at offset 12 +/\x{d800}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{dfff}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{d7ff}/8 + +/\x{e000}/8 + /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd 0: \x{100}a\x{1234} -/\x80/8DZ ------------------------------------------------------------------- - Bra - \x{80} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 194 -Need char = 128 - -/\xff/8DZ ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 ------------------------------------------------------------------ Bra @@ -151,100 +33,12 @@ Need char = 191 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'A' Need char = '.' \x{0041}\x{2262}\x{0391}\x{002e} 0: A\x{2262}\x{391}. -/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 ------------------------------------------------------------------- - Bra - \x{d55c}\x{ad6d}\x{c5b4} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 237 -Need char = 180 - \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: utf8 -First char = 230 -Need char = 158 - \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: utf8 -First char = 194 -Need char = 128 - -/\x{084}/DZ8 ------------------------------------------------------------------- - Bra - \x{84} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 194 -Need char = 132 - -/\x{104}/DZ8 ------------------------------------------------------------------- - Bra - \x{104} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 132 - -/\x{861}/DZ8 ------------------------------------------------------------------- - Bra - \x{861} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 224 -Need char = 161 - -/\x{212ab}/DZ8 ------------------------------------------------------------------- - Bra - \x{212ab} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 240 -Need char = 171 - /.{3,5}X/DZ8 ------------------------------------------------------------------ Bra @@ -255,13 +49,12 @@ Need char = 171 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char Need char = 'X' \x{212ab}\x{212ab}\x{212ab}\x{861}X 0: \x{212ab}\x{212ab}\x{212ab}\x{861}X - /.{3,5}?/DZ8 ------------------------------------------------------------------ Bra @@ -271,7 +64,7 @@ Need char = 'X' End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char \x{212ab}\x{212ab}\x{212ab}\x{861} @@ -280,20 +73,6 @@ No need char /(?<=\C)X/8 Failed: \C not allowed in lookbehind assertion at offset 6 -/-- 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: \xe1 - 2: \x88\xb4 - X\nabc - 0: X\x{0a}abc - 1: \x{0a} - 2: abc - /^[ab]/8DZ ------------------------------------------------------------------ Bra @@ -303,7 +82,7 @@ can't tell the difference.) --/ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char bar @@ -326,7 +105,7 @@ No match End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char c @@ -340,136 +119,6 @@ No need char aaa No match -/[^ab\xC0-\xF0]/8SDZ ------------------------------------------------------------------- - Bra - [\x00-`c-\xbf\xf1-\xff] (neg) - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -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: utf8 -First char = 196 -Need char = 128 -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: utf8 -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: utf8 -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: utf8 -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: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: x \xc4 - /\x{100}*(\d+|"(?1)")/8 1234 0: 1234 @@ -494,18 +143,6 @@ No match \x{100}\x{100}abcd No match -/\x{100}/8DZ ------------------------------------------------------------------- - Bra - \x{100} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - /\x{100}*/8DZ ------------------------------------------------------------------ Bra @@ -514,7 +151,7 @@ Need char = 128 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -527,7 +164,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'a' No need char @@ -540,36 +177,10 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'a' Need char = 'b' -/a\x{100}\x{101}*/8DZ ------------------------------------------------------------------- - Bra - a\x{100} - \x{101}* - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'a' -Need char = 128 - -/a\x{100}\x{101}+/8DZ ------------------------------------------------------------------- - Bra - a\x{100} - \x{101}+ - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'a' -Need char = 129 - /\x{100}*A/8DZ ------------------------------------------------------------------ Bra @@ -579,7 +190,7 @@ Need char = 129 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char Need char = 'A' A @@ -590,61 +201,15 @@ Need char = 'A' Bra \x{100}*+ \d - Once Recurse Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char -/[^\x{c4}]/DZ ------------------------------------------------------------------- - Bra - [^\xc4] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -No options -No first char -No need char - -/[^\x{c4}]/8DZ ------------------------------------------------------------------- - Bra - [\x00-\xc3\xc5-\xff] (neg) - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - -/[\x{100}]/8DZ ------------------------------------------------------------------- - Bra - [\x{100}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - \x{100} - 0: \x{100} - Z\x{100} - 0: \x{100} - \x{100}Z - 0: \x{100} - *** Failers -No match - /[Z\x{100}]/8DZ ------------------------------------------------------------------ Bra @@ -653,7 +218,7 @@ No match End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char Z\x{100} @@ -688,7 +253,7 @@ No match End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -700,7 +265,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char \x{100} @@ -717,25 +282,11 @@ No need char ------------------------------------------------------------------ Capturing subpattern count = 0 No options -First char = 255 +First char = \xff No need char >\xff< 0: \xff -/[\xff]/DZ8 ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - >\x{ff}< - 0: \x{ff} - /[^\xFF]/DZ ------------------------------------------------------------------ Bra @@ -748,18 +299,6 @@ No options No first char No need char -/[^\xff]/8DZ ------------------------------------------------------------------- - Bra - [\x00-\xfe] (neg) - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - /[Ä-Ãœ]/8 Ö # Matches without Study 0: \x{d6} @@ -784,99 +323,6 @@ No need char \x{d6} 0: \x{d6} -/[Ã]/8 -Failed: invalid UTF-8 string at offset 2 - -/Ã/8 -Failed: invalid UTF-8 string at offset 0 - -/ÃÃÃxxx/8 -Failed: invalid UTF-8 string at offset 1 - -/ÃÃÃxxx/8?DZ ------------------------------------------------------------------- - Bra - \X{c0}\X{c0}\X{c0}xxx - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 no_utf8_check -First char = 195 -Need char = 'x' - -/abc/8 - Ã] -Error -10 - à -Error -10 - ÃÃà -Error -10 - ÃÃÃ\? -No match - -/anything/8 - \xc0\x80 -Error -10 - \xc1\x8f -Error -10 - \xe0\x9f\x80 -Error -10 - \xf0\x8f\x80\x80 -Error -10 - \xf8\x87\x80\x80\x80 -Error -10 - \xfc\x83\x80\x80\x80\x80 -Error -10 - \xfe\x80\x80\x80\x80\x80 -Error -10 - \xff\x80\x80\x80\x80\x80 -Error -10 - \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 - \xf9\x87\x80\x80\x80 -Error -10 - \xfc\x84\x80\x80\x80\x80 -Error -10 - \xfd\x83\x80\x80\x80\x80 -Error -10 - \?\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}abc(xyz(?1))/8DZ ------------------------------------------------------------------- - Bra - \x{100}abc - CBra 1 - xyz - Once - Recurse - Ket - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -First char = 196 -Need char = 'z' - /[^\x{100}]abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra @@ -884,15 +330,13 @@ Need char = 'z' abc CBra 1 xyz - Once Recurse Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 -Options: utf8 +Options: utf No first char Need char = 'z' @@ -903,15 +347,13 @@ Need char = 'z' abc CBra 1 xyz - Once Recurse Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 -Options: utf8 +Options: utf No first char Need char = 'z' @@ -923,9 +365,7 @@ Need char = 'z' \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -933,7 +373,7 @@ Need char = 'z' End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -946,9 +386,7 @@ No need char \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -957,9 +395,7 @@ No need char \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -968,7 +404,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -980,9 +416,7 @@ No need char \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -990,7 +424,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -1003,9 +437,7 @@ No need char \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -1014,9 +446,7 @@ No need char \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -1025,7 +455,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -1039,10 +469,6 @@ No need char \x{100}X 0: X -/a\x{1234}b/P8 - a\x{1234}b - 0: a\x{1234}b - /^\ሴ/8DZ ------------------------------------------------------------------ Bra @@ -1052,23 +478,10 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char -/\777/I -Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3 - -/\777/8I -Capturing subpattern count = 0 -Options: utf8 -First char = 199 -Need char = 191 - \x{1ff} - 0: \x{1ff} - \777 - 0: \x{1ff} - /\x{100}*\d/8DZ ------------------------------------------------------------------ Bra @@ -1078,7 +491,7 @@ Need char = 191 End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1091,7 +504,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1104,7 +517,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1117,7 +530,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1130,7 +543,7 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1143,49 +556,10 @@ No need char End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char -/\x{100}+\x{200}/8DZ ------------------------------------------------------------------- - Bra - \x{100}++ - \x{200} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - -/\x{100}+X/8DZ ------------------------------------------------------------------- - Bra - \x{100}++ - X - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 'X' - -/X+\x{200}/8DZ ------------------------------------------------------------------- - Bra - X++ - \x{200} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'X' -Need char = 128 - /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() @@ -1227,9 +601,6 @@ Matched, but too many substrings End ------------------------------------------------------------------ -/^[\QÄ€\E-\QÅ\E/BZ8 -Failed: missing terminating ] for character class at offset 15 - /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK 0: abc1 @@ -1415,7 +786,7 @@ No match /[\H]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\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{7fffffff}] + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\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}] Ket End ------------------------------------------------------------------ @@ -1423,7 +794,7 @@ No match /[\V]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{2029}-\x{7fffffff}] + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}] Ket End ------------------------------------------------------------------ @@ -1432,39 +803,9 @@ No match \x{1ec5} 0: \x{1ec5} -/-- This tests the stricter UTF-8 check according to RFC 3629. --/ - -/X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} -No match - \x{d800} -Error -10 - \x{d800}\? -No match - \x{da00} -Error -10 - \x{da00}\? -No match - \x{dfff} -Error -10 - \x{dfff}\? -No match - \x{110000} -Error -10 - \x{110000}\? -No match - \x{2000000} -Error -10 - \x{2000000}\? -No match - \x{7fffffff} -Error -10 - \x{7fffffff}\? -No match - /a\Rb/I8 Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb @@ -1482,7 +823,7 @@ No match /a\Rb/I8 Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb @@ -1504,7 +845,7 @@ No match /a\R?b/I8 Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb @@ -1522,7 +863,7 @@ No match /a\R?b/I8 Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb @@ -1579,26 +920,11 @@ No match \x{de}\x{de} 0: \xde\xde 1: \xde - \x{123} -** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. -** Truncation will probably give the wrong result. -No match /X/8f A\x{1ec5}ABCXYZ 0: X -/(*UTF8)\x{1234}/ - abcd\x{1234}pqr - 0: \x{1234} - -/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I -Capturing subpattern count = 0 -Options: bsr_unicode utf8 -Forced newline sequence: CRLF -First char = 'a' -Need char = 'b' - /Xa{2,4}b/8 X\P Partial match: X @@ -2076,150 +1402,448 @@ Partial match: abcde \PX Partial match: X -/\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/SI8 -Capturing subpattern count = 0 -Options: utf8 -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/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/SI8 -Capturing subpattern count = 0 -Options: utf8 -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} - -/\R/SI -Capturing subpattern count = 0 -No options -No first char -No need char -Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \x85 - -/\R/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char -Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 - -/\h*A/SI8 -Capturing subpattern count = 0 -Options: utf8 -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: utf8 -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: utf8 -No first char -Need char = 'x' -Subject length lower bound = 4 -Starting byte set: \x09 \x0a \x0c \x0d \x20 x - /\sxxx\s/8T1 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} -/\sxxx\s/I8ST1 -Capturing subpattern count = 0 -Options: utf8 -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/8T1 \x{a2} \x{84} 0: \x{a2} \x{84} -/\S \S/I8ST1 +'A#хц'8xBZ +------------------------------------------------------------------ + Bra + A + Ket + End +------------------------------------------------------------------ + +'A#хц + PQ'8xBZ +------------------------------------------------------------------ + Bra + APQ + Ket + End +------------------------------------------------------------------ + +/a+#Ñ…aa + z#XX?/8xBZ +------------------------------------------------------------------ + Bra + a++ + z + Ket + End +------------------------------------------------------------------ + +/a+#Ñ…aa + z#Ñ…?/8xBZ +------------------------------------------------------------------ + Bra + a++ + z + Ket + End +------------------------------------------------------------------ + +/\g{A}xxx#bXX(?'A'123) (?'A'456)/8xBZ +------------------------------------------------------------------ + Bra + \1 + xxx + CBra 1 + 456 + Ket + Ket + End +------------------------------------------------------------------ + +/\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ +------------------------------------------------------------------ + Bra + \1 + xxx + CBra 1 + 456 + Ket + Ket + End +------------------------------------------------------------------ + +/^\cÄ£/8 +Failed: \c must be followed by an ASCII character at offset 3 + +/(\R*)(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + +/(\R)*(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + +/[^\x{1234}]+/iS8I Capturing subpattern count = 0 -Options: utf8 +Options: caseless 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 +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 2 +No set of starting bytes + +// +Failed: inconsistent NEWLINE options at offset 0 + +/f.*/ + \P\Pfor +Partial match: for + +/f.*/s + \P\Pfor +Partial match: for + +/f.*/8 + \P\Pfor +Partial match: for + +/f.*/8s + \P\Pfor +Partial match: for + +/\x{d7ff}\x{e000}/8 + +/\x{d800}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{dfff}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\h+/8 + \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}\x{a0}\x{2000} + 0: \x{200a}\x{a0}\x{2000} + +/[\h\x{e000}]+/8BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+ + Ket + End +------------------------------------------------------------------ + \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}\x{a0}\x{2000} + 0: \x{200a}\x{a0}\x{2000} + +/\H+/8 + \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} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + 0: \x{9f}\x{a1}\x{2fff}\x{3001} + +/[\H\x{d7ff}]+/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\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 +------------------------------------------------------------------ + \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} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + 0: \x{9f}\x{a1}\x{2fff}\x{3001} + +/\v+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/[\v\x{e000}]+/8BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+ + Ket + End +------------------------------------------------------------------ + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/\V+/8 + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + 0: \x{09}\x{0e}\x{84}\x{86} + +/[\V\x{d7ff}]+/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+ + Ket + End +------------------------------------------------------------------ + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + 0: \x{09}\x{0e}\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/(..)\1/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P + 0: abab + 1: ab + +/(..)\1/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P + 0: aBAb + 1: aB + +/(..)\1{2,}/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P +Partial match: abab + ababa\P +Partial match: ababa + ababab\P + 0: ababab + 1: ab + ababab\P\P +Partial match: ababab + abababa\P + 0: ababab + 1: ab + abababa\P\P +Partial match: abababa + +/(..)\1{2,}/8i + ab\P +Partial match: ab + aBa\P +Partial match: aBa + aBAb\P +Partial match: aBAb + AbaBA\P +Partial match: AbaBA + abABAb\P + 0: abABAb + 1: ab + aBAbaB\P\P +Partial match: aBAbaB + abABabA\P + 0: abABab + 1: ab + abaBABa\P\P +Partial match: abaBABa + +/(..)\1{2,}?x/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P +Partial match: aBAb + abaBA\P +Partial match: abaBA + abAbaB\P +Partial match: abAbaB + abaBabA\P +Partial match: abaBabA + abAbABaBx\P + 0: abAbABaBx + 1: ab + +/./8 + \r\P + 0: \x{0d} + \r\P\P +Partial match: \x{0d} + +/.{2,3}/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d}\x{0d} + \r\r\r\P\P +Partial match: \x{0d}\x{0d}\x{0d} + +/.{2,3}?/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d} + \r\r\r\P\P + 0: \x{0d}\x{0d} + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}] + [^\x{1234}] + [^\x{ffff}] + [^\x{10000}] + [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}] + /i [^\x{1234}] + /i [^\x{ffff}] + /i [^\x{10000}] + /i [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}]* + [^\x{10000}]+ + [^\x{10ffff}]?? + [^\x{8000}]{4} + [^\x{8000}]* + [^\x{7fff}]{2} + [^\x{7fff}]{0,7}? + [^\x{fffff}]{5} + [^\x{fffff}]?+ + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}]* + /i [^\x{10000}]+ + /i [^\x{10ffff}]?? + /i [^\x{8000}]{4} + /i [^\x{8000}]* + /i [^\x{7fff}]{2} + /i [^\x{7fff}]{0,7}? + Once + /i [^\x{fffff}]{5} + /i [^\x{fffff}]? + Ket + Ket + End +------------------------------------------------------------------ + +/(?<=\x{1234}\x{1234})\bxy/I8 +Capturing subpattern count = 0 +Options: utf +First char = 'x' +Need char = 'y' +Max lookbehind = 2 + +/(?8BZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ + +/[\u0100-\u0200]/8BZ +------------------------------------------------------------------ + Bra + [\x{100}-\x{200}] + Ket + End +------------------------------------------------------------------ + +/\ud800/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5 /-- End of testinput5 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput6 b/ext/pcre/pcrelib/testdata/testoutput6 index 6a9ec839d94..e88fc091b73 100644 --- a/ext/pcre/pcrelib/testdata/testoutput6 +++ b/ext/pcre/pcrelib/testdata/testoutput6 @@ -1114,6 +1114,8 @@ No match 0: A\x80 /^[\p{Arabic}]/8 + \x{604} + 0: \x{604} \x{60e} 0: \x{60e} \x{656} @@ -1143,8 +1145,6 @@ No match \x{6fa} 0: \x{6fa} ** Failers -No match - \x{600} No match \x{650} No match @@ -1176,8 +1176,6 @@ No match 0: \x{964} \x{965} 0: \x{965} - \x{970} - 0: \x{970} /^\p{Inherited}/8 \x{64b} @@ -1353,4 +1351,26 @@ No match a\xFCb No match +/â±¥/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/[â±¥]/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/Ⱥ/8i + Ⱥ + 0: \x{23a} + â±¥ + 0: \x{2c65} + /-- End of testinput6 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput7 b/ext/pcre/pcrelib/testdata/testoutput7 index 123ba82c4b0..ccfdad965c5 100644 --- a/ext/pcre/pcrelib/testdata/testoutput7 +++ b/ext/pcre/pcrelib/testdata/testoutput7 @@ -1,7700 +1,1316 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ - -/abc/ - abc - 0: abc - -/ab*c/ - abc - 0: abc - abbbbc - 0: abbbbc - ac - 0: ac - -/ab+c/ - abc - 0: abc - abbbbbbc - 0: abbbbbbc - *** Failers -No match - ac -No match - ab -No match - -/a*/ - a - 0: a - 1: - aaaaaaaaaaaaaaaaa - 0: aaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaa - 4: aaaaaaaaaaaaa - 5: aaaaaaaaaaaa - 6: aaaaaaaaaaa - 7: aaaaaaaaaa - 8: aaaaaaaaa - 9: aaaaaaaa -10: aaaaaaa -11: aaaaaa -12: aaaaa -13: aaaa -14: aaa -15: aa -16: a -17: - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaaaaaaaaaaaaaaa - 4: aaaaaaaaaaaaaaaaaaaaaaaaaa - 5: aaaaaaaaaaaaaaaaaaaaaaaaa - 6: aaaaaaaaaaaaaaaaaaaaaaaa - 7: aaaaaaaaaaaaaaaaaaaaaaa - 8: aaaaaaaaaaaaaaaaaaaaaa - 9: aaaaaaaaaaaaaaaaaaaaa -10: aaaaaaaaaaaaaaaaaaaa -11: aaaaaaaaaaaaaaaaaaa -12: aaaaaaaaaaaaaaaaaa -13: aaaaaaaaaaaaaaaaa -14: aaaaaaaaaaaaaaaa -15: aaaaaaaaaaaaaaa -16: aaaaaaaaaaaaaa -17: aaaaaaaaaaaaa -18: aaaaaaaaaaaa -19: aaaaaaaaaaa -20: aaaaaaaaaa -21: aaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F - 0: - -/(a|abcd|african)/ - a - 0: a - abcd - 0: abcd - 1: a - african - 0: african - 1: a - -/^abc/ - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/^abc/m - abcdef - 0: abc - xyz\nabc - 0: abc - *** Failers -No match - xyzabc -No match - -/\Aabc/ - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/\Aabc/m - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/\Gabc/ - abcdef - 0: abc - xyzabc\>3 - 0: abc - *** Failers -No match - xyzabc -No match - xyzabc\>2 -No match - -/x\dy\Dz/ - x9yzz - 0: x9yzz - x0y+z - 0: x0y+z - *** Failers -No match - xyz -No match - xxy0z -No match - -/x\sy\Sz/ - x yzz - 0: x yzz - x y+z - 0: x y+z - *** Failers -No match - xyz -No match - xxyyz -No match - -/x\wy\Wz/ - xxy+z - 0: xxy+z - *** Failers -No match - xxy0z -No match - x+y+z -No match - -/x.y/ - x+y - 0: x+y - x-y - 0: x-y - *** Failers -No match - x\ny -No match - -/x.y/s - x+y - 0: x+y - x-y - 0: x-y - x\ny - 0: x\x0ay +/-- These tests for Unicode property support test PCRE's API and show some of + the compiled code. They are not Perl-compatible. --/ -/(a.b(?s)c.d|x.y)p.q/ - a+bc+dp+q - 0: a+bc+dp+q - a+bc\ndp+q - 0: a+bc\x0adp+q - x\nyp+q - 0: x\x0ayp+q - *** Failers -No match - a\nbc\ndp+q -No match - a+bc\ndp\nq -No match - x\nyp\nq -No match +/[\p{L}]/DZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/a\d\z/ - ba0 - 0: a0 - *** Failers -No match - ba0\n -No match - ba0\ncd -No match +/[\p{^L}]/DZ +------------------------------------------------------------------ + Bra + [\P{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/a\d\z/m - ba0 - 0: a0 - *** Failers -No match - ba0\n -No match - ba0\ncd -No match +/[\P{L}]/DZ +------------------------------------------------------------------ + Bra + [\P{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/a\d\Z/ - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match +/[\P{^L}]/DZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/a\d\Z/m - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match +/[abc\p{L}\x{0660}]/8DZ +------------------------------------------------------------------ + Bra + [a-c\p{L}\x{660}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char -/a\d$/ - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match +/[\p{Nd}]/8DZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + 1234 + 0: 1 -/a\d$/m - ba0 - 0: a0 - ba0\n - 0: a0 - ba0\ncd - 0: a0 - *** Failers -No match - -/abc/i - abc - 0: abc - aBc - 0: aBc - ABC - 0: ABC - -/[^a]/ - abcd - 0: b - -/ab?\w/ - abz - 0: abz - 1: ab - abbz - 0: abb - 1: ab - azz - 0: az - -/x{0,3}yz/ - ayzq - 0: yz - axyzq - 0: xyz - axxyz - 0: xxyz - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - -/x{3}yz/ - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - ayzq -No match - axyzq -No match - axxyz -No match - -/x{2,3}yz/ - axxyz - 0: xxyz - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - ayzq -No match - axyzq -No match - -/[^a]+/ - bac - 0: b - bcdefax - 0: bcdef - 1: bcde - 2: bcd - 3: bc - 4: b - *** Failers - 0: *** F - 1: *** - 2: *** - 3: ** - 4: * - aaaaa -No match - -/[^a]*/ - bac - 0: b - 1: - bcdefax - 0: bcdef - 1: bcde - 2: bcd - 3: bc - 4: b - 5: - *** Failers - 0: *** F - 1: *** - 2: *** - 3: ** - 4: * - 5: - aaaaa - 0: - -/[^a]{3,5}/ - xyz - 0: xyz - awxyza - 0: wxyz - 1: wxy - abcdefa - 0: bcdef - 1: bcde - 2: bcd - abcdefghijk - 0: bcdef - 1: bcde - 2: bcd - *** Failers - 0: *** F - 1: *** - 2: *** - axya -No match - axa -No match - aaaaa -No match - -/\d*/ - 1234b567 +/[\p{Nd}+-]+/8DZ +------------------------------------------------------------------ + Bra + [+\-\p{Nd}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + 1234 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 + 12-34 + 0: 12-34 + 12+\x{661}-34 + 0: 12+\x{661}-34 + ** Failers No match - xyz -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 - -/\d?A/ - 045ABC - 0: 5A - ABC - 0: A - *** Failers -No match - XYZ -No match - -/\D?A/ - ABC - 0: A - BAC - 0: BA - 9ABC - 0: A - *** Failers + abcd No match -/a+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/^.*xyz/ - xyz - 0: xyz - ggggggggxyz - 0: ggggggggxyz - -/^.+xyz/ - abcdxyz - 0: abcdxyz - axyz - 0: axyz - *** Failers +/[\x{105}-\x{109}]/8iDZ +------------------------------------------------------------------ + Bra + [\x{104}-\x{109}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + \x{104} + 0: \x{104} + \x{105} + 0: \x{105} + \x{109} + 0: \x{109} + ** Failers No match - xyz + \x{100} +No match + \x{10a} No match -/^.?xyz/ - xyz - 0: xyz - cxyz - 0: cxyz +/[z-\x{100}]/8iDZ +------------------------------------------------------------------ + Bra + [Z\x{39c}\x{178}z-\x{101}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + Z + 0: Z + z + 0: z + \x{39c} + 0: \x{39c} + \x{178} + 0: \x{178} + | + 0: | + \x{80} + 0: \x{80} + \x{ff} + 0: \x{ff} + \x{100} + 0: \x{100} + \x{101} + 0: \x{101} + ** Failers +No match + \x{102} +No match + Y +No match + y +No match -/^\d{2,3}X/ - 12X - 0: 12X - 123X - 0: 123X - *** Failers +/[z-\x{100}]/8DZi +------------------------------------------------------------------ + Bra + [Z\x{39c}\x{178}z-\x{101}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + +/(?:[\PPa*]*){8,}/ + +/[\P{Any}]/BZ +------------------------------------------------------------------ + Bra + [\P{Any}] + Ket + End +------------------------------------------------------------------ + +/[\P{Any}\E]/BZ +------------------------------------------------------------------ + Bra + [\P{Any}] + Ket + End +------------------------------------------------------------------ + +/(\P{Yi}+\277)/ + +/(\P{Yi}+\277)?/ + +/(?<=\P{Yi}{3}A)X/ + +/\p{Yi}+(\P{Yi}+)(?1)/ + +/(\P{Yi}{2}\277)?/ + +/[\P{Yi}A]/ + +/[\P{Yi}\P{Yi}\P{Yi}A]/ + +/[^\P{Yi}A]/ + +/[^\P{Yi}\P{Yi}\P{Yi}A]/ + +/(\P{Yi}*\277)*/ + +/(\P{Yi}*?\277)*/ + +/(\p{Yi}*+\277)*/ + +/(\P{Yi}?\277)*/ + +/(\P{Yi}??\277)*/ + +/(\p{Yi}?+\277)*/ + +/(\P{Yi}{0,3}\277)*/ + +/(\P{Yi}{0,3}?\277)*/ + +/(\p{Yi}{0,3}+\277)*/ + +/\p{Zl}{2,3}+/8BZ +------------------------------------------------------------------ + Bra + prop Zl {2} + prop Zl ?+ + Ket + End +------------------------------------------------------------------ + \xe2\x80\xa8\xe2\x80\xa8 + 0: \x{2028}\x{2028} + \x{2028}\x{2028}\x{2028} + 0: \x{2028}\x{2028}\x{2028} + +/\p{Zl}/8BZ +------------------------------------------------------------------ + Bra + prop Zl + Ket + End +------------------------------------------------------------------ + +/\p{Lu}{3}+/8BZ +------------------------------------------------------------------ + Bra + prop Lu {3} + Ket + End +------------------------------------------------------------------ + +/\pL{2}+/8BZ +------------------------------------------------------------------ + Bra + prop L {2} + Ket + End +------------------------------------------------------------------ + +/\p{Cc}{2}+/8BZ +------------------------------------------------------------------ + Bra + prop Cc {2} + Ket + End +------------------------------------------------------------------ + +/^\p{Cs}/8 + \?\x{dfff} + 0: \x{dfff} + ** Failers +No match + \x{09f} +No match + +/^\p{Sc}+/8 + $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} + 0: $\x{a2}\x{a3}\x{a4}\x{a5} + \x{9f2} + 0: \x{9f2} + ** Failers No match X No match - 1X + \x{2c2} No match - 1234X + +/^\p{Zs}/8 + \ \ + 0: + \x{a0} + 0: \x{a0} + \x{1680} + 0: \x{1680} + \x{180e} + 0: \x{180e} + \x{2000} + 0: \x{2000} + \x{2001} + 0: \x{2001} + ** Failers No match - -/^[abcd]\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - *** Failers + \x{2028} No match - e45 + \x{200d} No match - abcd -No match - abcd1234 -No match - 1234 -No match - -/^[abcd]*\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - abcd1234 - 0: abcd1 - 1234 + +/-- These four are here rather than in test 6 because Perl has problems with + the negative versions of the properties. --/ + +/\p{^Lu}/8i + 1234 0: 1 - *** Failers -No match - e45 -No match - abcd + ** Failers + 0: * + ABC No match -/^[abcd]+\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - abcd1234 - 0: abcd1 - *** Failers -No match - 1234 -No match - e45 -No match - abcd -No match - -/^a+X/ - aX - 0: aX - aaX - 0: aaX - -/^[abcd]?\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - 1234 +/\P{Lu}/8i + 1234 0: 1 + ** Failers + 0: * + ABC +No match + +/\p{Ll}/8i + a + 0: a + Az + 0: z + ** Failers + 0: a + ABC +No match + +/\p{Lu}/8i + A + 0: A + a\x{10a0}B + 0: \x{10a0} + ** Failers + 0: F + a +No match + \x{1d00} +No match + +/[\x{c0}\x{391}]/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/-- The next two are special cases where the lengths of the different cases of +the same character differ. The first went wrong with heap frame storage; the +second was broken in all cases. --/ + +/^\x{023a}+?(\x{0130}+)/8i + \x{023a}\x{2c65}\x{0130} + 0: \x{23a}\x{2c65}\x{130} + 1: \x{130} + +/^\x{023a}+([^X])/8i + \x{023a}\x{2c65}X + 0: \x{23a}\x{2c65} + 1: \x{2c65} + +/\x{c0}+\x{116}+/8i + \x{c0}\x{e0}\x{116}\x{117} + 0: \x{c0}\x{e0}\x{116}\x{117} + +/[\x{c0}\x{116}]+/8i + \x{c0}\x{e0}\x{116}\x{117} + 0: \x{c0}\x{e0}\x{116}\x{117} + +/(\x{de})\1/8i + \x{de}\x{de} + 0: \x{de}\x{de} + 1: \x{de} + \x{de}\x{fe} + 0: \x{de}\x{fe} + 1: \x{de} + \x{fe}\x{fe} + 0: \x{fe}\x{fe} + 1: \x{fe} + \x{fe}\x{de} + 0: \x{fe}\x{de} + 1: \x{fe} + +/^\x{c0}$/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/^\x{e0}$/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE +will match it only with UCP support, because without that it has no notion +of case for anything other than the ASCII letters. --/ + +/((?i)[\x{c0}])/8 + \x{c0} + 0: \x{c0} + 1: \x{c0} + \x{e0} + 0: \x{e0} + 1: \x{e0} + +/(?i:[\x{c0}])/8 + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 + +/^\X/8 + A + 0: A + A\x{300}BC + 0: A\x{300} + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302} *** Failers + 0: * + \x{300} No match - abcd1234 + +/-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ + +/^\p{Xan}/8 + ABCD + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + ** Failers No match - e45 + _ABC No match -/^[abcd]{2,3}\d/ - ab45 - 0: ab4 - bcd93 - 0: bcd9 - *** Failers +/^\p{Xan}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} + ** Failers No match - 1234 -No match - a36 -No match - abcd1234 -No match - ee45 + _ABC No match -/^(abc)*\d/ - abc45 - 0: abc4 - abcabcabc45 - 0: abcabcabc4 - 42xyz - 0: 4 - *** Failers +/^\p{Xan}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca} + +/^\p{Xan}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} + +/^\p{Xan}{2,9}/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca} + +/^\p{Xan}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca}\x{a6c} + +/^[\p{Xan}]/8 + ABCD1234_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + ** Failers +No match + _ABC +No match + +/^[\p{Xan}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} + ** Failers +No match + _ABC No match -/^(abc)+\d/ - abc45 - 0: abc4 - abcabcabc45 - 0: abcabcabc4 - *** Failers +/^>\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} + ** Failers No match - 42xyz + \x{0b} No match -/^(abc)?\d/ - abc45 - 0: abc4 - 42xyz - 0: 4 - *** Failers +/^>\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} + +/^>\p{Xsp}+?/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + +/^>\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} + +/^>\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} + +/^>\p{Xsp}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\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} + +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} + ** Failers No match - abcabcabc45 + \x{0b} No match -/^(abc){2,3}\d/ - abcabc45 - 0: abcabc4 - abcabcabc45 - 0: abcabcabc4 - *** Failers +/^>\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} + +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + +/^>\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} + +/^>\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} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\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} + +/^\p{Xwd}/8 + ABCD + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers No match - abcabcabcabc45 -No match - abc45 -No match - 42xyz + [] No match -/1(abc|xyz)2(?1)3/ - 1abc2abc3456 - 0: 1abc2abc3 - 1abc2xyz3456 - 0: 1abc2xyz3 +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/^(a*\w|ab)=(a*\w|ab)/ - ab=ab - 0: ab=ab - 1: ab=a +/^\p{Xwd}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca} -/^(a*\w|ab)=(?1)/ - ab=ab - 0: ab=ab +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_B12\x{6ca}\x{a6c}\x{10a7} + 0: A_B12\x{6ca}\x{a6c}\x{10a7} + +/^\p{Xwd}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca}\x{a6c} + +/^[\p{Xwd}]/8 + ABCD1234_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers +No match + [] +No match + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/^([^()]|\((?1)*\))*$/ +/-- A check not in UTF-8 mode --/ + +/^[\p{Xwd}]+/ + ABCD1234_ + 0: ABCD1234_ + +/-- Some negative checks --/ + +/^[\P{Xwd}]+/8 + !.+\x{019}\x{35a}AB + 0: !.+\x{19}\x{35a} + +/^[\p{^Xwd}]+/8 + !.+\x{019}\x{35a}AB + 0: !.+\x{19}\x{35a} + +/[\D]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Nd}] + Ket + End +------------------------------------------------------------------ + 1\x{3c8}2 + 0: \x{3c8} + +/[\d]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ + >\x{6f4}< + 0: \x{6f4} + +/[\S]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Xsp}] + Ket + End +------------------------------------------------------------------ + \x{1680}\x{6f4}\x{1680} + 0: \x{6f4} + +/[\s]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Xsp}] + Ket + End +------------------------------------------------------------------ + >\x{1680}< + 0: \x{1680} + +/[\W]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Xwd}] + Ket + End +------------------------------------------------------------------ + A\x{1712}B + 0: \x{1712} + +/[\w]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Xwd}] + Ket + End +------------------------------------------------------------------ + >\x{1723}< + 0: \x{1723} + +/\D/WBZ8 +------------------------------------------------------------------ + Bra + notprop Nd + Ket + End +------------------------------------------------------------------ + 1\x{3c8}2 + 0: \x{3c8} + +/\d/WBZ8 +------------------------------------------------------------------ + Bra + prop Nd + Ket + End +------------------------------------------------------------------ + >\x{6f4}< + 0: \x{6f4} + +/\S/WBZ8 +------------------------------------------------------------------ + Bra + notprop Xsp + Ket + End +------------------------------------------------------------------ + \x{1680}\x{6f4}\x{1680} + 0: \x{6f4} + +/\s/WBZ8 +------------------------------------------------------------------ + Bra + prop Xsp + Ket + End +------------------------------------------------------------------ + >\x{1680}> + 0: \x{1680} + +/\W/WBZ8 +------------------------------------------------------------------ + Bra + notprop Xwd + Ket + End +------------------------------------------------------------------ + A\x{1712}B + 0: \x{1712} + +/\w/WBZ8 +------------------------------------------------------------------ + Bra + prop Xwd + Ket + End +------------------------------------------------------------------ + >\x{1723}< + 0: \x{1723} + +/[[:alpha:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ + +/[[:lower:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Ll}] + Ket + End +------------------------------------------------------------------ + +/[[:upper:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Lu}] + Ket + End +------------------------------------------------------------------ + +/[[:alnum:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xan}] + Ket + End +------------------------------------------------------------------ + +/[[:ascii:]]/WBZ +------------------------------------------------------------------ + Bra + [\x00-\x7f] + Ket + End +------------------------------------------------------------------ + +/[[:cntrl:]]/WBZ +------------------------------------------------------------------ + Bra + [\x00-\x1f\x7f] + Ket + End +------------------------------------------------------------------ + +/[[:digit:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ + +/[[:graph:]]/WBZ +------------------------------------------------------------------ + Bra + [!-~] + Ket + End +------------------------------------------------------------------ + +/[[:print:]]/WBZ +------------------------------------------------------------------ + Bra + [ -~] + Ket + End +------------------------------------------------------------------ + +/[[:punct:]]/WBZ +------------------------------------------------------------------ + Bra + [!-/:-@[-`{-~] + Ket + End +------------------------------------------------------------------ + +/[[:space:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xps}] + Ket + End +------------------------------------------------------------------ + +/[[:word:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xwd}] + Ket + End +------------------------------------------------------------------ + +/[[:xdigit:]]/WBZ +------------------------------------------------------------------ + Bra + [0-9A-Fa-f] + Ket + End +------------------------------------------------------------------ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + 0: abc + \x{37e}abc\x{376} + 0: abc + \x{37e}\x{376}\x{371}\x{393}\x{394} + 0: \x{376}\x{371}\x{393} + !\x{c0}++\x{c1}\x{c2} + 0: ++\x{c1} + !\x{c0}+++++ + 0: \x{c0}++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + 0: abc + ** Failers + 0: Fai + \x{37e}abc\x{376} +No match + \x{37e}\x{376}\x{371}\x{393}\x{394} +No match + !\x{c0}++\x{c1}\x{c2} +No match + !\x{c0}+++++ +No match + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + 0: abc + !\x{c0}++\x{c1}\x{c2} + 0: ++\xc1 + !\x{c0}+++++ + 0: \xc0++ + +/-- Some of these are silly, but they check various combinations --/ + +/[[:^alpha:][:^cntrl:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc + 0: abc + +/[[:^cntrl:][:^alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc + 0: abc + +/[[:alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [\p{L}]+ + Ket + End +------------------------------------------------------------------ abc 0: abc - a(b)c - 0: a(b)c - a(b(c))d - 0: a(b(c))d - *** Failers) -No match - a(b(c)d -No match -/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)a*)\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9 - *** Failers -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x - <> - 0: <> - - 0: - hij> - 0: hij> - hij> - 0: - def> - 0: def> - - 0: <> - *** Failers -No match - abcxyz - 1 ^ ^ x - 0: abcxyz - 123abcxyz999 ---->123abcxyz999 - 1 ^ ^ x - 0: abcxyz - -/(ab|cd){3,4}/C - ababab ---->ababab - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - 0: ababab - abcdabcd ---->abcdabcd - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - 0: abcdabcd - 1: abcdab - abcdcdcdcdcd ---->abcdcdcdcdcd - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - 0: abcdcdcd - 1: abcdcd - -/^abc/ - abcdef + abc 0: abc - *** Failers -No match - abcdef\B + +/[^\d]+/8WBZ +------------------------------------------------------------------ + Bra + [^\p{Nd}]+ + Ket + End +------------------------------------------------------------------ + abc123 + 0: abc + abc\x{123} + 0: abc\x{123} + \x{660}abc + 0: abc + +/\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ +------------------------------------------------------------------ + Bra + prop Lu ++ + 9 + prop Lu + + B + prop Lu ++ + b + Ket + End +------------------------------------------------------------------ + +/\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\p{Han}+X\p{Greek}+\x{370}/BZ8 +------------------------------------------------------------------ + Bra + prop Han ++ + X + prop Greek + + \x{370} + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+!\p{Xan}+A/BZ +------------------------------------------------------------------ + Bra + prop Xan ++ + ! + prop Xan + + A + Ket + End +------------------------------------------------------------------ + +/\p{Xsp}+!\p{Xsp}\t/BZ +------------------------------------------------------------------ + Bra + prop Xsp ++ + ! + prop Xsp + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xps}+!\p{Xps}\t/BZ +------------------------------------------------------------------ + Bra + prop Xps ++ + ! + prop Xps + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xwd}+!\p{Xwd}_/BZ +------------------------------------------------------------------ + Bra + prop Xwd ++ + ! + prop Xwd + _ + Ket + End +------------------------------------------------------------------ + +/A+\p{N}A+\dB+\p{N}*B+\d*/WBZ +------------------------------------------------------------------ + Bra + A++ + prop N + A++ + prop Nd + B+ + prop N *+ + B+ + prop Nd * + Ket + End +------------------------------------------------------------------ + +/-- These behaved oddly in Perl, so they are kept in this test --/ + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} No match -/^(a*|xyz)/ - bcd - 0: - aaabcd - 0: aaa - 1: aa - 2: a - 3: - xyz - 0: xyz +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} +No match + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1/8i + \x{2c65}\x{2c65}\x{23a}\x{23a} + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(ⱥⱥ)\1/8i + ⱥⱥȺȺ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(\x{23a}\x{23a}\x{23a})\1Y/8i + X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}Y + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1Y/8i + X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a}Y + 1: \x{2c65}\x{2c65} + +/-- --/ + +/-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ + +/^[\p{Batak}]/8 + \x{1bc0} + 0: \x{1bc0} + \x{1bff} + 0: \x{1bff} + ** Failers +No match + \x{1bf4} +No match + +/^[\p{Brahmi}]/8 + \x{11000} + 0: \x{11000} + \x{1106f} + 0: \x{1106f} + ** Failers +No match + \x{1104e} +No match + +/^[\p{Mandaic}]/8 + \x{840} + 0: \x{840} + \x{85e} + 0: \x{85e} + ** Failers +No match + \x{85c} +No match + \x{85d} +No match + +/-- --/ + +/(\X*)(.)/s8 + A\x{300} + 0: A 1: - xyz\N - 0: xyz - *** Failers - 0: - bcd\N + 2: A + +/^S(\X*)e(\X*)$/8 + SteÌreÌo No match -/xyz$/ - xyz - 0: xyz - xyz\n - 0: xyz - *** Failers -No match - xyz\Z -No match - xyz\n\Z -No match - -/xyz$/m - xyz - 0: xyz - xyz\n - 0: xyz - abcxyz\npqr - 0: xyz - abcxyz\npqr\Z - 0: xyz - xyz\n\Z - 0: xyz - *** Failers -No match - xyz\Z +/^\X/8 + ÌreÌo No match -/\Gabc/ - abcdef - 0: abc - defabcxyz\>3 - 0: abc - *** Failers -No match - defabcxyz -No match - -/^abcdef/ - ab\P -Partial match: ab - abcde\P -Partial match: abcde - abcdef\P - 0: abcdef +/^a\X41z/ + aX41z + 0: aX41z *** Failers No match - abx\P + aAz No match -/^a{2,4}\d+z/ +/(?<=ab\Cde)X/8 +Failed: \C not allowed in lookbehind assertion at offset 10 + +/\X/ + a\P + 0: a + a\P\P +Partial match: a + +/\Xa/ + aa\P + 0: aa + aa\P\P + 0: aa + +/\X{2}/ + aa\P + 0: aa + aa\P\P +Partial match: aa + +/\X+a/ a\P Partial match: a aa\P + 0: aa + aa\P\P Partial match: aa - aa2\P -Partial match: aa2 - aaa\P -Partial match: aaa - aaa23\P -Partial match: aaa23 - aaaa12345\P -Partial match: aaaa12345 - aa0z\P - 0: aa0z - aaaa4444444444444z\P - 0: aaaa4444444444444z - *** Failers -No match - az\P -No match - aaaaa\P -No match - a56\P -No match -/^abcdef/ - abc\P -Partial match: abc - def\R - 0: def - -/(?<=foo)bar/ - xyzfo\P -No match - foob\P\>2 -Partial match: foob - foobar...\R\P\>4 - 0: ar - xyzfo\P -No match - foobar\>2 - 0: bar - *** Failers -No match - xyzfo\P -No match - obar\R -No match - -/(ab*(cd|ef))+X/ - adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z -No match - lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z -Partial match: abbbbbbcdaefabbbbbbbefa - cdabbbbbbbb\P\R\B\Z -Partial match: cdabbbbbbbb - efabbbbbbbbbbbbbbbb\P\R\B\Z -Partial match: efabbbbbbbbbbbbbbbb - bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z - 0: bbbbbbbbbbbbcdX - -/(a|b)/SF>testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex ->>aaabxyzpqrrrabbxyyyypqAzz - 0: aaabxyzpqrrrabbxyyyypqAzz - >aaaabxyzpqrrrabbxyyyypqAzz - 0: aaaabxyzpqrrrabbxyyyypqAzz - >>>>abcxyzpqrrrabbxyyyypqAzz - 0: abcxyzpqrrrabbxyyyypqAzz - *** Failers -No match - abxyzpqrrabbxyyyypqAzz -No match - abxyzpqrrrrabbxyyyypqAzz -No match - abxyzpqrrrabxyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyypqAzz -No match - aaabcxyzpqrrrabbxyyyypqqqqqqqAzz -No match - -/^(abc){1,2}zz/ - abczz - 0: abczz - abcabczz - 0: abcabczz - *** Failers -No match - zz -No match - abcabcabczz -No match - >>abczz -No match - -/^(b+?|a){1,2}?c/ - bc - 0: bc - bbc - 0: bbc - bbbc - 0: bbbc - bac - 0: bac - bbac - 0: bbac - aac - 0: aac - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - *** Failers -No match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}c/ - bc - 0: bc - bbc - 0: bbc - bbbc - 0: bbbc - bac - 0: bac - bbac - 0: bbac - aac - 0: aac - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - *** Failers -No match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}?bc/ - bbc - 0: bbc - -/^(b*|ba){1,2}?bc/ - babc - 0: babc - bbabc - 0: bbabc - bababc - 0: bababc - *** Failers -No match - bababbc -No match - babababc -No match - -/^(ba|b*){1,2}?bc/ - babc - 0: babc - bbabc - 0: bbabc - bababc - 0: bababc - *** Failers -No match - bababbc -No match - babababc -No match - -/^\ca\cA\c[\c{\c:/ - \x01\x01\e;z - 0: \x01\x01\x1b;z - -/^[ab\]cde]/ - athing - 0: a - bthing - 0: b - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e - *** Failers -No match - fthing -No match - [thing -No match - \\thing -No match - -/^[]cde]/ - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e - *** Failers -No match - athing -No match - fthing -No match - -/^[^ab\]cde]/ - fthing - 0: f - [thing - 0: [ - \\thing - 0: \ - *** Failers - 0: * - athing -No match - bthing -No match - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -/^[^]cde]/ - athing - 0: a - fthing - 0: f - *** Failers - 0: * - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -/^\/ - - 0: \x81 - -/^ÿ/ - ÿ - 0: \xff - -/^[0-9]+$/ - 0 - 0: 0 - 1 - 0: 1 - 2 - 0: 2 - 3 - 0: 3 - 4 - 0: 4 - 5 - 0: 5 - 6 - 0: 6 - 7 - 0: 7 - 8 - 0: 8 - 9 - 0: 9 - 10 - 0: 10 - 100 - 0: 100 - *** Failers -No match - abc -No match - -/^.*nter/ - enter - 0: enter - inter - 0: inter - uponter - 0: uponter - -/^xxx[0-9]+$/ - xxx0 - 0: xxx0 - xxx1234 - 0: xxx1234 - *** Failers -No match - xxx -No match - -/^.+[0-9][0-9][0-9]$/ - x123 - 0: x123 - xx123 - 0: xx123 - 123456 - 0: 123456 - *** Failers -No match - 123 -No match - x1234 - 0: x1234 - -/^.+?[0-9][0-9][0-9]$/ - x123 - 0: x123 - xx123 - 0: xx123 - 123456 - 0: 123456 - *** Failers -No match - 123 -No match - x1234 - 0: x1234 - -/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ - abc!pqr=apquxz.ixr.zzz.ac.uk - 0: abc!pqr=apquxz.ixr.zzz.ac.uk - *** Failers -No match - !pqr=apquxz.ixr.zzz.ac.uk -No match - abc!=apquxz.ixr.zzz.ac.uk -No match - abc!pqr=apquxz:ixr.zzz.ac.uk -No match - abc!pqr=apquxz.ixr.zzz.ac.ukk -No match - -/:/ - Well, we need a colon: somewhere - 0: : - *** Fail if we don't -No match - -/([\da-f:]+)$/i - 0abc - 0: 0abc - abc - 0: abc - fed - 0: fed - E - 0: E - :: - 0: :: - 5f03:12C0::932e - 0: 5f03:12C0::932e - fed def - 0: def - Any old stuff - 0: ff - *** Failers -No match - 0zzz -No match - gzzz -No match - fed\x20 -No match - Any old rubbish -No match - -/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ - .1.2.3 - 0: .1.2.3 - A.12.123.0 - 0: A.12.123.0 - *** Failers -No match - .1.2.3333 -No match - 1.2.3 -No match - 1234.2.3 -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 IN SOA non-sp1 non-sp2 ( - 0: 1 IN SOA non-sp1 non-sp2 ( - *** Failers -No match - 1IN SOA non-sp1 non-sp2( -No match - -/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ - a. - 0: a. - Z. - 0: Z. - 2. - 0: 2. - ab-c.pq-r. - 0: ab-c.pq-r. - sxk.zzz.ac.uk. - 0: sxk.zzz.ac.uk. - x-.y-. - 0: x-.y-. - *** Failers -No match - -abc.peq. -No match - -/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ - *.a - 0: *.a - *.b0-a - 0: *.b0-a - *.c3-b.c - 0: *.c3-b.c - *.c-a.b-c - 0: *.c-a.b-c - *** Failers -No match - *.0 -No match - *.a- -No match - *.a-b.c- -No match - *.c-a.0-c -No match - -/^(?=ab(de))(abd)(e)/ - abde - 0: abde - -/^(?!(ab)de|x)(abd)(f)/ - abdf - 0: abdf - -/^(?=(ab(cd)))(ab)/ - abcd - 0: ab - -/^[\da-f](\.[\da-f])*$/i - a.b.c.d - 0: a.b.c.d - A.B.C.D - 0: A.B.C.D - a.b.c.1.2.3.C - 0: a.b.c.1.2.3.C - -/^\".*\"\s*(;.*)?$/ - \"1234\" - 0: "1234" - \"abcd\" ; - 0: "abcd" ; - \"\" ; rhubarb - 0: "" ; rhubarb - *** Failers -No match - \"1234\" : things -No match - -/^$/ - \ - 0: - *** Failers -No match - -/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x - ab c - 0: ab c - *** Failers -No match - abc -No match - ab cde -No match - -/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ - ab c - 0: ab c - *** Failers -No match - abc -No match - ab cde -No match - -/^ a\ b[c ]d $/x - a bcd - 0: a bcd - a b d - 0: a b d - *** Failers -No match - abcd -No match - ab d -No match - -/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - -/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - -/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ - a+ Z0+\x08\n\x1d\x12 - 0: a+ Z0+\x08\x0a\x1d\x12 - -/^[.^$|()*+?{,}]+/ - .^\$(*+)|{?,?} - 0: .^$(*+)|{?,?} - 1: .^$(*+)|{?,? - 2: .^$(*+)|{?, - 3: .^$(*+)|{? - 4: .^$(*+)|{ - 5: .^$(*+)| - 6: .^$(*+) - 7: .^$(*+ - 8: .^$(* - 9: .^$( -10: .^$ -11: .^ -12: . - -/^a*\w/ - z - 0: z - az - 0: az - 1: a - aaaz - 0: aaaz - 1: aaa - 2: aa - 3: a - a - 0: a - aa +/\X+?a/ + a\P +Partial match: a + ab\P +Partial match: ab + aa\P 0: aa - 1: a - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - a+ - 0: a - aa+ + aa\P\P 0: aa - 1: a - -/^a*?\w/ - z - 0: z - az - 0: az - 1: a - aaaz - 0: aaaz - 1: aaa - 2: aa - 3: a - a - 0: a - aa - 0: aa - 1: a - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - a+ - 0: a - aa+ - 0: aa - 1: a - -/^a+\w/ - az - 0: az - aaaz - 0: aaaz - 1: aaa - 2: aa - aa - 0: aa - aaaa - 0: aaaa - 1: aaa - 2: aa - aa+ - 0: aa - -/^a+?\w/ - az - 0: az - aaaz - 0: aaaz - 1: aaa - 2: aa - aa - 0: aa - aaaa - 0: aaaa - 1: aaa - 2: aa - aa+ - 0: aa - -/^\d{8}\w{2,}/ - 1234567890 - 0: 1234567890 - 12345678ab - 0: 12345678ab - 12345678__ - 0: 12345678__ - *** Failers -No match - 1234567 -No match - -/^[aeiou\d]{4,5}$/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 12345 - aaaaa - 0: aaaaa - *** Failers -No match - 123456 -No match - -/^[aeiou\d]{4,5}?/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 12345 - 1: 1234 - aaaaa - 0: aaaaa - 1: aaaa - 123456 - 0: 12345 - 1: 1234 - -/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - -/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - From abcd Mon Sep 1 12:33:02 1997 - 0: From abcd Mon Sep 1 12:33 - *** Failers -No match - From abcd Sep 01 12:33:02 1997 -No match - -/^12.34/s - 12\n34 - 0: 12\x0a34 - 12\r34 - 0: 12\x0d34 - -/\w+(?=\t)/ - the quick brown\t fox - 0: brown - -/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 - 0: abc - *** Failers -No match - abc123 -No match - -/^1234(?# test newlines - inside)/ - 1234 - 0: 1234 - -/^1234 #comment in extended re - /x - 1234 - 0: 1234 - -/#rhubarb - abcd/x - abcd - 0: abcd - -/^abcd#rhubarb/x - abcd - 0: abcd - -/(?!^)abc/ - the abc - 0: abc - *** Failers -No match - abc -No match - -/(?=^)abc/ - abc - 0: abc - *** Failers -No match - the abc -No match - -/^[ab]{1,3}(ab*|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}?(ab*|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}?(ab*?|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}(ab*?|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/ (?: [\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 -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - 1: user@dom - user\@dom.ain - 0: user@dom.ain - 1: user@dom - \"A. Other\" (a comment) - 0: "A. Other" (a comment) - 1: "A. Other" - 2: "A. Other" - A. Other (a comment) - 0: Other (a comment) - 1: Other - 2: Other - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re - A missing angle @,;:".\\\[\]\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# 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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -# leading word -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces -(?: -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -| -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -) # "special" comment or quoted string -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" -)* -< -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# < -(?: -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -(?: , -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -)* # additional domains -: -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)? # 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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\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 -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address spec -> # > -# name and address -) -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - 1: user@dom - user\@dom.ain - 0: user@dom.ain - 1: user@dom - \"A. Other\" (a comment) - 0: "A. Other" - A. Other (a comment) - 0: Other - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re - A missing angle - a\rb - 0: a\x0db - *** Failers -No match - a\nb -No match - -/abc$/ - abc - 0: abc - abc\n - 0: abc - *** Failers -No match - abc\ndef -No match - -/(abc)\123/ - abc\x53 - 0: abcS - -/(abc)\223/ - abc\x93 - 0: abc\x93 - -/(abc)\323/ - abc\xd3 - 0: abc\xd3 - -/(abc)\100/ - abc\x40 - 0: abc@ - abc\100 - 0: abc@ - -/(abc)\1000/ - abc\x400 - 0: abc@0 - abc\x40\x30 - 0: abc@0 - abc\1000 - 0: abc@0 - abc\100\x30 - 0: abc@0 - abc\100\060 - 0: abc@0 - 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)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ - abcdefghijk\12S - 0: abcdefghijk\x0aS - -/ab\idef/ - abidef - 0: abidef - -/a{0}bc/ - bc - 0: bc - -/(a|(bc)){0,0}?xyz/ - xyz - 0: xyz - -/abc[\10]de/ - abc\010de - 0: abc\x08de - -/abc[\1]de/ - abc\1de - 0: abc\x01de - -/(abc)[\1]de/ - abc\1de - 0: abc\x01de - -/(?s)a.b/ - a\nb - 0: a\x0ab - -/^([^a])([^\b])([^c]*)([^d]{3,4})/ - baNOTccccd - 0: baNOTcccc - 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 - 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - anything -No match - b\bc -No match - baccd -No match - -/[^a]/ - Abc - 0: A - -/[^a]/i - Abc - 0: b - -/[^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 - 0: c - *** Failers - 0: s - abk -No match - -/[^k]{2,3}$/ - abc - 0: abc - kbc - 0: bc - kabc - 0: abc - *** Failers - 0: ers - abk -No match - akb -No match - akk -No match - -/^\d{8,}\@.+[^k]$/ - 12345678\@a.b.c.d - 0: 12345678@a.b.c.d - 123456789\@x.y.z - 0: 123456789@x.y.z - *** Failers -No match - 12345678\@x.y.uk -No match - 1234567\@a.b.c.d -No match - -/[^a]/ - aaaabcd - 0: b - aaAabcd - 0: A - -/[^a]/i - aaaabcd - 0: b - aaAabcd - 0: b - -/[^az]/ - aaaabcd - 0: b - aaAabcd - 0: A - -/[^az]/i - aaaabcd - 0: b - aaAabcd - 0: b - -/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ - \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 - 0: \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 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\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\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 - -/P[^*]TAIRE[^*]{1,6}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/P[^*]TAIRE[^*]{1,}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/(\.\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 - -/(\.\d\d((?=0)|\d(?=\d)))/ - 1.230003938 - 0: .230 - 1: .23 - 1.875000282 - 0: .875 - *** Failers -No match - 1.235 -No match - -/a(?)b/ - ab - 0: ab - -/\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. - 0: food is under the bar in the bar - 1: food is under the bar - -/foo(.*?)bar/ - The food is under the bar in the barn. - 0: food is under the bar in the bar - 1: food is under the bar - -/(.*)(\d*)/ - I have 2 numbers: 53147 -Matched, but too many subsidiary matches - 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 numbers: - 6: I have 2 numbers: - 7: I have 2 numbers - 8: I have 2 number - 9: I have 2 numbe -10: I have 2 numb -11: I have 2 num -12: I have 2 nu -13: I have 2 n -14: I have 2 -15: I have 2 -16: I have -17: I have -18: I hav -19: I ha -20: I h -21: I - -/(.*)(\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 - -/(.*?)(\d*)/ - I have 2 numbers: 53147 -Matched, but too many subsidiary matches - 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 numbers: - 6: I have 2 numbers: - 7: I have 2 numbers - 8: I have 2 number - 9: I have 2 numbe -10: I have 2 numb -11: I have 2 num -12: I have 2 nu -13: I have 2 n -14: I have 2 -15: I have 2 -16: I have -17: I have -18: I hav -19: I ha -20: I h -21: I - -/(.*?)(\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 - -/(.*)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*?)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*)\b(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*\D)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/^\D*(?!123)/ - ABC123 - 0: AB - 1: A - 2: - -/^(\D*)(?=\d)(?!123)/ - ABC445 - 0: ABC - *** Failers -No match - ABC123 -No match - -/^[W-]46]/ - W46]789 - 0: W46] - -46]789 - 0: -46] - *** Failers -No match - Wall -No match - Zebra -No match - 42 -No match - [abcd] -No match - ]abcd[ -No match - -/^[W-\]46]/ - W46]789 - 0: W - Wall - 0: W - Zebra - 0: Z - Xylophone - 0: X - 42 - 0: 4 - [abcd] - 0: [ - ]abcd[ - 0: ] - \\backslash - 0: \ - *** Failers -No match - -46]789 -No match - well -No match - -/\d\d\/\d\d\/\d\d\d\d/ - 01/01/2000 - 0: 01/01/2000 - -/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match - -/^(a){0,0}/ - bcd - 0: - abc - 0: - aab - 0: - -/^(a){0,1}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: a - 1: - -/^(a){0,2}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - -/^(a){0,3}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - aaa - 0: aaa - 1: aa - 2: a - 3: - -/^(a){0,}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - aaa - 0: aaa - 1: aa - 2: a - 3: - aaaaaaaa - 0: aaaaaaaa - 1: aaaaaaa - 2: aaaaaa - 3: aaaaa - 4: aaaa - 5: aaa - 6: aa - 7: a - 8: - -/^(a){1,1}/ - bcd -No match - abc - 0: a - aab - 0: a - -/^(a){1,2}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - -/^(a){1,3}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: aa - 2: a - -/^(a){1,}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: aa - 2: a - aaaaaaaa - 0: aaaaaaaa - 1: aaaaaaa - 2: aaaaaa - 3: aaaaa - 4: aaaa - 5: aaa - 6: aa - 7: a - -/.*\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.{0,}\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/m - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*\.gif/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*$/ - borfle\nbib.gif\nno - 0: no - -/.*$/m - borfle\nbib.gif\nno - 0: borfle - -/.*$/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - -/.*$/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - 1: borfle\x0abib.gif - 2: borfle - -/.*$/ - borfle\nbib.gif\nno\n - 0: no - -/.*$/m - borfle\nbib.gif\nno\n - 0: borfle - -/.*$/s - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - 1: borfle\x0abib.gif\x0ano - -/.*$/ms - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - 1: borfle\x0abib.gif\x0ano - 2: borfle\x0abib.gif - 3: borfle - -/(.*X|^B)/ - abcde\n1234Xyz - 0: 1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(.*X|^B)/m - abcde\n1234Xyz - 0: 1234X - BarFoo - 0: B - abcde\nBar - 0: B - -/(.*X|^B)/s - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(.*X|^B)/ms - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - abcde\nBar - 0: B - -/(?s)(.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(?s:.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/^.*B/ - **** Failers -No match - abc\nB -No match - -/(?s)^.*B/ - abc\nB - 0: abc\x0aB - -/(?m)^.*B/ - abc\nB - 0: B - -/(?ms)^.*B/ - abc\nB - 0: abc\x0aB - -/(?ms)^B/ - abc\nB - 0: B - -/(?s)B$/ - B\n - 0: B - -/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ - 123456654321 - 0: 123456654321 - -/^\d\d\d\d\d\d\d\d\d\d\d\d/ - 123456654321 - 0: 123456654321 - -/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ - 123456654321 - 0: 123456654321 - -/^[abc]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^[a-c]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^(a|b|c){12}/ - abcabcabcabc - 0: abcabcabcabc - -/^[abcdefghijklmnopqrstuvwxy0123456789]/ - n - 0: n - *** Failers -No match - z -No match - -/abcde{0,0}/ - abcd - 0: abcd - *** Failers -No match - abce -No match - -/ab[cd]{0,0}e/ - abe - 0: abe - *** Failers -No match - abcde -No match - -/ab(c){0,0}d/ - abd - 0: abd - *** Failers -No match - abcd -No match - -/a(b*)/ - a - 0: a - ab - 0: ab - 1: a - abbbb - 0: abbbb - 1: abbb - 2: abb - 3: ab - 4: a - *** Failers - 0: a - bbbbb -No match - -/ab\d{0}e/ - abe - 0: abe - *** Failers -No match - ab1e -No match - -/"([^\\"]+|\\.)*"/ - the \"quick\" brown fox - 0: "quick" - \"the \\\"quick\\\" brown fox\" - 0: "the \"quick\" brown fox" - -/.*?/g+ - abc - 0: abc - 0+ - 1: ab - 2: a - 3: - 0: - 0+ - -/\b/g+ - abc - 0: - 0+ abc - 0: - 0+ - -/\b/+g - abc - 0: - 0+ abc - 0: - 0+ - -//g - abc - 0: - 0: - 0: - 0: - -/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is - 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide - 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide - -/a[^a]b/ - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/ - acb - 0: acb - *** Failers -No match - a\nb -No match - -/a[^a]b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/^(b+?|a){1,2}?c/ - bac - 0: bac - bbac - 0: bbac - bbbac - 0: bbbac - bbbbac - 0: bbbbac - bbbbbac - 0: bbbbbac - -/^(b+|a){1,2}?c/ - bac - 0: bac - bbac - 0: bbac - bbbac - 0: bbbac - bbbbac - 0: bbbbac - bbbbbac - 0: bbbbbac - -/(?!\A)x/m - x\nb\n -No match - a\bx\n - 0: x - -/\x0{ab}/ - \0{ab} - 0: \x00{ab} - -/(A|B)*?CD/ - CD - 0: CD - -/(A|B)*CD/ - CD - 0: CD - -/(?.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ -No match - -"(?>.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - -/(?>(\.\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 -No match - -/^((?>\w+)|(?>\s+))*$/ - now is the time for all good men to come to the aid of the party - 0: now is the time for all good men to come to the aid of the party - *** Failers -No match - this is not a line with only words and spaces! -No match - -/(\d+)(\w)/ - 12345a - 0: 12345a - 1: 12345 - 2: 1234 - 3: 123 - 4: 12 - 12345+ - 0: 12345 - 1: 1234 - 2: 123 - 3: 12 - -/((?>\d+))(\w)/ - 12345a - 0: 12345a - *** Failers -No match - 12345+ -No match - -/(?>a+)b/ - aaab - 0: aaab - -/((?>a+)b)/ - aaab - 0: aaab - -/(?>(a+))b/ - aaab - 0: aaab - -/(?>b)+/ - aaabbbccc - 0: bbb - 1: bb - 2: b - -/(?>a+|b+|c+)*c/ - aaabbbbccccd - 0: aaabbbbcccc - 1: aaabbbbc - -/(a+|b+|c+)*c/ - aaabbbbccccd - 0: aaabbbbcccc - 1: aaabbbbccc - 2: aaabbbbcc - 3: aaabbbbc - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: abc(ade)ufh()() - 2: abc(ade)ufh() - 3: abc(ade)ufh - 4: abc(ade) - 5: abc - -/\(((?>[^()]+)|\([^()]+\))+\)/ - (abc) - 0: (abc) - (abc(def)xyz) - 0: (abc(def)xyz) - *** Failers -No match - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/a(?-i)b/i - ab - 0: ab - Ab - 0: Ab - *** Failers -No match - aB -No match - AB -No match - -/(a (?x)b c)d e/ - a bcd e - 0: a bcd e - *** Failers -No match - a b cd e -No match - abcd e -No match - a bcde -No match - -/(a b(?x)c d (?-x)e f)/ - a bcde f - 0: a bcde f - *** Failers -No match - abcdef -No match - -/(a(?i)b)c/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - abC -No match - aBC -No match - Abc -No match - ABc -No match - ABC -No match - AbC -No match - -/a(?i:b)c/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - ABC -No match - abC -No match - aBC -No match - -/a(?i:b)*c/ - aBc - 0: aBc - aBBc - 0: aBBc - *** Failers -No match - aBC -No match - aBBC -No match - -/a(?=b(?i)c)\w\wd/ - abcd - 0: abcd - abCd - 0: abCd - *** Failers -No match - aBCd -No match - abcD -No match - -/(?s-i:more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million - *** Failers -No match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?:(?s-i)more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million - *** Failers -No match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?>a(?i)b+)+c/ - abc - 0: abc - aBbc - 0: aBbc - aBBc - 0: aBBc - *** Failers -No match - Abc -No match - abAb -No match - abbC -No match - -/(?=a(?i)b)\w\wc/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - Ab -No match - abC -No match - aBC -No match - -/(?<=a(?i)b)(\w\w)c/ - abxxc - 0: xxc - aBxxc - 0: xxc - *** Failers -No match - Abxxc -No match - ABxxc -No match - abxxC -No match - -/^(?(?=abc)\w{3}:|\d\d)$/ - abc: - 0: abc: - 12 - 0: 12 - *** Failers -No match - 123 -No match - xyz -No match - -/^(?(?!abc)\d\d|\w{3}:)$/ - abc: - 0: abc: - 12 - 0: 12 - *** Failers -No match - 123 -No match - xyz -No match - -/(?(?<=foo)bar|cat)/ - foobar - 0: bar - cat - 0: cat - fcat - 0: cat - focat - 0: cat - *** Failers -No match - foocat -No match - -/(?(?a*)*/ - a - 0: a - 1: - aa - 0: aa - 1: - aaaa - 0: aaaa - 1: - -/(abc|)+/ - abc - 0: abc - 1: - abcabc - 0: abcabc - 1: abc - 2: - abcabcabc - 0: abcabcabc - 1: abcabc - 2: abc - 3: - xyz - 0: - -/([a]*)*/ - a - 0: a - 1: - aaaaa - 0: aaaaa - 1: aaaa - 2: aaa - 3: aa - 4: a - 5: - -/([ab]*)*/ - a - 0: a - 1: - b - 0: b - 1: - ababab - 0: ababab - 1: ababa - 2: abab - 3: aba - 4: ab - 5: a - 6: - aaaabcde - 0: aaaab - 1: aaaa - 2: aaa - 3: aa - 4: a - 5: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - -/([^a]*)*/ - b - 0: b - 1: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - aaa - 0: - -/([^ab]*)*/ - cccc - 0: cccc - 1: ccc - 2: cc - 3: c - 4: - abab - 0: - -/([a]*?)*/ - a - 0: a - 1: - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/([ab]*?)*/ - a - 0: a - 1: - b - 0: b - 1: - abab - 0: abab - 1: aba - 2: ab - 3: a - 4: - baba - 0: baba - 1: bab - 2: ba - 3: b - 4: - -/([^a]*?)*/ - b - 0: b - 1: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - aaa - 0: - -/([^ab]*?)*/ - c - 0: c - 1: - cccc - 0: cccc - 1: ccc - 2: cc - 3: c - 4: - baba - 0: - -/(?>a*)*/ - a - 0: a - 1: - aaabcde - 0: aaa - 1: - -/((?>a*))*/ - aaaaa - 0: aaaaa - 1: - aabbaa - 0: aa - 1: - -/((?>a*?))*/ - aaaaa - 0: aaaaa - 1: - aabbaa - 0: aa - 1: - -/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x - 12-sep-98 - 0: 12-sep-98 - 12-09-98 - 0: 12-09-98 - *** Failers -No match - sep-12-98 -No match - -/(?i:saturday|sunday)/ - saturday - 0: saturday - sunday - 0: sunday - Saturday - 0: Saturday - Sunday - 0: Sunday - SATURDAY - 0: SATURDAY - SUNDAY - 0: SUNDAY - SunDay - 0: SunDay - -/(a(?i)bc|BB)x/ - abcx - 0: abcx - aBCx - 0: aBCx - bbx - 0: bbx - BBx - 0: BBx - *** Failers -No match - abcX -No match - aBCX -No match - bbX -No match - BBX -No match - -/^([ab](?i)[cd]|[ef])/ - ac - 0: ac - aC - 0: aC - bD - 0: bD - elephant - 0: e - Europe - 0: E - frog - 0: f - France - 0: F - *** Failers -No match - Africa -No match - -/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ - ab - 0: ab - aBd - 0: aBd - xy - 0: xy - xY - 0: xY - zebra - 0: z - Zambesi - 0: Z - *** Failers -No match - aCD -No match - XY -No match - -/(?<=foo\n)^bar/m - foo\nbar - 0: bar - *** Failers -No match - bar -No match - baz\nbar -No match - -/(?<=(?]&/ - <&OUT - 0: <& - -/(?:(f)(o)(o)|(b)(a)(r))*/ - foobar - 0: foobar - 1: foo - 2: - -/(?<=a)b/ - ab - 0: b - *** Failers -No match - cb -No match - b -No match - -/(?a+)ab/ - -/(?>a+)b/ - aaab - 0: aaab - -/([[:]+)/ - a:[b]: - 0: :[ - 1: : - -/([[=]+)/ - a=[b]= - 0: =[ - 1: = - -/([[.]+)/ - a.[b]. - 0: .[ - 1: . - -/((?>a+)b)/ - aaab - 0: aaab - -/(?>(a+))b/ - aaab - 0: aaab - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: abc(ade)ufh()() - 2: abc(ade)ufh() - 3: abc(ade)ufh - 4: abc(ade) - 5: abc - -/a\Z/ - *** Failers -No match - aaab -No match - a\nb\n -No match - -/b\Z/ - a\nb\n - 0: b - -/b\z/ - -/b\Z/ - a\nb - 0: b - -/b\z/ - a\nb - 0: b - *** Failers -No match -/(?>.*)(?<=(abcd|wxyz))/ - alphabetabcd - 0: alphabetabcd - endingwxyz - 0: endingwxyz - *** Failers -No match - a rather long string that doesn't end with one of them -No match +/-- These Unicode 6.1.0 scripts are not known to Perl. --/ -/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match +/\p{Chakma}\d/8W + \x{11100}\x{1113c} + 0: \x{11100}\x{1113c} -/(?<=\d{3}(?!999))foo/ - 999foo - 0: foo - 123999foo - 0: foo - *** Failers -No match - 123abcfoo -No match +/\p{Takri}\d/8W + \x{11680}\x{116c0} + 0: \x{11680}\x{116c0} + +/^\X/8 + A\P + 0: A + A\P\P +Partial match: A + A\x{300}\x{301}\P + 0: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{301}\P + 0: A\x{301} + A\x{301}\P\P +Partial match: A\x{301} -/(?<=(?!...999)\d{3})foo/ - 999foo - 0: foo - 123999foo - 0: foo - *** Failers -No match - 123abcfoo -No match +/^\X{2,3}/8 + A\P +Partial match: A + A\P\P +Partial match: A + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} -/(?<=\d{3}(?!999)...)foo/ - 123abcfoo - 0: foo - 123456foo - 0: foo - *** Failers -No match - 123999foo -No match +/^\X{2}/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} -/(?<=\d{3}...)(?Z)+|A)*/ - ZABCDEFG - 0: ZA - 1: Z - 2: - -/((?>)+|A)*/ - ZABCDEFG - 0: - -/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 - -things - 0: - - 0digit - 0: 0 - *** Failers -No match - bcdef -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: - -/\s+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d - 1: \x09\x0a\x0c - 2: \x09\x0a - 3: \x09 - 4: - -/a b/x - ab -No match - -/(?!\A)x/m - a\nxb\n - 0: x - -/(?!^)x/m - a\nxb\n -No match - -/abc\Qabc\Eabc/ - abcabcabc - 0: abcabcabc - -/abc\Q(*+|\Eabc/ - abc(*+|abc - 0: abc(*+|abc - -/ abc\Q abc\Eabc/x - abc abcabc - 0: abc abcabc - *** Failers -No match - abcabcabc -No match - -/abc#comment - \Q#not comment - literal\E/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal\E #more comment - /x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal\E #more comment/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/\Qabc\$xyz\E/ - abc\\\$xyz - 0: abc\$xyz - -/\Qabc\E\$\Qxyz\E/ - abc\$xyz - 0: abc$xyz - -/\Gabc/ - abc - 0: abc - *** Failers -No match - xyzabc -No match - -/\Gabc./g - abc1abc2xyzabc3 - 0: abc1 - 0: abc2 - -/abc./g - abc1abc2xyzabc3 - 0: abc1 - 0: abc2 - 0: abc3 - -/a(?x: b c )d/ - XabcdY - 0: abcd - *** Failers -No match - Xa b c d Y -No match - -/((?x)x y z | a b c)/ - XabcY - 0: abc - AxyzB - 0: xyz - -/(?i)AB(?-i)C/ - XabCY - 0: abC - *** Failers -No match - XabcY -No match - -/((?i)AB(?-i)C|D)E/ - abCE - 0: abCE - DE - 0: DE - *** Failers -No match - abcE -No match - abCe -No match - dE -No match - De -No match - -/[z\Qa-d]\E]/ - z - 0: z - a - 0: a - - - 0: - - d - 0: d - ] - 0: ] - *** Failers - 0: a - b -No match - -/[\z\C]/ - z - 0: z - C - 0: C - -/\M/ - M - 0: M - -/(a+)*b/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ - REGular - 0: REGular - regulaer - 0: regulaer - Regex - 0: Regex - regulär - 0: regul\xe4r - -/Åæåä[à-ÿÀ-ß]+/ - Åæåäà - 0: \xc5\xe6\xe5\xe4\xe0 - Åæåäÿ - 0: \xc5\xe6\xe5\xe4\xff - ÅæåäÀ - 0: \xc5\xe6\xe5\xe4\xc0 - Åæåäß - 0: \xc5\xe6\xe5\xe4\xdf - -/(?<=Z)X./ - \x84XAZXB - 0: XB - -/^(?(2)a|(1)(2))+$/ - 123a -Error -17 - -/(?<=a|bbbb)c/ - ac - 0: c - bbbbc - 0: c - -/abc/>testsavedregex -Compiled regex written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex - - 0: abc - xyz\r\nabc\ - 0: abc - xyz\rabc\ - 0: abc - xyz\r\nabc\ - 0: abc - ** Failers -No match - xyz\nabc\ -No match - xyz\r\nabc\ -No match - xyz\nabc\ -No match - xyz\rabc\ -No match - xyz\rabc\ -No match - -/abc$/m - xyzabc - 0: abc - xyzabc\n - 0: abc - xyzabc\npqr - 0: abc - xyzabc\r\ - 0: abc - xyzabc\rpqr\ - 0: abc - xyzabc\r\n\ - 0: abc - xyzabc\r\npqr\ - 0: abc - ** Failers -No match - xyzabc\r -No match - xyzabc\rpqr -No match - xyzabc\r\n -No match - xyzabc\r\npqr -No match - -/^abc/m - xyz\rabcdef - 0: abc - xyz\nabcdef\ - 0: abc - ** Failers -No match - xyz\nabcdef -No match - -/^abc/m - xyz\nabcdef - 0: abc - xyz\rabcdef\ - 0: abc - ** Failers -No match - xyz\rabcdef -No match - -/^abc/m - xyz\r\nabcdef - 0: abc - xyz\rabcdef\ - 0: abc - ** Failers -No match - xyz\rabcdef -No match - -/.*/ - 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: - \abc\ndef - 0: abc\x0adef - 1: abc\x0ade - 2: abc\x0ad - 3: abc\x0a - 4: abc - 5: ab - 6: a - 7: - \abc\rdef - 0: abc - 1: ab - 2: a - 3: - \abc\r\ndef - 0: abc - 1: ab - 2: a - 3: - \abc\ndef - 0: abc\x0adef - 1: abc\x0ade - 2: abc\x0ad - 3: abc\x0a - 4: abc - 5: ab - 6: a - 7: - \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 - 1: ab - 2: a - 3: - -/\w+(.)(.)?def/s - abc\ndef - 0: abc\x0adef - abc\rdef - 0: abc\x0ddef - abc\r\ndef - 0: abc\x0d\x0adef - -/^\w+=.*(\\\n.*)*/ - abc=xyz\\\npqr - 0: abc=xyz\\x0apqr - 1: abc=xyz\\x0apq - 2: abc=xyz\\x0ap - 3: abc=xyz\\x0a - 4: abc=xyz\ - 5: abc=xyz - 6: abc=xy - 7: abc=x - 8: abc= - -/^(a()*)*/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/^(?:a(?:(?:))*)*/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/^(a()+)+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/^(?:a(?:(?:))+)+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/(a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?>a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?:a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/^a.b/ - a\rb - 0: a\x0db - a\nb\ - 0: a\x0ab - ** Failers -No match - a\nb -No match - a\nb\ -No match - a\rb\ -No match - a\rb\ -No match - -/^abc./mgx - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK - 0: abc1 - 0: abc2 - 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc7 - -/abc.$/mgx - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 - 0: abc1 - 0: abc2 - 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc9 - -/^a\Rb/ - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b - ** Failers -No match - a\n\rb -No match - -/^a\R*b/ - ab - 0: ab - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b - a\n\rb - 0: a\x0a\x0db - a\n\r\x85\x0cb - 0: a\x0a\x0d\x85\x0cb - -/^a\R+b/ - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b - a\n\rb - 0: a\x0a\x0db - a\n\r\x85\x0cb - 0: a\x0a\x0d\x85\x0cb - ** Failers -No match - ab -No match - -/^a\R{1,3}b/ - a\nb - 0: a\x0ab - a\n\rb - 0: a\x0a\x0db - a\n\r\x85b - 0: a\x0a\x0d\x85b - a\r\n\r\nb - 0: a\x0d\x0a\x0d\x0ab - a\r\n\r\n\r\nb - 0: a\x0d\x0a\x0d\x0a\x0d\x0ab - a\n\r\n\rb - 0: a\x0a\x0d\x0a\x0db - a\n\n\r\nb - 0: a\x0a\x0a\x0d\x0ab - ** Failers -No match - a\n\n\n\rb -No match - a\r -No match - -/^a[\R]b/ - aRb - 0: aRb - ** Failers -No match - a\nb -No match - -/.+foo/ - afoo - 0: afoo - ** Failers -No match - \r\nfoo -No match - \nfoo -No match - -/.+foo/ - afoo - 0: afoo - \nfoo - 0: \x0afoo - ** Failers -No match - \r\nfoo -No match - -/.+foo/ - afoo - 0: afoo - ** Failers -No match - \nfoo -No match - \r\nfoo -No match - -/.+foo/s - afoo - 0: afoo - \r\nfoo - 0: \x0d\x0afoo - \nfoo - 0: \x0afoo - -/^$/mg - abc\r\rxyz - 0: - abc\n\rxyz - 0: - ** Failers -No match - abc\r\nxyz -No match - -/^X/m - XABC - 0: X - ** Failers -No match - XABC\B -No match - -/(?m)^$/g+ - abc\r\n\r\n - 0: - 0+ \x0d\x0a - -/(?m)^$|^\r\n/g+ - abc\r\n\r\n - 0: \x0d\x0a - 0+ - 1: - -/(?m)$/g+ - abc\r\n\r\n - 0: - 0+ \x0d\x0a\x0d\x0a - 0: - 0+ \x0d\x0a - 0: - 0+ - -/(?|(abc)|(xyz))/ - >abc< - 0: abc - >xyz< - 0: xyz - -/(x)(?|(abc)|(xyz))(x)/ - xabcx - 0: xabcx - xxyzx - 0: xxyzx - -/(x)(?|(abc)(pqr)|(xyz))(x)/ - xabcpqrx - 0: xabcpqrx - xxyzx - 0: xxyzx - -/(?|(abc)|(xyz))(?1)/ - abcabc - 0: abcabc - xyzabc - 0: xyzabc - ** Failers -No match - xyzxyz -No match - -/\H\h\V\v/ - X X\x0a - 0: X X\x0a - X\x09X\x0b - 0: X\x09X\x0b - ** Failers -No match - \xa0 X\x0a -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 -No match - \x09\x20\xa0\x0a\x0b -No match - -/\H{3,4}/ - XY ABCDE - 0: ABCD - 1: ABC - XY PQR ST - 0: PQR - -/.\h{3,4}./ - XY AB PQRS - 0: B P - 1: B - -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - 0: XNNNYZ - > X NYQZ - 0: X NYQZ - ** Failers -No match - >XYZ -No match - > X NY Z -No match - -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - 0: XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - -/.+A/ - \r\nA -No match - -/\nA/ - \r\nA - 0: \x0aA - -/[\r\n]A/ - \r\nA - 0: \x0aA - -/(\r|\n)A/ - \r\nA - 0: \x0aA - -/a\Rb/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - ** Failers -No match - a\x85b -No match - a\x0bb -No match - -/a\Rb/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - a\x85b - 0: a\x85b - a\x0bb - 0: a\x0bb - ** Failers -No match - a\x85b\ -No match - a\x0bb\ -No match - -/a\R?b/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - ** Failers -No match - a\x85b -No match - a\x0bb -No match - -/a\R?b/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - a\x85b - 0: a\x85b - a\x0bb - 0: a\x0bb - ** Failers -No match - a\x85b\ -No match - a\x0bb\ -No match - -/a\R{2,4}b/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\r\n\nb - 0: a\x0d\x0a\x0ab - a\n\r\rb - 0: a\x0a\x0d\x0db - a\r\n\r\n\r\n\r\nb - 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab - ** Failers -No match - a\x85\85b -No match - a\x0b\0bb -No match - -/a\R{2,4}b/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\r\rb - 0: a\x0d\x0db - a\n\n\nb - 0: a\x0a\x0a\x0ab - a\r\n\n\r\rb - 0: a\x0d\x0a\x0a\x0d\x0db - a\x85\85b -No match - a\x0b\0bb -No match - ** Failers -No match - a\r\r\r\r\rb -No match - a\x85\85b\ -No match - a\x0b\0bb\ -No match - -/a(?!)|\wbc/ - abc - 0: abc - -/a[]b/ - ** Failers -No match - ab -No match - -/a[]+b/ - ** Failers -No match - ab -No match - -/a[]*+b/ - ** Failers -No match - ab -No match - -/a[^]b/ - aXb - 0: aXb - a\nb - 0: a\x0ab - ** Failers -No match - ab -No match - -/a[^]+b/ - aXb - 0: aXb - a\nX\nXb - 0: a\x0aX\x0aXb - ** Failers -No match - ab -No match - -/X$/E - X - 0: X - ** Failers -No match - X\n -No match - -/X$/ - X - 0: X - X\n - 0: X - -/xyz/C - xyz ---->xyz - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - abcxyz ---->abcxyz - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - abcxyz\Y ---->abcxyz - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - ** Failers -No match - abc -No match - abc\Y ---->abc - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x -No match - abcxypqr -No match - abcxypqr\Y ---->abcxypqr - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x -No match - -/(*NO_START_OPT)xyz/C - abcxyz ---->abcxyz -+15 ^ x -+15 ^ x -+15 ^ x -+15 ^ x -+16 ^^ y -+17 ^ ^ z -+18 ^ ^ - 0: xyz - -/(?C)ab/ - ab ---->ab - 0 ^ a - 0: ab - \C-ab - 0: ab - -/ab/C - ab ---->ab - +0 ^ a - +1 ^^ b - +2 ^ ^ - 0: ab - \C-ab - 0: ab - -/^"((?(?=[a])[^"])|b)*"$/C - "ab" ---->"ab" - +0 ^ ^ - +1 ^ " - +2 ^^ ((?(?=[a])[^"])|b)* -+21 ^^ " - +3 ^^ (?(?=[a])[^"]) -+18 ^^ b - +5 ^^ (?=[a]) - +8 ^ [a] -+11 ^^ ) -+12 ^^ [^"] -+16 ^ ^ ) -+17 ^ ^ | -+21 ^ ^ " - +3 ^ ^ (?(?=[a])[^"]) -+18 ^ ^ b - +5 ^ ^ (?=[a]) - +8 ^ [a] -+19 ^ ^ ) -+21 ^ ^ " - +3 ^ ^ (?(?=[a])[^"]) -+18 ^ ^ b - +5 ^ ^ (?=[a]) - +8 ^ [a] -+17 ^ ^ | -+22 ^ ^ $ -+23 ^ ^ - 0: "ab" - \C-"ab" - 0: "ab" - -/\d+X|9+Y/ - ++++123999\P -Partial match: 123999 - ++++123999Y\P - 0: 999Y - -/Z(*F)/ - Z\P -No match - ZA\P -No match - -/Z(?!)/ - Z\P -No match - ZA\P -No match - -/dog(sbody)?/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dog(sbody)??/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dog|dogsbody/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dogsbody|dog/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/Z(*F)Q|ZXY/ - Z\P -Partial match: Z - ZA\P -No match - X\P -No match - -/\bthe cat\b/ - the cat\P - 0: the cat - the cat\P\P -Partial match: the cat - -/dog(sbody)?/ - dogs\D\P - 0: dog - body\D\R - 0: body - -/dog(sbody)?/ - dogs\D\P\P -Partial match: dogs - body\D\R - 0: body - -/abc/ - abc\P - 0: abc - abc\P\P - 0: abc - -/abc\K123/ - xyzabc123pqr -Error -16 - -/(?<=abc)123/ - xyzabc123pqr - 0: 123 - xyzabc12\P -Partial match: abc12 - xyzabc12\P\P -Partial match: abc12 - -/\babc\b/ - +++abc+++ - 0: abc - +++ab\P -Partial match: +ab - +++ab\P\P -Partial match: +ab - -/(?=C)/g+ - ABCDECBA - 0: - 0+ CDECBA - 0: - 0+ CBA - -/(abc|def|xyz)/I -Capturing subpattern count = 1 -No options -No first char -No need char - terhjk;abcdaadsfe - 0: abc - the quick xyz brown fox - 0: xyz - \Yterhjk;abcdaadsfe - 0: abc - \Ythe quick xyz brown fox - 0: xyz - ** Failers -No match - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - -/(abc|def|xyz)/SI -Capturing subpattern count = 1 -No options -No first char -No need char -Subject length lower bound = 3 -Starting byte set: a d x - terhjk;abcdaadsfe - 0: abc - the quick xyz brown fox - 0: xyz - \Yterhjk;abcdaadsfe - 0: abc - \Ythe quick xyz brown fox - 0: xyz - ** Failers -No match - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - -/abcd*/+ - 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 - 0: - 0+ xxx - -/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 - -/(?:(?1)|B)(A(*F)|C)/ - ABCD - 0: BC - CCD - 0: CC - ** Failers -No match - CAD -No match - -/^(?:(?1)|B)(A(*F)|C)/ - CCD - 0: CC - BCD - 0: BC - ** Failers -No match - ABCD -No match - CAD -No match - BAD -No match - -/^(?!a(*SKIP)b)/ - ac -Error -16 - -/^(?=a(*SKIP)b|ac)/ - ** Failers -No match - ac -Error -16 - -/^(?=a(*THEN)b|ac)/ - ac -Error -16 - -/^(?=a(*PRUNE)b)/ - ab -Error -16 - ** Failers -No match - ac -Error -16 - -/^(?(?!a(*SKIP)b))/ - ac -Error -16 - -/(?<=abc)def/ - abc\P\P -Partial match: abc - -/abc$/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc - -/abc$/m - abc - 0: abc - abc\n - 0: abc - abc\P\P -Partial match: abc - abc\n\P\P - 0: abc - abc\P - 0: abc - abc\n\P - 0: abc - -/abc\z/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc - -/abc\Z/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc - -/abc\b/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc - -/abc\B/ - abc -No match - abc\P -Partial match: abc - abc\P\P -Partial match: abc - -/.+/ - abc\>0 - 0: abc - 1: ab - 2: a - abc\>1 - 0: bc - 1: b - abc\>2 - 0: c - abc\>3 -No match - abc\>4 -Error -24 - abc\>-4 -Error -24 +/^\X+/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + +/^\X+?Z/8 + AA\P +Partial match: AA + AA\P\P +Partial match: AA /-- End of testinput7 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput8 b/ext/pcre/pcrelib/testdata/testoutput8 index f4f5343ef21..73e0eae87ba 100644 --- a/ext/pcre/pcrelib/testdata/testoutput8 +++ b/ext/pcre/pcrelib/testdata/testoutput8 @@ -1,531 +1,445 @@ -/-- 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. --/ - -/\x{100}ab/8 - \x{100}ab - 0: \x{100}ab - -/a\x{100}*b/8 - ab - 0: ab - a\x{100}b - 0: a\x{100}b - a\x{100}\x{100}b - 0: a\x{100}\x{100}b - -/a\x{100}+b/8 - a\x{100}b - 0: a\x{100}b - a\x{100}\x{100}b - 0: a\x{100}\x{100}b - *** Failers -No match - ab -No match +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). + The -dfa flag must be used with pcretest when running it. --/ -/\bX/8 - Xoanon - 0: X - +Xoanon - 0: X - \x{300}Xoanon - 0: X +/abc/ + abc + 0: abc + +/ab*c/ + abc + 0: abc + abbbbc + 0: abbbbc + ac + 0: ac + +/ab+c/ + abc + 0: abc + abbbbbbc + 0: abbbbbbc *** Failers No match - YXoanon + ac +No match + ab No match -/\BX/8 - YXoanon - 0: X +/a*/ + a + 0: a + 1: + aaaaaaaaaaaaaaaaa + 0: aaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaa + 4: aaaaaaaaaaaaa + 5: aaaaaaaaaaaa + 6: aaaaaaaaaaa + 7: aaaaaaaaaa + 8: aaaaaaaaa + 9: aaaaaaaa +10: aaaaaaa +11: aaaaaa +12: aaaaa +13: aaaa +14: aaa +15: aa +16: a +17: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many subsidiary matches + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaaaaaaaaaaaaaaa + 4: aaaaaaaaaaaaaaaaaaaaaaaaaa + 5: aaaaaaaaaaaaaaaaaaaaaaaaa + 6: aaaaaaaaaaaaaaaaaaaaaaaa + 7: aaaaaaaaaaaaaaaaaaaaaaa + 8: aaaaaaaaaaaaaaaaaaaaaa + 9: aaaaaaaaaaaaaaaaaaaaa +10: aaaaaaaaaaaaaaaaaaaa +11: aaaaaaaaaaaaaaaaaaa +12: aaaaaaaaaaaaaaaaaa +13: aaaaaaaaaaaaaaaaa +14: aaaaaaaaaaaaaaaa +15: aaaaaaaaaaaaaaa +16: aaaaaaaaaaaaaa +17: aaaaaaaaaaaaa +18: aaaaaaaaaaaa +19: aaaaaaaaaaa +20: aaaaaaaaaa +21: aaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F + 0: + +/(a|abcd|african)/ + a + 0: a + abcd + 0: abcd + 1: a + african + 0: african + 1: a + +/^abc/ + abcdef + 0: abc *** Failers No match - Xoanon + xyzabc No match - +Xoanon + xyz\nabc No match - \x{300}Xoanon + +/^abc/m + abcdef + 0: abc + xyz\nabc + 0: abc + *** Failers +No match + xyzabc +No match + +/\Aabc/ + abcdef + 0: abc + *** Failers +No match + xyzabc +No match + xyz\nabc +No match + +/\Aabc/m + abcdef + 0: abc + *** Failers +No match + xyzabc +No match + xyz\nabc +No match + +/\Gabc/ + abcdef + 0: abc + xyzabc\>3 + 0: abc + *** Failers +No match + xyzabc +No match + xyzabc\>2 +No match + +/x\dy\Dz/ + x9yzz + 0: x9yzz + x0y+z + 0: x0y+z + *** Failers +No match + xyz +No match + xxy0z +No match + +/x\sy\Sz/ + x yzz + 0: x yzz + x y+z + 0: x y+z + *** Failers +No match + xyz +No match + xxyyz +No match + +/x\wy\Wz/ + xxy+z + 0: xxy+z + *** Failers +No match + xxy0z +No match + x+y+z +No match + +/x.y/ + x+y + 0: x+y + x-y + 0: x-y + *** Failers +No match + x\ny +No match + +/x.y/s + x+y + 0: x+y + x-y + 0: x-y + x\ny + 0: x\x0ay + +/(a.b(?s)c.d|x.y)p.q/ + a+bc+dp+q + 0: a+bc+dp+q + a+bc\ndp+q + 0: a+bc\x0adp+q + x\nyp+q + 0: x\x0ayp+q + *** Failers +No match + a\nbc\ndp+q +No match + a+bc\ndp\nq +No match + x\nyp\nq No match -/X\b/8 - X+oanon - 0: X - ZX\x{300}oanon - 0: X - FAX - 0: X - *** Failers -No match - Xoanon -No match - -/X\B/8 - Xoanon - 0: X +/a\d\z/ + ba0 + 0: a0 *** Failers No match - X+oanon + ba0\n No match - ZX\x{300}oanon + ba0\ncd No match - FAX + +/a\d\z/m + ba0 + 0: a0 + *** Failers No match + ba0\n +No match + ba0\ncd +No match + +/a\d\Z/ + ba0 + 0: a0 + ba0\n + 0: a0 + *** Failers +No match + ba0\ncd +No match + +/a\d\Z/m + ba0 + 0: a0 + ba0\n + 0: a0 + *** Failers +No match + ba0\ncd +No match + +/a\d$/ + ba0 + 0: a0 + ba0\n + 0: a0 + *** Failers +No match + ba0\ncd +No match + +/a\d$/m + ba0 + 0: a0 + ba0\n + 0: a0 + ba0\ncd + 0: a0 + *** Failers +No match + +/abc/i + abc + 0: abc + aBc + 0: aBc + ABC + 0: ABC -/[^a]/8 +/[^a]/ abcd 0: b - a\x{100} - 0: \x{100} - -/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 - ab99 - 0: ab9 - \x{123}\x{123}45 - 0: \x{123}\x{123}4 - \x{400}\x{401}\x{402}6 - 0: \x{400}\x{401}\x{402}6 - *** Failers -No match - d99 -No match - \x{123}\x{122}4 -No match - \x{400}\x{403}6 -No match - \x{400}\x{401}\x{402}\x{402}6 -No match - -/abc/8 - Ã] -Error -10 - à -Error -10 - ÃÃà -Error -10 - ÃÃÃ\? -No match - \xe1\x88 -Error -10 - \P\xe1\x88 -Error -10 - \P\P\xe1\x88 -Error -25 - -/a.b/8 - acb - 0: acb - a\x7fb - 0: a\x{7f}b - a\x{100}b - 0: a\x{100}b - *** Failers -No match - a\nb -No match - -/a(.{3})b/8 - a\x{4000}xyb - 0: a\x{4000}xyb - a\x{4000}\x7fyb - 0: a\x{4000}\x{7f}yb - a\x{4000}\x{100}yb - 0: a\x{4000}\x{100}yb - *** Failers -No match - a\x{4000}b -No match - ac\ncb -No match - -/a(.*?)(.)/ - a\xc0\x88b - 0: a\xc0\x88b - 1: a\xc0\x88 - 2: a\xc0 - -/a(.*?)(.)/8 - a\x{100}b - 0: a\x{100}b - 1: a\x{100} - -/a(.*)(.)/ - a\xc0\x88b - 0: a\xc0\x88b - 1: a\xc0\x88 - 2: a\xc0 - -/a(.*)(.)/8 - a\x{100}b - 0: a\x{100}b - 1: a\x{100} - -/a(.)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - -/a(.)(.)/8 - a\x{240}bcd - 0: a\x{240}b - -/a(.?)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - 1: a\xc0 - -/a(.?)(.)/8 - a\x{240}bcd - 0: a\x{240}b - 1: a\x{240} - -/a(.??)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - 1: a\xc0 - -/a(.??)(.)/8 - a\x{240}bcd - 0: a\x{240}b - 1: a\x{240} - -/a(.{3})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - *** Failers -No match - a\x{1234}b -No match - ac\ncb -No match - -/a(.{3,})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxbcdefghijb - 1: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - *** Failers -No match - a\x{1234}b -No match - -/a(.{3,}?)b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxbcdefghijb - 1: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - *** Failers -No match - a\x{1234}b -No match - -/a(.{3,5})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - 0: axbxxb - axxxxxbcdefghijb - 0: axxxxxb - *** Failers -No match - a\x{1234}b -No match - axxxxxxbcdefghijb -No match - -/a(.{3,5}?)b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - 0: axbxxb - axxxxxbcdefghijb - 0: axxxxxb - *** Failers -No match - a\x{1234}b -No match - axxxxxxbcdefghijb -No match - -/^[a\x{c0}]/8 - *** Failers -No match - \x{100} -No match - -/(?<=aXb)cd/8 - aXbcd - 0: cd - -/(?<=a\x{100}b)cd/8 - a\x{100}bcd - 0: cd - -/(?<=a\x{100000}b)cd/8 - a\x{100000}bcd - 0: cd -/(?:\x{100}){3}b/8 - \x{100}\x{100}\x{100}b - 0: \x{100}\x{100}\x{100}b - *** Failers -No match - \x{100}\x{100}b -No match +/ab?\w/ + abz + 0: abz + 1: ab + abbz + 0: abb + 1: ab + azz + 0: az -/\x{ab}/8 - \x{ab} - 0: \x{ab} - \xc2\xab - 0: \x{ab} - *** Failers -No match - \x00{ab} -No match - -/(?<=(.))X/8 - WXYZ - 0: X - \x{256}XYZ - 0: X +/x{0,3}yz/ + ayzq + 0: yz + axyzq + 0: xyz + axxyz + 0: xxyz + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz *** Failers No match - XYZ + ax +No match + axx +No match + +/x{3}yz/ + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz + *** Failers +No match + ax +No match + axx +No match + ayzq +No match + axyzq +No match + axxyz +No match + +/x{2,3}yz/ + axxyz + 0: xxyz + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz + *** Failers +No match + ax +No match + axx +No match + ayzq +No match + axyzq +No match + +/[^a]+/ + bac + 0: b + bcdefax + 0: bcdef + 1: bcde + 2: bcd + 3: bc + 4: b + *** Failers + 0: *** F + 1: *** + 2: *** + 3: ** + 4: * + aaaaa 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 - 0: \x{100}b - -/^[^a]{2,}/8 - \x{100}bcAa - 0: \x{100}bcA - 1: \x{100}bc - 2: \x{100}b - -/^[^a]{2,}?/8 - \x{100}bca - 0: \x{100}bc - 1: \x{100}b - -/[^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 - 0: \x{100}b - -/^[^a]{2,}/8i - \x{100}bcAa - 0: \x{100}bc - 1: \x{100}b - -/^[^a]{2,}?/8i - \x{100}bca - 0: \x{100}bc - 1: \x{100}b - -/\x{100}{0,0}/8 - abcd - 0: - -/\x{100}?/8 - abcd - 0: - \x{100}\x{100} - 0: \x{100} +/[^a]*/ + bac + 0: b 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 + bcdefax + 0: bcdef + 1: bcde + 2: bcd + 3: bc + 4: b + 5: + *** Failers + 0: *** F + 1: *** + 2: *** + 3: ** + 4: * + 5: + aaaaa 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} + +/[^a]{3,5}/ + xyz + 0: xyz + awxyza + 0: wxyz + 1: wxy + abcdefa + 0: bcdef + 1: bcde + 2: bcd + abcdefghijk + 0: bcdef + 1: bcde + 2: bcd + *** Failers + 0: *** F + 1: *** + 2: *** + axya +No match + axa +No match + aaaaa +No match + +/\d*/ + 1234b567 + 0: 1234 + 1: 123 + 2: 12 + 3: 1 4: - -/\x{100}{1,1}/8 - abcd\x{100}\x{100}\x{100}\x{100} - 0: \x{100} - -/\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 - 0: \x{100}\x{100}\x{100} - -/\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 - 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} - 2: \x{100}\x{100}\x{100}\x{100}\x{100} - 3: \x{100}\x{100}\x{100}\x{100} - 4: \x{100}\x{100}\x{100} - -/(?<=a\x{100}{2}b)X/8 - Xyyya\x{100}\x{100}bXzzz - 0: X - -/\D*/8 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 4: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 6: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 7: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 8: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 9: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -10: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -11: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -12: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -13: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -14: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -15: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -16: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -18: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -19: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/\D*/8 - \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 - 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} - 3: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 4: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 5: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 6: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 7: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 8: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 9: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -10: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -11: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -12: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -13: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -14: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -15: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -16: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -17: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -18: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -19: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -20: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -21: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 - 1X2 - 0: X - 1\x{100}2 - 0: \x{100} - -/>\S/8 - > >X Y - 0: >X - > >\x{100} Y - 0: >\x{100} - -/\d/8 - \x{100}3 - 0: 3 + xyz + 0: -/\s/8 - \x{100} X - 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 +No match -/\D+/8 - 12abcd34 - 0: abcd - 1: abc - 2: ab - 3: a +/\D+/ + ab123c56 + 0: ab + 1: a *** Failers 0: *** Failers 1: *** Failer @@ -538,603 +452,6455 @@ Matched, but too many subsidiary matches 8: *** 9: ** 10: * + 789 +No match + +/\d?A/ + 045ABC + 0: 5A + ABC + 0: A + *** Failers +No match + XYZ +No match + +/\D?A/ + ABC + 0: A + BAC + 0: BA + 9ABC + 0: A + *** Failers +No match + +/a+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/^.*xyz/ + xyz + 0: xyz + ggggggggxyz + 0: ggggggggxyz + +/^.+xyz/ + abcdxyz + 0: abcdxyz + axyz + 0: axyz + *** Failers +No match + xyz +No match + +/^.?xyz/ + xyz + 0: xyz + cxyz + 0: cxyz + +/^\d{2,3}X/ + 12X + 0: 12X + 123X + 0: 123X + *** Failers +No match + X +No match + 1X +No match + 1234X +No match + +/^[abcd]\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + *** Failers +No match + e45 +No match + abcd +No match + abcd1234 +No match 1234 No match -/\D{2,3}/8 - 12abcd34 +/^[abcd]*\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + abcd1234 + 0: abcd1 + 1234 + 0: 1 + *** Failers +No match + e45 +No match + abcd +No match + +/^[abcd]+\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + abcd1234 + 0: abcd1 + *** Failers +No match + 1234 +No match + e45 +No match + abcd +No match + +/^a+X/ + aX + 0: aX + aaX + 0: aaX + +/^[abcd]?\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + 1234 + 0: 1 + *** Failers +No match + abcd1234 +No match + e45 +No match + +/^[abcd]{2,3}\d/ + ab45 + 0: ab4 + bcd93 + 0: bcd9 + *** Failers +No match + 1234 +No match + a36 +No match + abcd1234 +No match + ee45 +No match + +/^(abc)*\d/ + abc45 + 0: abc4 + abcabcabc45 + 0: abcabcabc4 + 42xyz + 0: 4 + *** Failers +No match + +/^(abc)+\d/ + abc45 + 0: abc4 + abcabcabc45 + 0: abcabcabc4 + *** Failers +No match + 42xyz +No match + +/^(abc)?\d/ + abc45 + 0: abc4 + 42xyz + 0: 4 + *** Failers +No match + abcabcabc45 +No match + +/^(abc){2,3}\d/ + abcabc45 + 0: abcabc4 + abcabcabc45 + 0: abcabcabc4 + *** Failers +No match + abcabcabcabc45 +No match + abc45 +No match + 42xyz +No match + +/1(abc|xyz)2(?1)3/ + 1abc2abc3456 + 0: 1abc2abc3 + 1abc2xyz3456 + 0: 1abc2xyz3 + +/^(a*\w|ab)=(a*\w|ab)/ + ab=ab + 0: ab=ab + 1: ab=a + +/^(a*\w|ab)=(?1)/ + ab=ab + 0: ab=ab + 1: ab=a + +/^([^()]|\((?1)*\))*$/ + abc 0: abc - 1: ab - 12ab34 - 0: ab - *** Failers - 0: *** - 1: ** - 1234 + a(b)c + 0: a(b)c + a(b(c))d + 0: a(b(c))d + *** Failers) No match - 12a34 + a(b(c)d No match -/\D{2,3}?/8 - 12abcd34 - 0: abc - 1: ab - 12ab34 - 0: ab - *** Failers - 0: *** - 1: ** - 1234 -No match - 12a34 -No match +/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)\s+ <34 - 0: > < - *** Failers -No match - -/>\s{2,3} < - ab> < - *** Failers -No match - ab> \s{2,3}? < - ab> < - *** Failers -No match - ab> a*)\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9 *** Failers No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match -/[Z\x{100}]/8 - Z\x{100} - 0: Z - \x{100} - 0: \x{100} - \x{100}Z - 0: \x{100} +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x + <> + 0: <> + + 0: + hij> + 0: hij> + hij> + 0: + def> + 0: def> + + 0: <> + *** Failers +No match + abcxyz + 1 ^ ^ x + 0: abcxyz + 123abcxyz999 +--->123abcxyz999 + 1 ^ ^ x + 0: abcxyz + +/(ab|cd){3,4}/C + ababab +--->ababab + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + 0: ababab + abcdabcd +--->abcdabcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdabcd + 1: abcdab + abcdcdcdcdcd +--->abcdcdcdcdcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdcdcd + 1: abcdcd + +/^abc/ + abcdef + 0: abc + *** Failers +No match + abcdef\B +No match + +/^(a*|xyz)/ + bcd + 0: + aaabcd + 0: aaa + 1: aa + 2: a + 3: + xyz + 0: xyz + 1: + xyz\N + 0: xyz + *** Failers + 0: + bcd\N +No match + +/xyz$/ + xyz + 0: xyz + xyz\n + 0: xyz + *** Failers +No match + xyz\Z +No match + xyz\n\Z +No match + +/xyz$/m + xyz + 0: xyz + xyz\n + 0: xyz + abcxyz\npqr + 0: xyz + abcxyz\npqr\Z + 0: xyz + xyz\n\Z + 0: xyz + *** Failers +No match + xyz\Z +No match + +/\Gabc/ + abcdef + 0: abc + defabcxyz\>3 + 0: abc *** Failers No match - -/[\x{100}\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - *** Failers + defabcxyz No match -/[\x{100}-\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - ab\x{111}cd - 0: \x{111} - *** Failers -No match - -/[z-\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - ab\x{111}cd - 0: \x{111} - abzcd - 0: z - ab|cd - 0: | - *** Failers -No match - -/[Q\x{100}\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - Q? - 0: Q - *** Failers -No match - -/[Q\x{100}-\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - ab\x{111}cd - 0: \x{111} - Q? - 0: Q - *** Failers -No match - -/[Qz-\x{200}]/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 0: \x{200} - ab\x{111}cd - 0: \x{111} - abzcd - 0: z - ab|cd - 0: | - Q? - 0: Q - *** Failers -No match - -/[\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 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 - -/[\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 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 - -/[Q\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 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 - -/[Q\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - 0: \x{100} - ab\x{200}cd - 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 - -/(?<=[\x{100}\x{200}])X/8 - abc\x{200}X - 0: X - abc\x{100}X - 0: X +/^abcdef/ + ab\P +Partial match: ab + abcde\P +Partial match: abcde + abcdef\P + 0: abcdef *** Failers No match - X + abx\P No match -/(?<=[Q\x{100}\x{200}])X/8 - abc\x{200}X - 0: X - abc\x{100}X - 0: X - abQX - 0: X +/^a{2,4}\d+z/ + a\P +Partial match: a + aa\P +Partial match: aa + aa2\P +Partial match: aa2 + aaa\P +Partial match: aaa + aaa23\P +Partial match: aaa23 + aaaa12345\P +Partial match: aaaa12345 + aa0z\P + 0: aa0z + aaaa4444444444444z\P + 0: aaaa4444444444444z *** Failers No match - X + az\P +No match + aaaaa\P +No match + a56\P No match -/(?<=[\x{100}\x{200}]{3})X/8 - abc\x{100}\x{200}\x{100}X - 0: X +/^abcdef/ + abc\P +Partial match: abc + def\R + 0: def + +/(?<=foo)bar/ + xyzfo\P +No match + foob\P\>2 +Partial match: foob + foobar...\R\P\>4 + 0: ar + xyzfo\P +No match + foobar\>2 + 0: bar + *** Failers +No match + xyzfo\P +No match + obar\R +No match + +/(ab*(cd|ef))+X/ + adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z +No match + lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z +Partial match: abbbbbbcdaefabbbbbbbefa + cdabbbbbbbb\P\R\B\Z +Partial match: cdabbbbbbbb + efabbbbbbbbbbbbbbbb\P\R\B\Z +Partial match: efabbbbbbbbbbbbbbbb + bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z + 0: bbbbbbbbbbbbcdX + +/(a|b)/SF>testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex +>>aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz *** Failers No match - abc\x{200}X + abxyzpqrrabbxyyyypqAzz No match - X + abxyzpqrrrrabbxyyyypqAzz +No match + abxyzpqrrrabxyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyypqAzz +No match + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz No match -/[^\x{100}\x{200}]X/8 - AX - 0: AX - \x{150}X - 0: \x{150}X - \x{500}X - 0: \x{500}X +/^(abc){1,2}zz/ + abczz + 0: abczz + abcabczz + 0: abcabczz *** Failers No match - \x{100}X + zz No match - \x{200}X + abcabcabczz +No match + >>abczz No match -/[^Q\x{100}\x{200}]X/8 - AX - 0: AX - \x{150}X - 0: \x{150}X - \x{500}X - 0: \x{500}X +/^(b+?|a){1,2}?c/ + bc + 0: bc + bbc + 0: bbc + bbbc + 0: bbbc + bac + 0: bac + bbac + 0: bbac + aac + 0: aac + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + bbbbbbbbbbbac + 0: bbbbbbbbbbbac *** Failers No match - \x{100}X + aaac No match - \x{200}X -No match - QX + abbbbbbbbbbbac No match -/[^\x{100}-\x{200}]X/8 - AX - 0: AX - \x{500}X - 0: \x{500}X +/^(b+|a){1,2}c/ + bc + 0: bc + bbc + 0: bbc + bbbc + 0: bbbc + bac + 0: bac + bbac + 0: bbac + aac + 0: aac + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + bbbbbbbbbbbac + 0: bbbbbbbbbbbac *** Failers No match - \x{100}X + aaac No match - \x{150}X -No match - \x{200}X + abbbbbbbbbbbac No match -/[z-\x{100}]/8i - z - 0: z - Z - 0: Z - \x{100} - 0: \x{100} +/^(b+|a){1,2}?bc/ + bbc + 0: bbc + +/^(b*|ba){1,2}?bc/ + babc + 0: babc + bbabc + 0: bbabc + bababc + 0: bababc *** Failers No match - \x{102} + bababbc No match - y + babababc No match -/[\xFF]/ - >\xff< +/^(ba|b*){1,2}?bc/ + babc + 0: babc + bbabc + 0: bbabc + bababc + 0: bababc + *** Failers +No match + bababbc +No match + babababc +No match + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + 0: \x01\x01\x1b;z + +/^[ab\]cde]/ + athing + 0: a + bthing + 0: b + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + fthing +No match + [thing +No match + \\thing +No match + +/^[]cde]/ + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + athing +No match + fthing +No match + +/^[^ab\]cde]/ + fthing + 0: f + [thing + 0: [ + \\thing + 0: \ + *** Failers + 0: * + athing +No match + bthing +No match + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^[^]cde]/ + athing + 0: a + fthing + 0: f + *** Failers + 0: * + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^\/ + + 0: \x81 + +/^ÿ/ + ÿ 0: \xff -/[\xff]/8 - >\x{ff}< - 0: \x{ff} +/^[0-9]+$/ + 0 + 0: 0 + 1 + 0: 1 + 2 + 0: 2 + 3 + 0: 3 + 4 + 0: 4 + 5 + 0: 5 + 6 + 0: 6 + 7 + 0: 7 + 8 + 0: 8 + 9 + 0: 9 + 10 + 0: 10 + 100 + 0: 100 + *** Failers +No match + abc +No match -/[^\xFF]/ - XYZ +/^.*nter/ + enter + 0: enter + inter + 0: inter + uponter + 0: uponter + +/^xxx[0-9]+$/ + xxx0 + 0: xxx0 + xxx1234 + 0: xxx1234 + *** Failers +No match + xxx +No match + +/^.+[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + 0: abc!pqr=apquxz.ixr.zzz.ac.uk + *** Failers +No match + !pqr=apquxz.ixr.zzz.ac.uk +No match + abc!=apquxz.ixr.zzz.ac.uk +No match + abc!pqr=apquxz:ixr.zzz.ac.uk +No match + abc!pqr=apquxz.ixr.zzz.ac.ukk +No match + +/:/ + Well, we need a colon: somewhere + 0: : + *** Fail if we don't +No match + +/([\da-f:]+)$/i + 0abc + 0: 0abc + abc + 0: abc + fed + 0: fed + E + 0: E + :: + 0: :: + 5f03:12C0::932e + 0: 5f03:12C0::932e + fed def + 0: def + Any old stuff + 0: ff + *** Failers +No match + 0zzz +No match + gzzz +No match + fed\x20 +No match + Any old rubbish +No match + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + 0: .1.2.3 + A.12.123.0 + 0: A.12.123.0 + *** Failers +No match + .1.2.3333 +No match + 1.2.3 +No match + 1234.2.3 +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 IN SOA non-sp1 non-sp2 ( + 0: 1 IN SOA non-sp1 non-sp2 ( + *** Failers +No match + 1IN SOA non-sp1 non-sp2( +No match + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + 0: a. + Z. + 0: Z. + 2. + 0: 2. + ab-c.pq-r. + 0: ab-c.pq-r. + sxk.zzz.ac.uk. + 0: sxk.zzz.ac.uk. + x-.y-. + 0: x-.y-. + *** Failers +No match + -abc.peq. +No match + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + 0: *.a + *.b0-a + 0: *.b0-a + *.c3-b.c + 0: *.c3-b.c + *.c-a.b-c + 0: *.c-a.b-c + *** Failers +No match + *.0 +No match + *.a- +No match + *.a-b.c- +No match + *.c-a.0-c +No match + +/^(?=ab(de))(abd)(e)/ + abde + 0: abde + +/^(?!(ab)de|x)(abd)(f)/ + abdf + 0: abdf + +/^(?=(ab(cd)))(ab)/ + abcd + 0: ab + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + 0: a.b.c.d + A.B.C.D + 0: A.B.C.D + a.b.c.1.2.3.C + 0: a.b.c.1.2.3.C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + 0: "1234" + \"abcd\" ; + 0: "abcd" ; + \"\" ; rhubarb + 0: "" ; rhubarb + *** Failers +No match + \"1234\" : things +No match + +/^$/ + \ + 0: + *** Failers +No match + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/^ a\ b[c ]d $/x + a bcd + 0: a bcd + a b d + 0: a b d + *** Failers +No match + abcd +No match + ab d +No match + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + 0: a+ Z0+\x08\x0a\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + 0: .^$(*+)|{?,?} + 1: .^$(*+)|{?,? + 2: .^$(*+)|{?, + 3: .^$(*+)|{? + 4: .^$(*+)|{ + 5: .^$(*+)| + 6: .^$(*+) + 7: .^$(*+ + 8: .^$(* + 9: .^$( +10: .^$ +11: .^ +12: . + +/^a*\w/ + z + 0: z + az + 0: az + 1: a + aaaz + 0: aaaz + 1: aaa + 2: aa + 3: a + a + 0: a + aa + 0: aa + 1: a + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + a+ + 0: a + aa+ + 0: aa + 1: a + +/^a*?\w/ + z + 0: z + az + 0: az + 1: a + aaaz + 0: aaaz + 1: aaa + 2: aa + 3: a + a + 0: a + aa + 0: aa + 1: a + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + a+ + 0: a + aa+ + 0: aa + 1: a + +/^a+\w/ + az + 0: az + aaaz + 0: aaaz + 1: aaa + 2: aa + aa + 0: aa + aaaa + 0: aaaa + 1: aaa + 2: aa + aa+ + 0: aa + +/^a+?\w/ + az + 0: az + aaaz + 0: aaaz + 1: aaa + 2: aa + aa + 0: aa + aaaa + 0: aaaa + 1: aaa + 2: aa + aa+ + 0: aa + +/^\d{8}\w{2,}/ + 1234567890 + 0: 1234567890 + 12345678ab + 0: 12345678ab + 12345678__ + 0: 12345678__ + *** Failers +No match + 1234567 +No match + +/^[aeiou\d]{4,5}$/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + aaaaa + 0: aaaaa + *** Failers +No match + 123456 +No match + +/^[aeiou\d]{4,5}?/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + 1: 1234 + aaaaa + 0: aaaaa + 1: aaaa + 123456 + 0: 12345 + 1: 1234 + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + From abcd Mon Sep 1 12:33:02 1997 + 0: From abcd Mon Sep 1 12:33 + *** Failers +No match + From abcd Sep 01 12:33:02 1997 +No match + +/^12.34/s + 12\n34 + 0: 12\x0a34 + 12\r34 + 0: 12\x0d34 + +/\w+(?=\t)/ + the quick brown\t fox + 0: brown + +/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 + 0: abc + *** Failers +No match + abc123 +No match + +/^1234(?# test newlines + inside)/ + 1234 + 0: 1234 + +/^1234 #comment in extended re + /x + 1234 + 0: 1234 + +/#rhubarb + abcd/x + abcd + 0: abcd + +/^abcd#rhubarb/x + abcd + 0: abcd + +/(?!^)abc/ + the abc + 0: abc + *** Failers +No match + abc +No match + +/(?=^)abc/ + abc + 0: abc + *** Failers +No match + the abc +No match + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/ (?: [\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 +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + 1: user@dom + user\@dom.ain + 0: user@dom.ain + 1: user@dom + \"A. Other\" (a comment) + 0: "A. Other" (a comment) + 1: "A. Other" + 2: "A. Other" + A. Other (a comment) + 0: Other (a comment) + 1: Other + 2: Other + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re + A missing angle @,;:".\\\[\]\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# 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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # 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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\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 +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + 1: user@dom + user\@dom.ain + 0: user@dom.ain + 1: user@dom + \"A. Other\" (a comment) + 0: "A. Other" + A. Other (a comment) + 0: Other + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re + A missing angle + a\rb + 0: a\x0db + *** Failers +No match + a\nb +No match + +/abc$/ + abc + 0: abc + abc\n + 0: abc + *** Failers +No match + abc\ndef +No match + +/(abc)\123/ + abc\x53 + 0: abcS + +/(abc)\223/ + abc\x93 + 0: abc\x93 + +/(abc)\323/ + abc\xd3 + 0: abc\xd3 + +/(abc)\100/ + abc\x40 + 0: abc@ + abc\100 + 0: abc@ + +/(abc)\1000/ + abc\x400 + 0: abc@0 + abc\x40\x30 + 0: abc@0 + abc\1000 + 0: abc@0 + abc\100\x30 + 0: abc@0 + abc\100\060 + 0: abc@0 + 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)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ + abcdefghijk\12S + 0: abcdefghijk\x0aS + +/ab\idef/ + abidef + 0: abidef + +/a{0}bc/ + bc + 0: bc + +/(a|(bc)){0,0}?xyz/ + xyz + 0: xyz + +/abc[\10]de/ + abc\010de + 0: abc\x08de + +/abc[\1]de/ + abc\1de + 0: abc\x01de + +/(abc)[\1]de/ + abc\1de + 0: abc\x01de + +/(?s)a.b/ + a\nb + 0: a\x0ab + +/^([^a])([^\b])([^c]*)([^d]{3,4})/ + baNOTccccd + 0: baNOTcccc + 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 + 0: *** Failers + 1: *** Failer + 2: *** Faile + 3: *** Fail + 4: *** Fai + 5: *** Fa + 6: *** F + anything +No match + b\bc +No match + baccd +No match + +/[^a]/ + Abc + 0: A + +/[^a]/i + Abc + 0: b + +/[^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 + 0: c + *** Failers + 0: s + abk +No match + +/[^k]{2,3}$/ + abc + 0: abc + kbc + 0: bc + kabc + 0: abc + *** Failers + 0: ers + abk +No match + akb +No match + akk +No match + +/^\d{8,}\@.+[^k]$/ + 12345678\@a.b.c.d + 0: 12345678@a.b.c.d + 123456789\@x.y.z + 0: 123456789@x.y.z + *** Failers +No match + 12345678\@x.y.uk +No match + 1234567\@a.b.c.d +No match + +/[^a]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^a]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/[^az]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^az]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ + \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 + 0: \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 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\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\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 + +/P[^*]TAIRE[^*]{1,6}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/P[^*]TAIRE[^*]{1,}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/(\.\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 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 0: .230 + 1: .23 + 1.875000282 + 0: .875 + *** Failers +No match + 1.235 +No match + +/a(?)b/ + ab + 0: ab + +/\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. + 0: food is under the bar in the bar + 1: food is under the bar + +/foo(.*?)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: food is under the bar + +/(.*)(\d*)/ + I have 2 numbers: 53147 +Matched, but too many subsidiary matches + 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 numbers: + 6: I have 2 numbers: + 7: I have 2 numbers + 8: I have 2 number + 9: I have 2 numbe +10: I have 2 numb +11: I have 2 num +12: I have 2 nu +13: I have 2 n +14: I have 2 +15: I have 2 +16: I have +17: I have +18: I hav +19: I ha +20: I h +21: I + +/(.*)(\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 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 +Matched, but too many subsidiary matches + 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 numbers: + 6: I have 2 numbers: + 7: I have 2 numbers + 8: I have 2 number + 9: I have 2 numbe +10: I have 2 numb +11: I have 2 num +12: I have 2 nu +13: I have 2 n +14: I have 2 +15: I have 2 +16: I have +17: I have +18: I hav +19: I ha +20: I h +21: I + +/(.*?)(\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 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/^\D*(?!123)/ + ABC123 + 0: AB + 1: A + 2: + +/^(\D*)(?=\d)(?!123)/ + ABC445 + 0: ABC + *** Failers +No match + ABC123 +No match + +/^[W-]46]/ + W46]789 + 0: W46] + -46]789 + 0: -46] + *** Failers +No match + Wall +No match + Zebra +No match + 42 +No match + [abcd] +No match + ]abcd[ +No match + +/^[W-\]46]/ + W46]789 + 0: W + Wall + 0: W + Zebra + 0: Z + Xylophone 0: X + 42 + 0: 4 + [abcd] + 0: [ + ]abcd[ + 0: ] + \\backslash + 0: \ + *** Failers +No match + -46]789 +No match + well +No match + +/\d\d\/\d\d\/\d\d\d\d/ + 01/01/2000 + 0: 01/01/2000 -/[^\xff]/8 - XYZ - 0: X - \x{123} - 0: \x{123} - -/^[ac]*b/8 - xb +/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark No match -/^[ac\x{100}]*b/8 - xb +/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match -/^[^x]*b/8i - xb +/^(a){0,0}/ + bcd + 0: + abc + 0: + aab + 0: + +/^(a){0,1}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: a + 1: + +/^(a){0,2}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + +/^(a){0,3}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + aaa + 0: aaa + 1: aa + 2: a + 3: + +/^(a){0,}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + aaa + 0: aaa + 1: aa + 2: a + 3: + aaaaaaaa + 0: aaaaaaaa + 1: aaaaaaa + 2: aaaaaa + 3: aaaaa + 4: aaaa + 5: aaa + 6: aa + 7: a + 8: + +/^(a){1,1}/ + bcd +No match + abc + 0: a + aab + 0: a + +/^(a){1,2}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + +/^(a){1,3}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: aa + 2: a + +/^(a){1,}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: aa + 2: a + aaaaaaaa + 0: aaaaaaaa + 1: aaaaaaa + 2: aaaaaa + 3: aaaaa + 4: aaaa + 5: aaa + 6: aa + 7: a + +/.*\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.{0,}\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/m + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*\.gif/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*$/ + borfle\nbib.gif\nno + 0: no + +/.*$/m + borfle\nbib.gif\nno + 0: borfle + +/.*$/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + +/.*$/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + 1: borfle\x0abib.gif + 2: borfle + +/.*$/ + borfle\nbib.gif\nno\n + 0: no + +/.*$/m + borfle\nbib.gif\nno\n + 0: borfle + +/.*$/s + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + 1: borfle\x0abib.gif\x0ano + +/.*$/ms + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + 1: borfle\x0abib.gif\x0ano + 2: borfle\x0abib.gif + 3: borfle + +/(.*X|^B)/ + abcde\n1234Xyz + 0: 1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar No match -/^[^x]*b/8 - xb +/(.*X|^B)/m + abcde\n1234Xyz + 0: 1234X + BarFoo + 0: B + abcde\nBar + 0: B + +/(.*X|^B)/s + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/ms + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + abcde\nBar + 0: B + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/(?s:.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/^.*B/ + **** Failers +No match + abc\nB +No match + +/(?s)^.*B/ + abc\nB + 0: abc\x0aB + +/(?m)^.*B/ + abc\nB + 0: B + +/(?ms)^.*B/ + abc\nB + 0: abc\x0aB + +/(?ms)^B/ + abc\nB + 0: B + +/(?s)B$/ + B\n + 0: B + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + 0: 123456654321 + +/^\d\d\d\d\d\d\d\d\d\d\d\d/ + 123456654321 + 0: 123456654321 + +/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ + 123456654321 + 0: 123456654321 + +/^[abc]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + 0: n + *** Failers +No match + z +No match + +/abcde{0,0}/ + abcd + 0: abcd + *** Failers +No match + abce +No match + +/ab[cd]{0,0}e/ + abe + 0: abe + *** Failers +No match + abcde +No match + +/ab(c){0,0}d/ + abd + 0: abd + *** Failers +No match + abcd +No match + +/a(b*)/ + a + 0: a + ab + 0: ab + 1: a + abbbb + 0: abbbb + 1: abbb + 2: abb + 3: ab + 4: a + *** Failers + 0: a + bbbbb +No match + +/ab\d{0}e/ + abe + 0: abe + *** Failers +No match + ab1e +No match + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + 0: "quick" + \"the \\\"quick\\\" brown fox\" + 0: "the \"quick\" brown fox" + +/.*?/g+ + abc + 0: abc + 0+ + 1: ab + 2: a + 3: + 0: + 0+ + +/\b/g+ + abc + 0: + 0+ abc + 0: + 0+ + +/\b/+g + abc + 0: + 0+ abc + 0: + 0+ + +//g + abc + 0: + 0: + 0: + 0: + +/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide + 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide + +/a[^a]b/ + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/ + acb + 0: acb + *** Failers +No match + a\nb +No match + +/a[^a]b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/^(b+?|a){1,2}?c/ + bac + 0: bac + bbac + 0: bbac + bbbac + 0: bbbac + bbbbac + 0: bbbbac + bbbbbac + 0: bbbbbac + +/^(b+|a){1,2}?c/ + bac + 0: bac + bbac + 0: bbac + bbbac + 0: bbbac + bbbbac + 0: bbbbac + bbbbbac + 0: bbbbbac + +/(?!\A)x/m + x\nb\n +No match + a\bx\n + 0: x + +/\x0{ab}/ + \0{ab} + 0: \x00{ab} + +/(A|B)*?CD/ + CD + 0: CD + +/(A|B)*CD/ + CD + 0: CD + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ +No match + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\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 +No match + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d+)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: 1234 + 3: 123 + 4: 12 + 12345+ + 0: 12345 + 1: 1234 + 2: 123 + 3: 12 + +/((?>\d+))(\w)/ + 12345a + 0: 12345a + *** Failers +No match + 12345+ +No match + +/(?>a+)b/ + aaab + 0: aaab + +/((?>a+)b)/ + aaab + 0: aaab + +/(?>(a+))b/ + aaab + 0: aaab + +/(?>b)+/ + aaabbbccc + 0: bbb + 1: bb + 2: b + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbcccc + 1: aaabbbbc + +/(a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbcccc + 1: aaabbbbccc + 2: aaabbbbcc + 3: aaabbbbc + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: abc(ade)ufh()() + 2: abc(ade)ufh() + 3: abc(ade)ufh + 4: abc(ade) + 5: abc + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + 0: (abc) + (abc(def)xyz) + 0: (abc(def)xyz) + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/a(?-i)b/i + ab + 0: ab + Ab + 0: Ab + *** Failers +No match + aB +No match + AB +No match + +/(a (?x)b c)d e/ + a bcd e + 0: a bcd e + *** Failers +No match + a b cd e +No match + abcd e +No match + a bcde +No match + +/(a b(?x)c d (?-x)e f)/ + a bcde f + 0: a bcde f + *** Failers +No match + abcdef +No match + +/(a(?i)b)c/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + abC +No match + aBC +No match + Abc +No match + ABc +No match + ABC +No match + AbC +No match + +/a(?i:b)c/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + ABC +No match + abC +No match + aBC +No match + +/a(?i:b)*c/ + aBc + 0: aBc + aBBc + 0: aBBc + *** Failers +No match + aBC +No match + aBBC +No match + +/a(?=b(?i)c)\w\wd/ + abcd + 0: abcd + abCd + 0: abCd + *** Failers +No match + aBCd +No match + abcD +No match + +/(?s-i:more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?:(?s-i)more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?>a(?i)b+)+c/ + abc + 0: abc + aBbc + 0: aBbc + aBBc + 0: aBBc + *** Failers +No match + Abc +No match + abAb +No match + abbC +No match + +/(?=a(?i)b)\w\wc/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + Ab +No match + abC +No match + aBC +No match + +/(?<=a(?i)b)(\w\w)c/ + abxxc + 0: xxc + aBxxc + 0: xxc + *** Failers +No match + Abxxc +No match + ABxxc +No match + abxxC +No match + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/(?(?<=foo)bar|cat)/ + foobar + 0: bar + cat + 0: cat + fcat + 0: cat + focat + 0: cat + *** Failers +No match + foocat +No match + +/(?(?a*)*/ + a + 0: a + 1: + aa + 0: aa + 1: + aaaa + 0: aaaa + 1: + +/(abc|)+/ + abc + 0: abc + 1: + abcabc + 0: abcabc + 1: abc + 2: + abcabcabc + 0: abcabcabc + 1: abcabc + 2: abc + 3: + xyz + 0: + +/([a]*)*/ + a + 0: a + 1: + aaaaa + 0: aaaaa + 1: aaaa + 2: aaa + 3: aa + 4: a + 5: + +/([ab]*)*/ + a + 0: a + 1: + b + 0: b + 1: + ababab + 0: ababab + 1: ababa + 2: abab + 3: aba + 4: ab + 5: a + 6: + aaaabcde + 0: aaaab + 1: aaaa + 2: aaa + 3: aa + 4: a + 5: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + +/([^a]*)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + aaa + 0: + +/([^ab]*)*/ + cccc + 0: cccc + 1: ccc + 2: cc + 3: c + 4: + abab + 0: + +/([a]*?)*/ + a + 0: a + 1: + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/([ab]*?)*/ + a + 0: a + 1: + b + 0: b + 1: + abab + 0: abab + 1: aba + 2: ab + 3: a + 4: + baba + 0: baba + 1: bab + 2: ba + 3: b + 4: + +/([^a]*?)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + aaa + 0: + +/([^ab]*?)*/ + c + 0: c + 1: + cccc + 0: cccc + 1: ccc + 2: cc + 3: c + 4: + baba + 0: + +/(?>a*)*/ + a + 0: a + 1: + aaabcde + 0: aaa + 1: + +/((?>a*))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/((?>a*?))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 0: 12-sep-98 + 12-09-98 + 0: 12-09-98 + *** Failers +No match + sep-12-98 +No match + +/(?i:saturday|sunday)/ + saturday + 0: saturday + sunday + 0: sunday + Saturday + 0: Saturday + Sunday + 0: Sunday + SATURDAY + 0: SATURDAY + SUNDAY + 0: SUNDAY + SunDay + 0: SunDay + +/(a(?i)bc|BB)x/ + abcx + 0: abcx + aBCx + 0: aBCx + bbx + 0: bbx + BBx + 0: BBx + *** Failers +No match + abcX +No match + aBCX +No match + bbX +No match + BBX +No match + +/^([ab](?i)[cd]|[ef])/ + ac + 0: ac + aC + 0: aC + bD + 0: bD + elephant + 0: e + Europe + 0: E + frog + 0: f + France + 0: F + *** Failers +No match + Africa +No match + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + 0: ab + aBd + 0: aBd + xy + 0: xy + xY + 0: xY + zebra + 0: z + Zambesi + 0: Z + *** Failers +No match + aCD +No match + XY +No match + +/(?<=foo\n)^bar/m + foo\nbar + 0: bar + *** Failers +No match + bar +No match + baz\nbar +No match + +/(?<=(?]&/ + <&OUT + 0: <& + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + 0: foobar + 1: foo + 2: + +/(?<=a)b/ + ab + 0: b + *** Failers +No match + cb +No match + b +No match + +/(?a+)ab/ + +/(?>a+)b/ + aaab + 0: aaab + +/([[:]+)/ + a:[b]: + 0: :[ + 1: : + +/([[=]+)/ + a=[b]= + 0: =[ + 1: = + +/([[.]+)/ + a.[b]. + 0: .[ + 1: . + +/((?>a+)b)/ + aaab + 0: aaab + +/(?>(a+))b/ + aaab + 0: aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: abc(ade)ufh()() + 2: abc(ade)ufh() + 3: abc(ade)ufh + 4: abc(ade) + 5: abc + +/a\Z/ + *** Failers +No match + aaab +No match + a\nb\n +No match + +/b\Z/ + a\nb\n + 0: b + +/b\z/ + +/b\Z/ + a\nb + 0: b + +/b\z/ + a\nb + 0: b + *** Failers +No match + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + 0: alphabetabcd + endingwxyz + 0: endingwxyz + *** Failers +No match + a rather long string that doesn't end with one of them +No match + +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark No match -/^\d*b/8 - xb +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match -/(|a)/g8 - catac - 0: - 0: a - 1: - 0: - 0: a - 1: - 0: - 0: - a\x{256}a - 0: a - 1: - 0: - 0: a - 1: +/(?<=\d{3}(?!999))foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=(?!...999)\d{3})foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 0: foo + 123456foo + 0: foo + *** Failers +No match + 123999foo +No match + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: Z + 2: + +/((?>)+|A)*/ + ZABCDEFG 0: -/^\x{85}$/8i - \x{85} - 0: \x{85} +/a*/g + abbab + 0: a + 1: + 0: + 0: + 0: a + 1: + 0: + 0: -/^abc./mgx8 - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK +/^[a-\d]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/^[\d-a]/ + abcde + 0: a + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +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: + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + 1: \x09\x0a\x0c + 2: \x09\x0a + 3: \x09 + 4: + +/a b/x + ab +No match + +/(?!\A)x/m + a\nxb\n + 0: x + +/(?!^)x/m + a\nxb\n +No match + +/abc\Qabc\Eabc/ + abcabcabc + 0: abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + 0: abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + 0: abc abcabc + *** Failers +No match + abcabcabc +No match + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + 0: abc\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + 0: abc$xyz + +/\Gabc/ + abc + 0: abc + *** Failers +No match + xyzabc +No match + +/\Gabc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + +/abc./g + abc1abc2xyzabc3 0: abc1 0: abc2 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc7 - 0: abc8 - 0: abc9 -/abc.$/mgx8 - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 - 0: abc1 - 0: abc2 - 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc7 - 0: abc8 - 0: abc9 +/a(?x: b c )d/ + XabcdY + 0: abcd + *** Failers +No match + Xa b c d Y +No match -/^a\Rb/8 - a\nb - 0: a\x{0a}b +/((?x)x y z | a b c)/ + XabcY + 0: abc + AxyzB + 0: xyz + +/(?i)AB(?-i)C/ + XabCY + 0: abC + *** Failers +No match + XabcY +No match + +/((?i)AB(?-i)C|D)E/ + abCE + 0: abCE + DE + 0: DE + *** Failers +No match + abcE +No match + abCe +No match + dE +No match + De +No match + +/[z\Qa-d]\E]/ + z + 0: z + a + 0: a + - + 0: - + d + 0: d + ] + 0: ] + *** Failers + 0: a + b +No match + +/[\z\C]/ + z + 0: z + C + 0: C + +/\M/ + M + 0: M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + 0: REGular + regulaer + 0: regulaer + Regex + 0: Regex + regulär + 0: regul\xe4r + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + 0: \xc5\xe6\xe5\xe4\xe0 + Åæåäÿ + 0: \xc5\xe6\xe5\xe4\xff + ÅæåäÀ + 0: \xc5\xe6\xe5\xe4\xc0 + Åæåäß + 0: \xc5\xe6\xe5\xe4\xdf + +/(?<=Z)X./ + \x84XAZXB + 0: XB + +/^(?(2)a|(1)(2))+$/ + 123a +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?<=a|bbbb)c/ + ac + 0: c + bbbbc + 0: c + +/abc/SS>testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex + + 0: abc + xyz\r\nabc\ + 0: abc + xyz\rabc\ + 0: abc + xyz\r\nabc\ + 0: abc + ** Failers +No match + xyz\nabc\ +No match + xyz\r\nabc\ +No match + xyz\nabc\ +No match + xyz\rabc\ +No match + xyz\rabc\ +No match + +/abc$/m + xyzabc + 0: abc + xyzabc\n + 0: abc + xyzabc\npqr + 0: abc + xyzabc\r\ + 0: abc + xyzabc\rpqr\ + 0: abc + xyzabc\r\n\ + 0: abc + xyzabc\r\npqr\ + 0: abc + ** Failers +No match + xyzabc\r +No match + xyzabc\rpqr +No match + xyzabc\r\n +No match + xyzabc\r\npqr +No match + +/^abc/m + xyz\rabcdef + 0: abc + xyz\nabcdef\ + 0: abc + ** Failers +No match + xyz\nabcdef +No match + +/^abc/m + xyz\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/^abc/m + xyz\r\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/.*/ + 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: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \abc\rdef + 0: abc + 1: ab + 2: a + 3: + \abc\r\ndef + 0: abc + 1: ab + 2: a + 3: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \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 + 1: ab + 2: a + 3: + +/\w+(.)(.)?def/s + abc\ndef + 0: abc\x0adef + abc\rdef + 0: abc\x0ddef + abc\r\ndef + 0: abc\x0d\x0adef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + 0: abc=xyz\\x0apqr + 1: abc=xyz\\x0apq + 2: abc=xyz\\x0ap + 3: abc=xyz\\x0a + 4: abc=xyz\ + 5: abc=xyz + 6: abc=xy + 7: abc=x + 8: abc= + +/^(a()*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(?:a(?:(?:))*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(a()+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/^(?:a(?:(?:))+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/^a.b/ a\rb - 0: a\x{0d}b + 0: a\x0db + a\nb\ + 0: a\x0ab + ** Failers +No match + a\nb +No match + a\nb\ +No match + a\rb\ +No match + a\rb\ +No match + +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc9 + +/^a\Rb/ + a\nb + 0: a\x0ab + a\rb + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b + 0: a\x0bb a\x0cb - 0: a\x{0c}b - a\x{85}b - 0: a\x{85}b - a\x{2028}b - 0: a\x{2028}b - a\x{2029}b - 0: a\x{2029}b + 0: a\x0cb + a\x85b + 0: a\x85b ** Failers No match a\n\rb No match -/^a\R*b/8 +/^a\R*b/ ab 0: ab a\nb - 0: a\x{0a}b + 0: a\x0ab a\rb - 0: a\x{0d}b + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b - a\x0c\x{2028}\x{2029}b - 0: a\x{0c}\x{2028}\x{2029}b - a\x{85}b - 0: a\x{85}b + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}\x0cb - 0: a\x{0a}\x{0d}\x{85}\x{0c}b + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb -/^a\R+b/8 +/^a\R+b/ a\nb - 0: a\x{0a}b + 0: a\x0ab a\rb - 0: a\x{0d}b + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b - a\x0c\x{2028}\x{2029}b - 0: a\x{0c}\x{2028}\x{2029}b - a\x{85}b - 0: a\x{85}b + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}\x0cb - 0: a\x{0a}\x{0d}\x{85}\x{0c}b + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb ** Failers No match ab No match - -/^a\R{1,3}b/8 + +/^a\R{1,3}b/ a\nb - 0: a\x{0a}b + 0: a\x0ab a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}b - 0: a\x{0a}\x{0d}\x{85}b + 0: a\x0a\x0db + a\n\r\x85b + 0: a\x0a\x0d\x85b a\r\n\r\nb - 0: a\x{0d}\x{0a}\x{0d}\x{0a}b + 0: a\x0d\x0a\x0d\x0ab a\r\n\r\n\r\nb - 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b + 0: a\x0d\x0a\x0d\x0a\x0d\x0ab a\n\r\n\rb - 0: a\x{0a}\x{0d}\x{0a}\x{0d}b + 0: a\x0a\x0d\x0a\x0db a\n\n\r\nb - 0: a\x{0a}\x{0a}\x{0d}\x{0a}b + 0: a\x0a\x0a\x0d\x0ab ** Failers No match a\n\n\n\rb @@ -1142,164 +6908,645 @@ No match a\r No match -/\h+\V?\v{3,4}/8 - \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 - \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 - >\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 - >\x09\x20\x{a0}X\x0a\x0a\x0a< - 0: X\x{0a}\x{0a}\x{0a} - -/\H\h\V\v/8 - X X\x0a - 0: X X\x{0a} - X\x09X\x0b - 0: X\x{09}X\x{0b} +/^a[\R]b/ + aRb + 0: aRb ** Failers No match - \x{a0} X\x0a + a\nb No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \r\nfoo +No match + \nfoo +No match + +/.+foo/ + afoo + 0: afoo + \nfoo + 0: \x0afoo + ** Failers +No match + \r\nfoo +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \nfoo +No match + \r\nfoo +No match + +/.+foo/s + afoo + 0: afoo + \r\nfoo + 0: \x0d\x0afoo + \nfoo + 0: \x0afoo + +/^$/mg + abc\r\rxyz + 0: + abc\n\rxyz + 0: + ** Failers +No match + abc\r\nxyz +No match + +/^X/m + XABC + 0: X + ** Failers +No match + XABC\B +No match + +/(?m)^$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + 0: \x0d\x0a + 0+ + 1: -/\H*\h+\V?\v{3,4}/8 - \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} - \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a - 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} - 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} - \x09\x20\x{a0}\x0a\x0b\x0c - 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} - ** Failers -No match - \x09\x20\x{a0}\x0a\x0b -No match - -/\H\h\V\v/8 - \x{3001}\x{3000}\x{2030}\x{2028} - 0: \x{3001}\x{3000}\x{2030}\x{2028} - X\x{180e}X\x{85} - 0: X\x{180e}X\x{85} - ** Failers -No match - \x{2009} X\x0a -No match - -/\H*\h+\V?\v{3,4}/8 - \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} - \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a - 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} - 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} - \x09\x20\x{202f}\x0a\x0b\x0c - 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} - ** Failers -No match - \x09\x{200a}\x{a0}\x{2028}\x0b -No match - -/a\Rb/I8 -Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 -First char = 'a' -Need char = 'b' - a\rb - 0: a\x{0d}b - a\nb - 0: a\x{0a}b - a\r\nb - 0: a\x{0d}\x{0a}b - ** Failers -No match - a\x{85}b -No match - a\x0bb -No match +/(?m)$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a\x0d\x0a + 0: + 0+ \x0d\x0a + 0: + 0+ -/a\Rb/I8 -Capturing subpattern count = 0 -Options: bsr_unicode utf8 -First char = 'a' -Need char = 'b' - a\rb - 0: a\x{0d}b - a\nb - 0: a\x{0a}b - a\r\nb - 0: a\x{0d}\x{0a}b - a\x{85}b - 0: a\x{85}b - a\x0bb - 0: a\x{0b}b - ** Failers -No match - a\x{85}b\ -No match - a\x0bb\ -No match - -/a\R?b/I8 -Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 -First char = 'a' -Need char = 'b' - a\rb - 0: a\x{0d}b - a\nb - 0: a\x{0a}b - a\r\nb - 0: a\x{0d}\x{0a}b - ** Failers -No match - a\x{85}b -No match - a\x0bb -No match +/(?|(abc)|(xyz))/ + >abc< + 0: abc + >xyz< + 0: xyz -/a\R?b/I8 -Capturing subpattern count = 0 -Options: bsr_unicode utf8 -First char = 'a' -Need char = 'b' - a\rb - 0: a\x{0d}b - a\nb - 0: a\x{0a}b - a\r\nb - 0: a\x{0d}\x{0a}b - a\x{85}b - 0: a\x{85}b - a\x0bb - 0: a\x{0b}b +/(x)(?|(abc)|(xyz))(x)/ + xabcx + 0: xabcx + xxyzx + 0: xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + 0: xabcpqrx + xxyzx + 0: xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + 0: abcabc + xyzabc + 0: xyzabc ** Failers No match - a\x{85}b\ -No match - a\x0bb\ + xyzxyz No match -/X/8f - A\x{1ec5}ABCXYZ +/\H\h\V\v/ + X X\x0a + 0: X X\x0a + X\x09X\x0b + 0: X\x09X\x0b + ** Failers +No match + \xa0 X\x0a +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 +No match + \x09\x20\xa0\x0a\x0b +No match + +/\H{3,4}/ + XY ABCDE + 0: ABCD + 1: ABC + XY PQR ST + 0: PQR + +/.\h{3,4}./ + XY AB PQRS + 0: B P + 1: B + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + 0: XNNNYZ + > X NYQZ + 0: X NYQZ + ** Failers +No match + >XYZ +No match + > X NY Z +No match + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + 0: XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA +No match + +/\nA/ + \r\nA + 0: \x0aA + +/[\r\n]A/ + \r\nA + 0: \x0aA + +/(\r|\n)A/ + \r\nA + 0: \x0aA + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + ** Failers +No match + a\x85b +No match + a\x0bb +No match + +/a\R?b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\rb + 0: a\x0db + a\nb + 0: a\x0ab + a\r\nb + 0: a\x0d\x0ab + a\x85b + 0: a\x85b + a\x0bb + 0: a\x0bb + ** Failers +No match + a\x85b\ +No match + a\x0bb\ +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\r\n\nb + 0: a\x0d\x0a\x0ab + a\n\r\rb + 0: a\x0a\x0d\x0db + a\r\n\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab + ** Failers +No match + a\x85\85b +No match + a\x0b\0bb +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\r\rb + 0: a\x0d\x0db + a\n\n\nb + 0: a\x0a\x0a\x0ab + a\r\n\n\r\rb + 0: a\x0d\x0a\x0a\x0d\x0db + a\x85\85b +No match + a\x0b\0bb +No match + ** Failers +No match + a\r\r\r\r\rb +No match + a\x85\85b\ +No match + a\x0b\0bb\ +No match + +/a(?!)|\wbc/ + abc + 0: abc + +/a[]b/ + ** Failers +No match + ab +No match + +/a[]+b/ + ** Failers +No match + ab +No match + +/a[]*+b/ + ** Failers +No match + ab +No match + +/a[^]b/ + aXb + 0: aXb + a\nb + 0: a\x0ab + ** Failers +No match + ab +No match + +/a[^]+b/ + aXb + 0: aXb + a\nX\nXb + 0: a\x0aX\x0aXb + ** Failers +No match + ab +No match + +/X$/E + X + 0: X + ** Failers +No match + X\n +No match + +/X$/ + X + 0: X + X\n 0: X -/abcd*/8 +/xyz/C + xyz +--->xyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz +--->abcxyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz\Y +--->abcxyz + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + ** Failers +No match + abc +No match + abc\Y +--->abc + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + abcxypqr +No match + abcxypqr\Y +--->abcxypqr + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + +/(*NO_START_OPT)xyz/C + abcxyz +--->abcxyz ++15 ^ x ++15 ^ x ++15 ^ x ++15 ^ x ++16 ^^ y ++17 ^ ^ z ++18 ^ ^ + 0: xyz + +/(?C)ab/ + ab +--->ab + 0 ^ a + 0: ab + \C-ab + 0: ab + +/ab/C + ab +--->ab + +0 ^ a + +1 ^^ b + +2 ^ ^ + 0: ab + \C-ab + 0: ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" +--->"ab" + +0 ^ ^ + +1 ^ " + +2 ^^ ((?(?=[a])[^"])|b)* ++21 ^^ " + +3 ^^ (?(?=[a])[^"]) ++18 ^^ b + +5 ^^ (?=[a]) + +8 ^ [a] ++11 ^^ ) ++12 ^^ [^"] ++16 ^ ^ ) ++17 ^ ^ | ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++19 ^ ^ ) ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++17 ^ ^ | ++22 ^ ^ $ ++23 ^ ^ + 0: "ab" + \C-"ab" + 0: "ab" + +/\d+X|9+Y/ + ++++123999\P +Partial match: 123999 + ++++123999Y\P + 0: 999Y + +/Z(*F)/ + Z\P +No match + ZA\P +No match + +/Z(?!)/ + Z\P +No match + ZA\P +No match + +/dog(sbody)?/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog(sbody)??/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog|dogsbody/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dogsbody|dog/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/Z(*F)Q|ZXY/ + Z\P +Partial match: Z + ZA\P +No match + X\P +No match + +/\bthe cat\b/ + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/dog(sbody)?/ + dogs\D\P + 0: dog + body\D\R + 0: body + +/dog(sbody)?/ + dogs\D\P\P +Partial match: dogs + body\D\R + 0: body + +/abc/ + abc\P + 0: abc + abc\P\P + 0: abc + +/abc\K123/ + xyzabc123pqr +Error -16 (item unsupported for DFA matching) + +/(?<=abc)123/ + xyzabc123pqr + 0: 123 + xyzabc12\P +Partial match: abc12 + xyzabc12\P\P +Partial match: abc12 + +/\babc\b/ + +++abc+++ + 0: abc + +++ab\P +Partial match: +ab + +++ab\P\P +Partial match: +ab + +/(?=C)/g+ + ABCDECBA + 0: + 0+ CDECBA + 0: + 0+ CBA + +/(abc|def|xyz)/I +Capturing subpattern count = 1 +No options +No first char +No need char + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + +/(abc|def|xyz)/SI +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a d x + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + +/abcd*/+ 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 + 0: + 0+ xxx -/abcd*/i8 +/abcd*/i xxxxabcd\P 0: abcd 1: abc @@ -1311,14 +7558,14 @@ Partial match: abcd XXXXABCD\P\P Partial match: ABCD -/abc\d*/8 +/abc\d*/ xxxxabc1\P 0: abc1 1: abc xxxxabc1\P\P Partial match: abc1 -/abc[de]*/8 +/abc[de]*/ xxxxabcde\P 0: abcde 1: abcd @@ -1326,26 +7573,447 @@ Partial match: abc1 xxxxabcde\P\P Partial match: abcde -/\bthe cat\b/8 - the cat\P - 0: the cat - the cat\P\P -Partial match: the cat - -/a+/8 - a\x{123}aa\>1 - 0: aa - 1: a - a\x{123}aa\>2 -Error -11 - a\x{123}aa\>3 - 0: aa - 1: a - a\x{123}aa\>4 - 0: a - a\x{123}aa\>5 +/(?:(?1)|B)(A(*F)|C)/ + ABCD + 0: BC + CCD + 0: CC + ** Failers +No match + CAD No match - a\x{123}aa\>6 -Error -24 -/-- End of testinput8 --/ +/^(?:(?1)|B)(A(*F)|C)/ + CCD + 0: CC + BCD + 0: BC + ** Failers +No match + ABCD +No match + CAD +No match + BAD +No match + +/^(?!a(*SKIP)b)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*THEN)b|ac)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*PRUNE)b)/ + ab +Error -16 (item unsupported for DFA matching) + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?(?!a(*SKIP)b))/ + ac +Error -16 (item unsupported for DFA matching) + +/(?<=abc)def/ + abc\P\P +Partial match: abc + +/abc$/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc$/m + abc + 0: abc + abc\n + 0: abc + abc\P\P +Partial match: abc + abc\n\P\P + 0: abc + abc\P + 0: abc + abc\n\P + 0: abc + +/abc\z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\Z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\b/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\B/ + abc +No match + abc\P +Partial match: abc + abc\P\P +Partial match: abc + +/.+/ + abc\>0 + 0: abc + 1: ab + 2: a + abc\>1 + 0: bc + 1: b + abc\>2 + 0: c + abc\>3 +No match + abc\>4 +Error -24 (bad offset value) + abc\>-4 +Error -24 (bad offset value) + +/^(?:a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(?:aa|(?:a)++\w)/ + aaaab + 0: aaaab + 1: aa + aaaa + 0: aa + ** Failers +No match + bbb +No match + +/^(?:a)*+\w/ + aaaab + 0: aaaab + bbb + 0: b + ** Failers +No match + aaaa +No match + +/^(a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(a|)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/(?=abc){3}abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)+abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)++abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc){0}xyz/ + xyz + 0: xyz + +/(?=abc){1}xyz/ + ** Failers +No match + xyz +No match + +/(?=(a))?./ + ab + 0: a + bc + 0: b + +/(?=(a))??./ + ab + 0: a + bc + 0: b + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/^(?=(?1))?[az]([abc])d/ + abd + 0: abd + zcdxx + 0: zcd + +/^(?!a){0}\w+/ + aaaaa + 0: aaaaa + 1: aaaa + 2: aaa + 3: aa + 4: a + +/(?<=(abc))?xyz/ + abcxyz + 0: xyz + pqrxyz + 0: xyz + +/((?2))((?1))/ + abc +Error -26 (nested recursion at the same subject position) + +/(?(R)a+|(?R)b)/ + aaaabcde + 0: aaaab + +/(?(R)a+|((?R))b)/ + aaaabcde + 0: aaaab + +/((?(R)a+|(?1)b))/ + aaaabcde + 0: aaaab + +/((?(R2)a+|(?1)b))/ + aaaabcde +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(a+)/ + \O6aaaa +Matched, but too many subsidiary matches + 0: aaaa + 1: aaa + 2: aa + \O8aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/ab\Cde/ + abXde + 0: abXde + +/(?<=ab\Cde)X/ + abZdeX + 0: X + +/^\R/ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/^\R{2,3}x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R{2,3}?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + x + 0: x + \rx + 0: \x0dx + +/^\R+x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\n\P +Partial match: \x0d\x0a + \r\n\P\P +Partial match: \x0d\x0a + \rx + 0: \x0dx + +/^a$/ + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^a$/m + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/ + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/m + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/./ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/.{2,3}/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +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 + +/.{2,3}?/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +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 + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R +Error -30 (invalid data in workspace for DFA restart) + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + 0: text xxxxx text F> + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + 0: xxxxabcd + 1: xxxxabc + xx\xa0xabcd + 0: xx\xa0xabcd + 1: xx\xa0xabc + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + 0: xxxxxxxxabcd + 1: xxxxxxxxabc + xx\xa0xxxxxabcd + 0: xx\xa0xxxxxabcd + 1: xx\xa0xxxxxabc + +/-- End of testinput8 --/ diff --git a/ext/pcre/pcrelib/testdata/testoutput9 b/ext/pcre/pcrelib/testdata/testoutput9 index cb70f1c2593..95cd618dc2a 100644 --- a/ext/pcre/pcrelib/testdata/testoutput9 +++ b/ext/pcre/pcrelib/testdata/testoutput9 @@ -1,83 +1,516 @@ -/-- This set of tests check Unicode property support with the DFA matching - functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest - when running it. --/ +/-- 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. --/ -/\pL\P{Nd}/8 - AB - 0: AB +/\x{100}ab/8 + \x{100}ab + 0: \x{100}ab + +/a\x{100}*b/8 + ab + 0: ab + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + +/a\x{100}+b/8 + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + *** Failers +No match + ab +No match + +/\bX/8 + Xoanon + 0: X + +Xoanon + 0: X + \x{300}Xoanon + 0: X + *** Failers +No match + YXoanon +No match + +/\BX/8 + YXoanon + 0: X *** Failers - 0: Fa - A0 No match - 00 + Xoanon +No match + +Xoanon +No match + \x{300}Xoanon No match -/\X./8 - AB - 0: AB - A\x{300}BC - 0: A\x{300}B - A\x{300}\x{301}\x{302}BC - 0: A\x{300}\x{301}\x{302}B +/X\b/8 + X+oanon + 0: X + ZX\x{300}oanon + 0: X + FAX + 0: X + *** Failers +No match + Xoanon +No match + +/X\B/8 + Xoanon + 0: X *** Failers - 0: ** - \x{300} No match - -/\X\X/8 - ABC - 0: AB - A\x{300}B\x{300}\x{301}C - 0: A\x{300}B\x{300}\x{301} - A\x{300}\x{301}\x{302}BC - 0: A\x{300}\x{301}\x{302}B - *** Failers - 0: ** - \x{300} + X+oanon No match - -/^\pL+/8 + ZX\x{300}oanon +No match + FAX +No match + +/[^a]/8 abcd + 0: b + a\x{100} + 0: \x{100} + +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + 0: ab9 + \x{123}\x{123}45 + 0: \x{123}\x{123}4 + \x{400}\x{401}\x{402}6 + 0: \x{400}\x{401}\x{402}6 + *** Failers +No match + d99 +No match + \x{123}\x{122}4 +No match + \x{400}\x{403}6 +No match + \x{400}\x{401}\x{402}\x{402}6 +No match + +/a.b/8 + acb + 0: acb + a\x7fb + 0: a\x{7f}b + a\x{100}b + 0: a\x{100}b + *** Failers +No match + a\nb +No match + +/a(.{3})b/8 + a\x{4000}xyb + 0: a\x{4000}xyb + a\x{4000}\x7fyb + 0: a\x{4000}\x{7f}yb + a\x{4000}\x{100}yb + 0: a\x{4000}\x{100}yb + *** Failers +No match + a\x{4000}b +No match + ac\ncb +No match + +/a(.*?)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: a\xc0\x88 + 2: a\xc0 + +/a(.*?)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: a\x{100} + +/a(.*)(.)/ + a\xc0\x88b + 0: a\xc0\x88b + 1: a\xc0\x88 + 2: a\xc0 + +/a(.*)(.)/8 + a\x{100}b + 0: a\x{100}b + 1: a\x{100} + +/a(.)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + +/a(.)(.)/8 + a\x{240}bcd + 0: a\x{240}b + +/a(.?)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: a\xc0 + +/a(.?)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: a\x{240} + +/a(.??)(.)/ + a\xc0\x92bcd + 0: a\xc0\x92 + 1: a\xc0 + +/a(.??)(.)/8 + a\x{240}bcd + 0: a\x{240}b + 1: a\x{240} + +/a(.{3})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + *** Failers +No match + a\x{1234}b +No match + ac\ncb +No match + +/a(.{3,})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxbcdefghijb + 1: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers +No match + a\x{1234}b +No match + +/a(.{3,5})b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + 0: axbxxb + axxxxxbcdefghijb + 0: axxxxxb + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/a(.{3,5}?)b/8 + a\x{1234}xyb + 0: a\x{1234}xyb + a\x{1234}\x{4321}yb + 0: a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + 0: a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + 0: axxxxb + a\x{1234}\x{4321}\x{3412}\x{3421}b + 0: a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + 0: axbxxb + axxxxxbcdefghijb + 0: axxxxxb + *** Failers +No match + a\x{1234}b +No match + axxxxxxbcdefghijb +No match + +/^[a\x{c0}]/8 + *** Failers +No match + \x{100} +No match + +/(?<=aXb)cd/8 + aXbcd + 0: cd + +/(?<=a\x{100}b)cd/8 + a\x{100}bcd + 0: cd + +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + 0: cd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b + 0: \x{100}\x{100}\x{100}b + *** Failers +No match + \x{100}\x{100}b +No match + +/\x{ab}/8 + \x{ab} + 0: \x{ab} + \xc2\xab + 0: \x{ab} + *** Failers +No match + \x00{ab} +No match + +/(?<=(.))X/8 + WXYZ + 0: X + \x{256}XYZ + 0: X + *** Failers +No match + XYZ +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 + 0: \x{100}b + +/^[^a]{2,}/8 + \x{100}bcAa + 0: \x{100}bcA + 1: \x{100}bc + 2: \x{100}b + +/^[^a]{2,}?/8 + \x{100}bca + 0: \x{100}bc + 1: \x{100}b + +/[^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 + 0: \x{100}b + +/^[^a]{2,}/8i + \x{100}bcAa + 0: \x{100}bc + 1: \x{100}b + +/^[^a]{2,}?/8i + \x{100}bca + 0: \x{100}bc + 1: \x{100}b + +/\x{100}{0,0}/8 + abcd + 0: + +/\x{100}?/8 + abcd + 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} + 0: \x{100} + +/\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 + 0: \x{100}\x{100}\x{100} + +/\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 + 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} + 2: \x{100}\x{100}\x{100}\x{100}\x{100} + 3: \x{100}\x{100}\x{100}\x{100} + 4: \x{100}\x{100}\x{100} + +/(?<=a\x{100}{2}b)X/8 + Xyyya\x{100}\x{100}bXzzz + 0: X + +/\D*/8 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many subsidiary matches + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 4: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 6: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 7: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 8: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 9: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +10: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +11: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +12: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +13: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +14: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +15: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +16: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +18: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +19: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/\D*/8 + \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 + 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} + 3: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 4: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 5: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 6: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 7: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 8: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} + 9: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +10: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +11: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +12: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +13: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +14: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +15: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +16: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +17: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +18: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +19: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +20: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} +21: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\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 + 1X2 + 0: X + 1\x{100}2 + 0: \x{100} + +/>\S/8 + > >X Y + 0: >X + > >\x{100} Y + 0: >\x{100} + +/\d/8 + \x{100}3 + 0: 3 + +/\s/8 + \x{100} X + 0: + +/\D+/8 + 12abcd34 0: abcd 1: abc 2: ab 3: a - a - 0: a - *** Failers -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 + *** Failers 0: *** Failers 1: *** Failer 2: *** Faile @@ -89,1949 +522,850 @@ No match 8: *** 9: ** 10: * - \x{300}\x{301}\x{302} + 1234 No match -/\X?abc/8 - abc +/\D{2,3}/8 + 12abcd34 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}abc - \x{300}abc - 0: abc - *** Failers -No match - -/^\X?abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - *** Failers -No match - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz -No match - \x{300}abc -No match - -/\X*abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc - \x{300}abc - 0: abc - *** Failers -No match - -/^\X*abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc - *** Failers -No match - \x{300}abc -No match - -/^\pL?=./8 - A=b - 0: A=b - =c - 0: =c - *** Failers -No match - 1=2 -No match - AAAA=b -No match - -/^\pL*=./8 - AAAA=b - 0: AAAA=b - =c - 0: =c - *** Failers -No match - 1=2 -No match - -/^\X{2,3}X/8 - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - *** Failers -No match - X -No match - A\x{300}\x{301}\x{302}X -No match - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X -No match - -/^\pC\pL\pM\pN\pP\pS\pZ\s+ <34 + 0: > < + *** Failers +No match + +/>\s{2,3} < + ab> < + *** Failers +No match + ab> \s{2,3}? < + ab> < + *** Failers +No match + ab> \xff< + 0: \xff -/^[\p{Arabic}]/8 - \x{06e9} - 0: \x{6e9} - \x{060b} - 0: \x{60b} - ** Failers -No match - X\x{06e9} -No match +/[\xff]/8 + >\x{ff}< + 0: \x{ff} -/^[\P{Yi}]/8 - \x{2f800} - 0: \x{2f800} - ** Failers - 0: * - \x{a014} -No match - \x{a4c6} -No match - -/^\p{Any}X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - X -No match - -/^\P{Any}X/8 - ** Failers -No match - AX -No match - -/^\p{Any}?X/8 +/[^\xFF]/ XYZ 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - ABXYZ -No match -/^\P{Any}?X/8 +/[^\xff]/8 XYZ 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - ABXYZ + \x{123} + 0: \x{123} + +/^[ac]*b/8 + xb No match -/^\p{Any}+X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers -No match - XYZ +/^[ac\x{100}]*b/8 + xb No match -/^\P{Any}+X/8 - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - A\x{1234}XYZ -No match - XYZ +/^[^x]*b/8i + xb No match -/^\p{Any}*X/8 - XYZ - 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers +/^[^x]*b/8 + xb No match - -/^\P{Any}*X/8 - XYZ - 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - A\x{1234}XYZ -No match - -/^[\p{Any}]X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - X -No match - -/^[\P{Any}]X/8 - ** Failers -No match - AX -No match - -/^[\p{Any}]?X/8 - XYZ - 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - ABXYZ -No match - -/^[\P{Any}]?X/8 - XYZ - 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - ABXYZ -No match - -/^[\p{Any}]+X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers -No match - XYZ -No match - -/^[\P{Any}]+X/8 - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - A\x{1234}XYZ -No match - XYZ -No match - -/^[\p{Any}]*X/8 - XYZ - 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers -No match - -/^[\P{Any}]*X/8 - XYZ - 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - A\x{1234}XYZ -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 - 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 -No match - abcdefgh -No match - \x{1234}\n\r\x{3456}xyz -No match - -/^\p{L&}X/8 - AXY - 0: AX - aXY - 0: aX - \x{1c5}XY - 0: \x{1c5}X - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^[\p{L&}]X/8 - AXY - 0: AX - aXY - 0: aX - \x{1c5}XY - 0: \x{1c5}X - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^\p{L&}+X/8 - AXY - 0: AX - aXY - 0: aX - AbcdeXyz - 0: AbcdeX - \x{1c5}AbXY - 0: \x{1c5}AbX - abcDEXypqreXlmn - 0: abcDEXypqreX - 1: abcDEX - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^[\p{L&}]+X/8 - AXY - 0: AX - aXY - 0: aX - AbcdeXyz - 0: AbcdeX - \x{1c5}AbXY - 0: \x{1c5}AbX - abcDEXypqreXlmn - 0: abcDEXypqreX - 1: abcDEX - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^\p{L&}+?X/8 - AXY - 0: AX - aXY - 0: aX - AbcdeXyz - 0: AbcdeX - \x{1c5}AbXY - 0: \x{1c5}AbX - abcDEXypqreXlmn - 0: abcDEXypqreX - 1: abcDEX - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^[\p{L&}]+?X/8 - AXY - 0: AX - aXY - 0: aX - AbcdeXyz - 0: AbcdeX - \x{1c5}AbXY - 0: \x{1c5}AbX - abcDEXypqreXlmn - 0: abcDEXypqreX - 1: abcDEX - ** Failers -No match - \x{1bb}XY -No match - \x{2b0}XY -No match - !XY -No match - -/^\P{L&}X/8 - !XY - 0: !X - \x{1bb}XY - 0: \x{1bb}X - \x{2b0}XY - 0: \x{2b0}X - ** Failers -No match - \x{1c5}XY -No match - AXY -No match - -/^[\P{L&}]X/8 - !XY - 0: !X - \x{1bb}XY - 0: \x{1bb}X - \x{2b0}XY - 0: \x{2b0}X - ** Failers -No match - \x{1c5}XY -No match - AXY -No match - -/^\x{023a}+?(\x{0130}+)/8i - \x{023a}\x{2c65}\x{0130} - 0: \x{23a}\x{2c65}\x{130} -/^\x{023a}+([^X])/8i - \x{023a}\x{2c65}X - 0: \x{23a}\x{2c65} - -/\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} +/^\d*b/8 + xb +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} - 2: \x{c0}\x{e0} - 3: \x{c0} +/(|a)/g8 + catac + 0: + 0: a + 1: + 0: + 0: a + 1: + 0: + 0: + a\x{256}a + 0: a + 1: + 0: + 0: a + 1: + 0: -/Check property support in non-UTF-8 mode/ +/^\x{85}$/8i + \x{85} + 0: \x{85} + +/^abc./mgx8 + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + 0: abc8 + 0: abc9 + +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + 0: abc8 + 0: abc9 + +/^a\Rb/8 + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0cb + 0: a\x{0c}b + a\x{85}b + 0: a\x{85}b + a\x{2028}b + 0: a\x{2028}b + a\x{2029}b + 0: a\x{2029}b + ** Failers +No match + a\n\rb +No match + +/^a\R*b/8 + ab + 0: ab + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0c\x{2028}\x{2029}b + 0: a\x{0c}\x{2028}\x{2029}b + a\x{85}b + 0: a\x{85}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}\x0cb + 0: a\x{0a}\x{0d}\x{85}\x{0c}b + +/^a\R+b/8 + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0c\x{2028}\x{2029}b + 0: a\x{0c}\x{2028}\x{2029}b + a\x{85}b + 0: a\x{85}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}\x0cb + 0: a\x{0a}\x{0d}\x{85}\x{0c}b + ** Failers +No match + ab +No match + +/^a\R{1,3}b/8 + a\nb + 0: a\x{0a}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}b + 0: a\x{0a}\x{0d}\x{85}b + a\r\n\r\nb + 0: a\x{0d}\x{0a}\x{0d}\x{0a}b + a\r\n\r\n\r\nb + 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b + a\n\r\n\rb + 0: a\x{0a}\x{0d}\x{0a}\x{0d}b + a\n\n\r\nb + 0: a\x{0a}\x{0a}\x{0d}\x{0a}b + ** Failers +No match + a\n\n\n\rb +No match + a\r +No match + +/\h+\V?\v{3,4}/8 + \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 + \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 + >\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 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + 0: X\x{0a}\x{0a}\x{0a} + +/\H\h\V\v/8 + X X\x0a + 0: X X\x{0a} + X\x09X\x0b + 0: X\x{09}X\x{0b} + ** Failers +No match + \x{a0} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \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} + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + \x09\x20\x{a0}\x0a\x0b\x0c + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x20\x{a0}\x0a\x0b +No match + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + 0: \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} + 0: X\x{180e}X\x{85} + ** Failers +No match + \x{2009} X\x0a +No match + +/\H*\h+\V?\v{3,4}/8 + \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} + \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a + 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} + 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} + \x09\x20\x{202f}\x0a\x0b\x0c + 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} + ** Failers +No match + \x09\x{200a}\x{a0}\x{2028}\x0b +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ +No match + a\x0bb\ +No match -/\p{L}{4}/ - 123abcdefg +/X/8f + A\x{1ec5}ABCXYZ + 0: X + +/abcd*/8 + xxxxabcd\P 0: abcd - 123abc\xc4\xc5zz - 0: abc\xc4 + 1: abc + xxxxabcd\P\P +Partial match: abcd -/\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}/8 - \x{102A4}\x{AA52}\x{A91D}\x{1C46}\x{10283}\x{1092E}\x{1C6B}\x{A93B}\x{A8BF}\x{1BA0}\x{A50A}==== - 0: \x{102a4}\x{aa52}\x{a91d}\x{1c46}\x{10283}\x{1092e}\x{1c6b}\x{a93b}\x{a8bf}\x{1ba0}\x{a50a} +/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 -/\x{a77d}\x{1d79}/8i - \x{a77d}\x{1d79} - 0: \x{a77d}\x{1d79} - \x{1d79}\x{a77d} - 0: \x{1d79}\x{a77d} +/abc\d*/8 + xxxxabc1\P + 0: abc1 + 1: abc + xxxxabc1\P\P +Partial match: abc1 -/\x{a77d}\x{1d79}/8 - \x{a77d}\x{1d79} - 0: \x{a77d}\x{1d79} - ** Failers -No match - \x{1d79}\x{a77d} -No match +/abc[de]*/8 + xxxxabcde\P + 0: abcde + 1: abcd + 2: abc + xxxxabcde\P\P +Partial match: abcde -/^\p{Xan}/8 - ABCD - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - ** Failers -No match - _ABC -No match +/\bthe cat\b/8 + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat -/^\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 -No match +/ab\Cde/8 + abXde +Error -16 (item unsupported for DFA matching) -/^\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_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - ** Failers -No match - _ABC -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 -No match +/(?<=ab\Cde)X/8 +Failed: \C not allowed in lookbehind assertion at offset 10 -/^>\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - ** Failers -No match - \x{0b} -No match +/./8 + \r\P + 0: \x{0d} + \r\P\P +Partial match: \x{0d} + +/.{2,3}/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +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} -/^>\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} - 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: > +/.{2,3}?/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +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} -/^>\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} - 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: > - -/^>\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} - 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} - -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\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} - 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: > +/[^\x{100}]/8 + \x{100}\x{101}X + 0: \x{101} -/^>\p{Xps}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - >\x{a0} - 0: >\x{a0} - ** Failers -No match - \x{0b} -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} - 0: >\x{1680}\x{2028}\x{0b} - 1: >\x{1680}\x{2028} - 2: >\x{1680} - -/^>\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} - 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}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\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 - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers -No match - [] -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_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers -No match - [] -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 --/ - -/\b...\B/8W - abc_ - 0: abc - \x{37e}abc\x{376} - 0: abc - \x{37e}\x{376}\x{371}\x{393}\x{394} - 0: \x{376}\x{371}\x{393} - !\x{c0}++\x{c1}\x{c2} - 0: ++\x{c1} - !\x{c0}+++++ - 0: \x{c0}++ - -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ - -/\b...\B/8 - abc_ - 0: abc - ** Failers - 0: Fai - \x{37e}abc\x{376} -No match - \x{37e}\x{376}\x{371}\x{393}\x{394} -No match - !\x{c0}++\x{c1}\x{c2} -No match - !\x{c0}+++++ -No match - -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ - -/\b...\B/W - abc_ - 0: abc - !\x{c0}++\x{c1}\x{c2} - 0: ++\xc1 - !\x{c0}+++++ - 0: \xc0++ +/[^\x{100}]+/8 + \x{100}\x{101}X + 0: \x{101}X + 1: \x{101} /-- End of testinput9 --/ diff --git a/ext/pcre/pcrelib/ucp.h b/ext/pcre/pcrelib/ucp.h index d68737e31de..59c3bec3d37 100644 --- a/ext/pcre/pcrelib/ucp.h +++ b/ext/pcre/pcrelib/ucp.h @@ -153,7 +153,19 @@ enum { ucp_Old_Turkic, ucp_Samaritan, ucp_Tai_Tham, - ucp_Tai_Viet + ucp_Tai_Viet, + /* New for Unicode 6.0.0: */ + ucp_Batak, + ucp_Brahmi, + ucp_Mandaic, + /* New for Unicode 6.1.0: */ + ucp_Chakma, + ucp_Meroitic_Cursive, + ucp_Meroitic_Hieroglyphs, + ucp_Miao, + ucp_Sharada, + ucp_Sora_Sompeng, + ucp_Takri }; #endif