diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 726fa1bea5..027ec31982 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,13 @@ The license applies to all entries newer than 2009-04-28. */ +2012-02-07 22:25 UTC+0100 Viktor Szakats (harbour syenar.net) + * src/3rd/pcre/Makefile + * src/3rd/pcre/* + + src/3rd/pcre/pcrejitc.c + * 8.12 -> 8.21 (using hb3rdpat) + ; NOTE: New JIT feature off by default, not enabled + 2012-02-07 22:10 UTC+0100 Viktor Szakats (harbour syenar.net) * src/3rd/jpeg/Makefile * src/3rd/jpeg/* diff --git a/harbour/src/3rd/pcre/LICENCE b/harbour/src/3rd/pcre/LICENCE index 0dd22571ad..ae7bbcf8cf 100644 --- a/harbour/src/3rd/pcre/LICENCE +++ b/harbour/src/3rd/pcre/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-2011 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-2011 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-2011 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-2011, Google Inc. All rights reserved. diff --git a/harbour/src/3rd/pcre/Makefile b/harbour/src/3rd/pcre/Makefile index 1fa2cd60fb..3b5c357ef7 100644 --- a/harbour/src/3rd/pcre/Makefile +++ b/harbour/src/3rd/pcre/Makefile @@ -19,6 +19,7 @@ C_SOURCES := \ pcreget.c \ pcreglob.c \ pcreinfo.c \ + pcrejitc.c \ pcremktb.c \ pcrenewl.c \ pcreoutf.c \ @@ -72,8 +73,8 @@ else endif # ORIGIN http://www.pcre.org/ -# VER 8.12 -# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.12.tar.gz +# VER 8.21 +# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.21.tar.gz # DIFF pcre.dif # # MAP LICENCE @@ -90,6 +91,7 @@ endif # MAP pcre_get.c pcreget.c # MAP pcre_globals.c pcreglob.c # MAP pcre_info.c pcreinfo.c +# MAP pcre_jit_compile.c pcrejitc.c # MAP pcre_maketables.c pcremktb.c # MAP pcre_newline.c pcrenewl.c # MAP pcre_ord2utf8.c pcreoutf.c diff --git a/harbour/src/3rd/pcre/config.h b/harbour/src/3rd/pcre/config.h index dd03a16b1b..7282d1e7cc 100644 --- a/harbour/src/3rd/pcre/config.h +++ b/harbour/src/3rd/pcre/config.h @@ -250,7 +250,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.21" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -259,7 +259,17 @@ 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.21" + +/* The value of PCREGREP_BUFSIZE determines the size of buffer used by + pcregrep to hold parts of the file it is searching. On systems that support + it, "configure" can be used to override the default, which is 8192. This is + also the minimum value. The actual amount of memory used by pcregrep is + three times this number, because it allows for the buffering of "before" + and "after" lines. */ +#ifndef PCREGREP_BUFSIZE +#define PCREGREP_BUFSIZE 20480 +#endif /* If you are compiling for a system other than a Unix-like system or @@ -293,6 +303,9 @@ them both to 0; an emulation function will be used. */ #define STDC_HEADERS 1 #endif +/* Define to enable support for Just-In-Time compiling. */ +/* #undef SUPPORT_JIT */ + /* Define to allow pcregrep to be linked with libbz2, so that it is able to handle .bz2 files. */ /* #undef SUPPORT_LIBBZ2 */ @@ -304,7 +317,10 @@ them both to 0; an emulation function will be used. */ handle .gz files. */ /* #undef SUPPORT_LIBZ */ -/* Define to enable support for Unicode properties */ +/* Define to enable JIT support in pcregrep. */ +/* #undef SUPPORT_PCREGREP_JIT */ + +/* Define to enable support for Unicode properties. */ /* #undef SUPPORT_UCP */ /* Define to enable support for the UTF-8 Unicode encoding. This will work @@ -315,7 +331,7 @@ them both to 0; an emulation function will be used. */ /* Version number of package */ #ifndef VERSION -#define VERSION "8.12" +#define VERSION "8.21" #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/harbour/src/3rd/pcre/pcre.dif b/harbour/src/3rd/pcre/pcre.dif index 1e6a91ab6d..4dcc29209e 100644 --- a/harbour/src/3rd/pcre/pcre.dif +++ b/harbour/src/3rd/pcre/pcre.dif @@ -1,7 +1,7 @@ -diff -urN pcre.orig/pcrefinf.c pcre/pcrefinf.c ---- pcre.orig/pcrefinf.c 2011-01-15 18:09:50.426241817 +0100 -+++ pcre/pcrefinf.c 2011-01-15 18:09:50.696242981 +0100 -@@ -126,7 +126,7 @@ +diff -urN pcre.orig\pcrefinf.c pcre\pcrefinf.c +--- pcre.orig\pcrefinf.c Tue Feb 07 22:22:32 2012 ++++ pcre\pcrefinf.c Tue Feb 07 22:22:32 2012 +@@ -139,7 +139,7 @@ case PCRE_INFO_MINLENGTH: *((int *)where) = (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? @@ -9,10 +9,10 @@ diff -urN pcre.orig/pcrefinf.c pcre/pcrefinf.c + (int)study->minlength : -1; break; - case PCRE_INFO_LASTLITERAL: -diff -urN pcre.orig/pcreglob.c pcre/pcreglob.c ---- pcre.orig/pcreglob.c 2011-01-15 18:09:50.446241418 +0100 -+++ pcre/pcreglob.c 2011-01-15 18:09:50.696242981 +0100 + case PCRE_INFO_JIT: +diff -urN pcre.orig\pcreglob.c pcre\pcreglob.c +--- pcre.orig\pcreglob.c Tue Feb 07 22:22:32 2012 ++++ pcre\pcreglob.c Tue Feb 07 22:22:32 2012 @@ -74,11 +74,17 @@ PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; diff --git a/harbour/src/3rd/pcre/pcre.h b/harbour/src/3rd/pcre/pcre.h index 21c4673724..58ea327e9b 100644 --- a/harbour/src/3rd/pcre/pcre.h +++ b/harbour/src/3rd/pcre/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-2011 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 21 #define PCRE_PRERELEASE -#define PCRE_DATE 2011-01-15 +#define PCRE_DATE 2011-12-12 /* 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,20 +98,25 @@ 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 */ +#define PCRE_UTF8 0x00000800 /* Compile, used in exec, DFA exec */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ #define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ @@ -119,7 +124,7 @@ compile-time only bits for runtime options, or vice versa. */ #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,12 +133,12 @@ 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 */ @@ -163,6 +168,33 @@ compile-time only bits for runtime options, or vice versa. */ #define PCRE_ERROR_BADNEWLINE (-23) #define PCRE_ERROR_BADOFFSET (-24) #define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_RECURSELOOP (-26) +#define PCRE_ERROR_JIT_STACKLIMIT (-27) + +/* 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 /* Request types for pcre_fullinfo() */ @@ -183,6 +215,8 @@ 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 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -196,6 +230,12 @@ compatible. */ #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 +#define PCRE_CONFIG_JIT 9 + +/* Request types for pcre_study(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_STUDY_JIT_COMPILE 0x0001 /* Bit flags for the pcre_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ @@ -206,12 +246,16 @@ 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_pcre_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre_jit_stack pcre_jit_stack; + /* 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,6 +276,7 @@ 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; /* The structure for passing out data via the pcre_callout_function. We use a @@ -254,6 +299,8 @@ 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; @@ -277,6 +324,10 @@ PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ +/* User defined callback which provides a stack just before the match starts. */ + +typedef pcre_jit_stack *(*pcre_jit_callback)(void *); + /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, @@ -309,8 +360,15 @@ PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); PCRE_EXP_DECL const char *pcre_version(void); +/* JIT compiler related functions. */ + +PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); +PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); +PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, pcre_jit_callback, void *); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/harbour/src/3rd/pcre/pcrecomp.c b/harbour/src/3rd/pcre/pcrecomp.c index e3005360a7..3d33f06f45 100644 --- a/harbour/src/3rd/pcre/pcrecomp.c +++ b/harbour/src/3rd/pcre/pcrecomp.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-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -88,14 +88,21 @@ 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) /* Table for handling escaped characters in the range '0'-'z'. Positive returns @@ -393,7 +400,7 @@ static const char error_texts[] = "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" @@ -409,6 +416,11 @@ static const char error_texts[] = "(*MARK) must have an argument\0" "this version of PCRE is not compiled with PCRE_UCP 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" ; /* Table to identify digits and hex digits. This is used when compiling @@ -545,7 +557,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, uschar **, const uschar **, int *, BOOL, BOOL, int, int, int *, int *, branch_chain *, compile_data *, int *); @@ -576,6 +588,77 @@ 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) +{ +uschar *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 = (pcre_malloc)(newsize); +if (newspace == NULL) return ERR21; + +memcpy(newspace, cd->start_workspace, cd->workspace_size); +cd->hwm = (uschar *)newspace + (cd->hwm - cd->start_workspace); +if (cd->workspace_size > COMPILE_WORK_SIZE) + (pcre_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 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); +} + + + /************************************************* * Handle escapes * *************************************************/ @@ -642,12 +725,42 @@ 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 ((digitab[ptr[1]] & ctype_xdigit) != 0 && (digitab[ptr[2]] & ctype_xdigit) != 0 + && (digitab[ptr[3]] & ctype_xdigit) != 0 && (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 + } + } + } + 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 @@ -664,6 +777,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; @@ -792,6 +906,28 @@ else 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 ((digitab[ptr[1]] & ctype_xdigit) != 0 && (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; @@ -885,9 +1021,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. */ @@ -996,39 +1134,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 * *************************************************/ @@ -1397,34 +1502,24 @@ 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) +first_significant_code(const uschar *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: @@ -1474,18 +1569,19 @@ 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 + utf8 TRUE in UTF-8 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(uschar *code, BOOL utf8, BOOL atend, compile_data *cd) { int length = -1; @@ -1502,26 +1598,34 @@ for (;;) 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)? 2:0), utf8, 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; @@ -1538,7 +1642,7 @@ for (;;) 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); + d = find_fixedlength(cs + 2, utf8, atend, cd); if (d < 0) return d; branchlength += d; cc += 1 + LINK_SIZE; @@ -1555,22 +1659,36 @@ for (;;) /* 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] + _pcre_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]; break; @@ -1578,13 +1696,13 @@ for (;;) /* 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]; + if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; #endif break; @@ -1592,11 +1710,13 @@ 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]; + if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; #endif break; @@ -1613,6 +1733,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: @@ -1625,7 +1749,8 @@ 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; @@ -1644,6 +1769,8 @@ for (;;) switch (*cc) { + case OP_CRPLUS: + case OP_CRMINPLUS: case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: @@ -1664,8 +1791,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 */ @@ -1698,6 +1908,7 @@ _pcre_find_bracket(const uschar *code, BOOL utf8, 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 @@ -1716,7 +1927,8 @@ for (;;) /* 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; @@ -1758,7 +1970,7 @@ for (;;) break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } @@ -1774,20 +1986,33 @@ for (;;) if (utf8) 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: + case OP_POSQUERYI: if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; break; } @@ -1864,7 +2089,7 @@ for (;;) break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } @@ -1880,20 +2105,33 @@ for (;;) if (utf8) 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: + case OP_POSQUERYI: if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; break; } @@ -1932,9 +2170,9 @@ could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8, 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 + _pcre_OP_lengths[*code], TRUE); code < endcode; - code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE)) + code = first_significant_code(code + _pcre_OP_lengths[c], TRUE)) { const uschar *ccode; @@ -1950,24 +2188,31 @@ 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 uschar *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)) @@ -1978,13 +2223,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 += _pcre_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 */ @@ -2071,8 +2342,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: @@ -2112,6 +2384,7 @@ 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; @@ -2120,17 +2393,26 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE #ifdef SUPPORT_UTF8 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: + case OP_POSQUERYI: if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f]; break; case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f]; break; #endif @@ -2145,7 +2427,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. */ @@ -2168,6 +2450,8 @@ 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 @@ -2218,6 +2502,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 @@ -2232,14 +2527,21 @@ 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; @@ -2622,11 +2924,11 @@ if (next >= 0) switch(op_code) #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: + case OP_CHARI: #ifdef SUPPORT_UTF8 GETCHARTEST(c, previous); #else @@ -2649,11 +2951,15 @@ if (next >= 0) switch(op_code) #endif /* SUPPORT_UTF8 */ return (c != cd->fcc[next]); /* Non-UTF-8 mode */ - /* For OP_NOT, its data is always a single-byte character. */ + /* For OP_NOT and OP_NOTI, the data is always a single-byte character. These + opcodes are not used for multi-byte characters, because they are coded using + an XCLASS instead. */ case OP_NOT: + return (c = *previous) == next; + + case OP_NOTI: if ((c = *previous) == next) return TRUE; - if ((options & PCRE_CASELESS) == 0) return FALSE; #ifdef SUPPORT_UTF8 if (utf8) { @@ -2758,7 +3064,7 @@ replaced by OP_PROP codes when PCRE_UCP is set. */ switch(op_code) { case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: #ifdef SUPPORT_UTF8 GETCHARTEST(c, previous); #else @@ -2945,6 +3251,7 @@ Arguments: firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) reqbyteptr 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 @@ -2956,7 +3263,7 @@ 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_data *cd, int *lengthptr) + int cond_depth, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ @@ -2965,7 +3272,7 @@ int greedy_default, greedy_non_default; int firstbyte, reqbyte; int zeroreqbyte, zerofirstbyte; int req_caseopt, reqvary, tempreqvary; -int options = *optionsptr; +int options = *optionsptr; /* May change dynamically */ int after_manual_callout = 0; int length_prevgroup = 0; register int c; @@ -2983,6 +3290,10 @@ uschar *previous_callout = NULL; uschar *save_hwm = NULL; uschar classbits[32]; +/* We can fish out the UTF-8 setting once and for all into a BOOL, but we +must not do this for other options (e.g. PCRE_EXTENDED) because they may change +dynamically as we process the pattern. */ + #ifdef SUPPORT_UTF8 BOOL class_utf8; BOOL utf8 = (options & PCRE_UTF8) != 0; @@ -2991,7 +3302,6 @@ uschar *class_utf8data_base; uschar utf8_char[6]; #else BOOL utf8 = FALSE; -uschar *utf8_char = NULL; #endif #ifdef PCRE_DEBUG @@ -3042,6 +3352,7 @@ for (;; ptr++) int subfirstbyte; int terminator; int mclength; + int tempbracount; uschar mcbuffer[8]; /* Get next byte in the pattern */ @@ -3066,7 +3377,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; @@ -3089,7 +3401,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\n", *lengthptr, (int)(code - last_code), + 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, @@ -3115,7 +3428,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; @@ -3163,7 +3477,7 @@ 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) { @@ -3222,17 +3536,18 @@ 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; + *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 @@ -3368,7 +3683,7 @@ for (;; ptr++) if (lengthptr != NULL) { - *lengthptr += class_utf8data - class_utf8data_base; + *lengthptr += (int)(class_utf8data - class_utf8data_base); class_utf8data = class_utf8data_base; } @@ -3504,6 +3819,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) @@ -3978,15 +4298,15 @@ for (;; ptr++) 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. + operate on single-bytes characters 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. */ + 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative. + Note that OP_NOT[I] 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 && @@ -3997,13 +4317,13 @@ for (;; ptr++) { zeroreqbyte = reqbyte; - /* The OP_NOT opcode works on one-byte characters only. */ + /* The OP_NOT[I] opcodes work on one-byte characters only. */ if (negate_class) { if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; - *code++ = OP_NOT; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; *code++ = class_lastchar; break; } @@ -4062,7 +4382,7 @@ for (;; ptr++) /* 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 @@ -4131,8 +4451,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; @@ -4155,14 +4475,45 @@ for (;; ptr++) } else repeat_type = greedy_default; + /* 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_RECURSE) + { + memmove(previous + 1 + LINK_SIZE, previous, 1 + LINK_SIZE); + *previous = OP_ONCE; + PUT(previous, 1, 2 + 2*LINK_SIZE); + previous[2 + 2*LINK_SIZE] = OP_KET; + PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); + code += 2 + 2 * LINK_SIZE; + length_prevgroup = 3 + 3*LINK_SIZE; + + /* When actually compiling, we need to check whether this was a forward + reference, and if so, adjust the offset. */ + + if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE) + { + int offset = GET(cd->hwm, -LINK_SIZE); + if (offset == previous + 1 - cd->start_code) + PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE); + } + } + + /* Now handle repetition for the different types of item. */ + /* If previous was a character 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 == OP_CHAR || *previous == OP_CHARNC) + if (*previous == OP_CHAR || *previous == OP_CHARI) { + op_type = (*previous == OP_CHAR)? 0 : OP_STARI - OP_STAR; + /* 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 @@ -4173,7 +4524,7 @@ for (;; ptr++) { uschar *lastchar = code - 1; while((*lastchar & 0xc0) == 0x80) lastchar--; - c = code - lastchar; /* Length of UTF-8 character */ + c = (int)(code - lastchar); /* Length of UTF-8 character */ memcpy(utf8_char, lastchar, c); /* Save the char */ c |= 0x80; /* Flag c as a length */ } @@ -4207,12 +4558,12 @@ for (;; ptr++) /* 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. */ + repeat_type. We can also test for auto-possessification. OP_NOT and OP_NOTI + are currently used only for single-byte chars. */ - else if (*previous == OP_NOT) + else if (*previous == OP_NOT || *previous == OP_NOTI) { - op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ + op_type = ((*previous == OP_NOT)? OP_NOTSTAR : OP_NOTSTARI) - OP_STAR; c = previous[1]; if (!possessive_quantifier && repeat_max < 0 && @@ -4409,7 +4760,8 @@ for (;; ptr++) #ifdef SUPPORT_UTF8 *previous == OP_XCLASS || #endif - *previous == OP_REF) + *previous == OP_REF || + *previous == OP_REFI) { if (repeat_max == 0) { @@ -4443,35 +4795,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; + uschar *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 @@ -4492,10 +4844,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 @@ -4515,6 +4868,7 @@ for (;; ptr++) *previous++ = OP_SKIPZERO; goto END_REPEAT; } + brazeroptr = previous; /* Save for possessive optimizing */ *previous++ = OP_BRAZERO + repeat_type; } @@ -4577,16 +4931,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; + for (i = 1; i < repeat_min; i++) { uschar *hc; uschar *this_hwm = cd->hwm; memcpy(code, previous, 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 = (uschar *)cd->start_workspace + save_offset; + this_hwm = (uschar *)cd->start_workspace + this_offset; + } + for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len); @@ -4654,6 +5024,21 @@ for (;; ptr++) } memcpy(code, previous, 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 = (uschar *)cd->start_workspace + save_offset; + this_hwm = (uschar *)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)); @@ -4679,35 +5064,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 *ketcode = code - 1 - LINK_SIZE; uschar *bracode = ketcode - GET(ketcode, 1); - *ketcode = OP_KETRMAX + repeat_type; - if (lengthptr == NULL && *bracode != OP_ONCE) + + /* 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)) + uschar *scode = bracode; + do { - *bracode += OP_SBRA - OP_BRA; - break; + if (could_be_empty_branch(scode, ketcode, utf8, 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, utf8, cd, save_hwm); + memmove(bracode + 1+LINK_SIZE, bracode, 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; } } } @@ -4728,13 +5188,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 @@ -4765,16 +5230,26 @@ 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. */ @@ -4828,11 +5303,14 @@ for (;; ptr++) while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {}; 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); } @@ -4849,22 +5327,32 @@ for (;; ptr++) if (namelen == verbs[i].len && strncmp((char *)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 firstbyte after *ACCEPT */ + if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; } - /* Handle the cases with/without an argument */ + /* Handle other cases with/without an argument */ - if (arglen == 0) + else if (arglen == 0) { if (verbs[i].op < 0) /* Argument is mandatory */ { @@ -4872,11 +5360,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 @@ -4887,11 +5371,7 @@ 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); code += arglen; @@ -5153,6 +5633,7 @@ for (;; ptr++) /* ------------------------------------------------------------ */ case CHAR_EQUALS_SIGN: /* Positive lookahead */ bravalue = OP_ASSERT; + cd->assert_depth += 1; ptr++; break; @@ -5167,6 +5648,7 @@ for (;; ptr++) continue; } bravalue = OP_ASSERT_NOT; + cd->assert_depth += 1; break; @@ -5176,11 +5658,13 @@ 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; @@ -5202,8 +5686,8 @@ 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; @@ -5571,17 +6055,28 @@ 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 && + else if (GET(called, 1) == 0 && cond_depth <= 0 && could_be_empty(called, code, bcptr, utf8, cd)) { *errorcodeptr = ERR40; @@ -5589,23 +6084,14 @@ for (;; ptr++) } } - /* 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 + byte (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; + groupsetfirstbyte = FALSE; } /* Can't determine a first byte now */ @@ -5666,9 +6152,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 firstbyte and reqbyte. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { @@ -5679,20 +6164,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; } /* 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 */ @@ -5728,43 +6206,52 @@ for (;; ptr++) skipbytes = 2; } - /* 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 */ + &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 */ )) 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. */ @@ -5829,7 +6316,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); @@ -5997,11 +6484,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)? @@ -6021,7 +6513,7 @@ for (;; ptr++) HANDLE_REFERENCE: /* Come here from named backref handling */ if (firstbyte == REQ_UNSET) firstbyte = 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; @@ -6081,9 +6573,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++ = (!utf8 && c == -ESC_C)? OP_ALLANY : -c; } } continue; @@ -6129,7 +6624,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 */ @@ -6158,7 +6653,7 @@ for (;; ptr++) else firstbyte = reqbyte = REQ_NONE; } - /* firstbyte was previously set; we can set reqbyte only the length is + /* firstbyte was previously set; we can set reqbyte only if the length is 1 or the matching is caseful. */ else @@ -6193,24 +6688,19 @@ 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) + cond_depth depth of nesting for conditional subpatterns firstbyteptr place to put the first required character, or a negative number reqbyteptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches @@ -6222,10 +6712,10 @@ Returns: TRUE on success */ static BOOL -compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr, +compile_regex(int options, uschar **codeptr, const uschar **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, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, + compile_data *cd, int *lengthptr) { const uschar *ptr = *ptrptr; uschar *code = *codeptr; @@ -6239,7 +6729,6 @@ int branchfirstbyte, branchreqbyte; int length; int orig_bracount; int max_bracount; -int old_external_options = cd->external_options; branch_chain bc; bc.outer = bcptr; @@ -6263,7 +6752,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) { @@ -6289,15 +6780,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) @@ -6312,21 +6794,13 @@ for (;;) into the length. */ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte, - &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length)) + &branchreqbyte, &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. */ @@ -6387,7 +6861,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) { @@ -6395,7 +6870,8 @@ 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; } @@ -6408,9 +6884,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) { @@ -6454,15 +6928,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; @@ -6522,8 +6987,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 @@ -6544,7 +7009,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 @@ -6554,35 +7018,38 @@ Returns: TRUE or FALSE */ static BOOL -is_anchored(register const uschar *code, int *options, unsigned int bracket_map, +is_anchored(register const uschar *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); + FALSE); register int op = *scode; /* Non-capturing brackets */ - if (op == OP_BRA) + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ - else if (op == OP_CBRA) + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); - if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; + if (!is_anchored(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ - else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC || + op == OP_COND) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and @@ -6597,9 +7064,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 */ @@ -6635,7 +7100,7 @@ is_startline(const uschar *code, unsigned int bracket_map, { do { const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], - NULL, 0, FALSE); + FALSE); register int op = *scode; /* If we are at the start of a conditional assertion group, *both* the @@ -6662,20 +7127,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); @@ -6684,7 +7151,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; } @@ -6699,7 +7166,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 */ @@ -6725,20 +7192,20 @@ 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 uschar *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)? 2:0; + const uschar *scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE); register int op = *scode; switch(op) @@ -6747,30 +7214,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 */ + case OP_EXACT: scode += 2; + /* 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 += 2; + /* 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; } @@ -6833,7 +7314,8 @@ 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]; @@ -6921,11 +7403,14 @@ while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && utf8 = (options & PCRE_UTF8) != 0; -/* Can't support UTF8 unless PCRE has been compiled to include the code. */ +/* Can't support UTF8 unless PCRE has been compiled to include the code. The +return of an error code from _pcre_valid_utf8() 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) + (errorcode = _pcre_valid_utf8((USPTR)pattern, -1, erroroffset)) != 0) { errorcode = ERR44; goto PCRE_EARLY_ERROR_RETURN2; @@ -6950,13 +7435,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 @@ -7022,9 +7505,10 @@ 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_workspace = cworkspace; +cd->workspace_size = COMPILE_WORK_SIZE; cd->start_pattern = (const uschar *)pattern; cd->end_pattern = (const uschar *)(pattern + strlen(pattern)); cd->req_varyopt = 0; @@ -7041,9 +7525,8 @@ 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, &firstbyte, &reqbyte, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, @@ -7060,7 +7543,7 @@ 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); +size = length + sizeof(real_pcre) + cd->names_found * cd->name_entry_size; re = (real_pcre *)(pcre_malloc)(size); if (re == NULL) @@ -7097,12 +7580,13 @@ 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->names_found = 0; cd->name_table = (uschar *)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 = (uschar *)(cd->start_workspace); cd->req_varyopt = 0; cd->had_accept = FALSE; cd->check_lookbehind = FALSE; @@ -7115,13 +7599,13 @@ of the function here. */ ptr = (const uschar *)pattern + skipatstart; code = (uschar *)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, + &firstbyte, &reqbyte, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; re->flags = cd->external_flags; -if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */ +if (cd->had_accept) reqbyte = REQ_NONE; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ @@ -7136,20 +7620,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 uschar *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 = _pcre_find_bracket(codestart, utf8, recno); + prev_recno = recno; + } + if (groupptr == NULL) errorcode = ERR53; + else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart)); + } } +/* If the workspace had to be expanded, free the new memory. */ + +if (cd->workspace_size > COMPILE_WORK_SIZE) + (pcre_free)((void *)cd->start_workspace); + /* Give an error if there's back reference to a non-existent capturing subpattern. */ @@ -7182,12 +7680,14 @@ if (cd->check_lookbehind) uschar *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; } PUT(cc, 1, fixed_length); @@ -7221,13 +7721,12 @@ 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); + firstbyte = find_firstassertedchar(codestart, FALSE); if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ { int ch = firstbyte & 255; diff --git a/harbour/src/3rd/pcre/pcreconf.c b/harbour/src/3rd/pcre/pcreconf.c index f5ebeec72a..2fdc99cf35 100644 --- a/harbour/src/3rd/pcre/pcreconf.c +++ b/harbour/src/3rd/pcre/pcreconf.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-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -83,6 +83,14 @@ switch (what) #endif break; + case PCRE_CONFIG_JIT: +#ifdef SUPPORT_JIT + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; diff --git a/harbour/src/3rd/pcre/pcredfa.c b/harbour/src/3rd/pcre/pcredfa.c index 61603cbdf7..5610201752 100644 --- a/harbour/src/3rd/pcre/pcredfa.c +++ b/harbour/src/3rd/pcre/pcredfa.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language (but see below for why this module is different). Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -121,18 +121,25 @@ static const uschar coptable[] = { 0, 0, /* \P, \p */ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ 0, /* \X */ - 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ - 1, /* Charnc */ + 1, /* Chari */ 1, /* not */ + 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 3, 3, 3, /* upto, minupto, exact */ 1, 1, 1, 3, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 3, 3, 3, /* upto I, minupto I, exact I */ + 1, 1, 1, 3, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 3, 3, 3, /* NOT upto, minupto, exact */ - 1, 1, 1, 3, /* NOT *+, ++, ?+, updo+ */ + 1, 1, 1, 3, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 3, 3, 3, /* NOT upto I, minupto I, exact I */ + 1, 1, 1, 3, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 3, 3, 3, /* Type upto, minupto, exact */ @@ -144,26 +151,30 @@ static const uschar coptable[] = { 0, /* NCLASS */ 0, /* XCLASS - variable length */ 0, /* REF */ + 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ - 0, /* Reverse */ - 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */ - 0, 0, 0, /* SBRA, SCBRA, SCOND */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ - 0, 0, /* BRAZERO, BRAMINZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */ - 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0 /* CLOSE, SKIPZERO */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -179,18 +190,25 @@ static const uschar poptable[] = { 1, 1, /* \P, \p */ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ 1, /* \X */ - 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ - 1, /* Charnc */ + 1, /* Chari */ 1, /* not */ + 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1, 1, 1, /* upto, minupto, exact */ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* upto I, minupto I, exact I */ + 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 1, 1, 1, /* NOT upto, minupto, exact */ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* NOT upto I, minupto I, exact I */ + 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 1, 1, 1, /* Type upto, minupto, exact */ @@ -202,26 +220,30 @@ static const uschar poptable[] = { 1, /* NCLASS */ 1, /* XCLASS - variable length */ 0, /* REF */ + 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ - 0, /* Reverse */ - 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */ - 0, 0, 0, /* SBRA, SCBRA, SCOND */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ - 0, 0, /* BRAZERO, BRAMINZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */ - 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0 /* CLOSE, SKIPZERO */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, @@ -252,7 +274,6 @@ these structures in, is a vector of ints. */ typedef struct stateblock { int offset; /* Offset to opcode */ int count; /* Count for repeats */ - int ims; /* ims flag bits */ int data; /* Some use extra data */ } stateblock; @@ -308,9 +329,7 @@ Arguments: offsetcount size of same workspace vector of workspace wscount size of same - ims the current ims flags rlevel function call recursion level - recursing regex recursive call level Returns: > 0 => number of match offset pairs placed in offsets = 0 => offsets overflowed; longest matches are present @@ -325,7 +344,6 @@ for the current character, one for the following character). */ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ - next_active_state->ims = ims; \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ @@ -336,7 +354,6 @@ for the current character, one for the following character). */ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ - next_active_state->ims = ims; \ next_active_state->data = (z); \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ @@ -348,7 +365,6 @@ for the current character, one for the following character). */ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ - next_new_state->ims = ims; \ next_new_state++; \ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ @@ -359,7 +375,6 @@ for the current character, one for the following character). */ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ - next_new_state->ims = ims; \ next_new_state->data = (z); \ next_new_state++; \ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ @@ -378,9 +393,7 @@ internal_dfa_exec( int offsetcount, int *workspace, int wscount, - int ims, - int rlevel, - int recursing) + int rlevel) { stateblock *active_states, *new_states, *temp_states; stateblock *next_active_state, *next_new_state; @@ -389,6 +402,8 @@ const uschar *ctypes, *lcc, *fcc; const uschar *ptr; const uschar *end_code, *first_op; +dfa_recursion_info new_recursive; + int active_count, new_count, match_count; /* Some fields in the md block are frequently referenced, so we load them into @@ -412,8 +427,8 @@ wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) / (2 * INTS_PER_STATEBLOCK); DPRINTF(("\n%.*s---------------------\n" - "%.*sCall to internal_dfa_exec f=%d r=%d\n", - rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing)); + "%.*sCall to internal_dfa_exec f=%d\n", + rlevel*2-2, SP, rlevel*2-2, SP, rlevel)); ctypes = md->tables + ctypes_offset; lcc = md->tables + lcc_offset; @@ -426,7 +441,8 @@ next_new_state = new_states = active_states + wscount; new_count = 0; first_op = this_start_code + 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)? 2:0); /* The first thing in any (sub) pattern is a bracket of some sort. Push all the alternative states onto the list, and find out where the end is. This @@ -525,7 +541,9 @@ else else { int length = 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)? + 2:0); do { ADD_NEW((int)(end_code - start_code + length), 0); @@ -605,6 +623,7 @@ for (;;) for (i = 0; i < active_count; i++) { stateblock *current_state = active_states + i; + BOOL caseless = FALSE; const uschar *code; int state_offset = current_state->offset; int count, codevalue, rrc; @@ -616,10 +635,6 @@ for (;;) else printf("0x%02x\n", c); #endif - /* This variable is referred to implicity in the ADD_xxx macros. */ - - ims = current_state->ims; - /* A negative offset is a special case meaning "hold off going to this (negated) state until the number of characters in the data field have been skipped". */ @@ -725,7 +740,12 @@ for (;;) /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry - on with the next opcode. Otherwise, unless we have an empty string and + on with the next opcode. For repeating opcodes, also add the repeat + state. Note that KETRPOS will always be encountered at the end of the + subpattern, because the possessive subpattern repeats are always handled + using recursive calls. Thus, it never adds any new states. + + At the end of the (sub)pattern, unless we have an empty string and PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the start of the subject, save the match data, shifting up all previous matches so we always have the longest first. */ @@ -733,6 +753,7 @@ for (;;) case OP_KET: case OP_KETRMIN: case OP_KETRMAX: + case OP_KETRPOS: if (code != end_code) { ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); @@ -749,7 +770,7 @@ for (;;) current_subject > start_subject + md->start_offset))) { if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; - else if (match_count > 0 && ++match_count * 2 >= offsetcount) + else if (match_count > 0 && ++match_count * 2 > offsetcount) match_count = 0; count = ((match_count == 0)? offsetcount : match_count * 2) - 2; if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int)); @@ -822,10 +843,14 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_CIRC: + if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_CIRCM: if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) || - ((ims & PCRE_MULTILINE) != 0 && - ptr != end_subject && - WAS_NEWLINE(ptr))) + (ptr != end_subject && WAS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } break; @@ -839,12 +864,6 @@ for (;;) } break; - /*-----------------------------------------------------------------*/ - case OP_OPT: - ims = code[1]; - ADD_ACTIVE(state_offset + 2, 0); - break; - /*-----------------------------------------------------------------*/ case OP_SOD: if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } @@ -890,11 +909,23 @@ for (;;) could_continue = TRUE; else if (clen == 0 || ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) && - ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen) + (ptr == end_subject - md->nllen) )) { ADD_ACTIVE(state_offset + 1, 0); } } - else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr)) + break; + + /*-----------------------------------------------------------------*/ + case OP_DOLLM: + if ((md->moptions & PCRE_NOTEOL) == 0) + { + if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || + ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) + { ADD_ACTIVE(state_offset + 1, 0); } + } + else if (IS_NEWLINE(ptr)) { ADD_ACTIVE(state_offset + 1, 0); } break; @@ -1950,7 +1981,7 @@ for (;;) break; /*-----------------------------------------------------------------*/ - case OP_CHARNC: + case OP_CHARI: if (clen == 0) break; #ifdef SUPPORT_UTF8 @@ -2136,19 +2167,35 @@ for (;;) break; /*-----------------------------------------------------------------*/ - /* Match a negated single character. This is only used for one-byte - characters, that is, we know that d < 256. The character we are + /* Match a negated single character casefully. This is only used for + one-byte characters, that is, we know that d < 256. The character we are checking (c) can be multibyte. */ case OP_NOT: - if (clen > 0) - { - unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d; - if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); } - } + if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); } break; /*-----------------------------------------------------------------*/ + /* Match a negated single character caselessly. This is only used for + one-byte characters, that is, we know that d < 256. The character we are + checking (c) can be multibyte. */ + + case OP_NOTI: + if (clen > 0 && c != d && c != fcc[d]) + { ADD_NEW(state_offset + dlen + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + + /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2160,7 +2207,7 @@ for (;;) if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) @@ -2188,6 +2235,15 @@ for (;;) break; /*-----------------------------------------------------------------*/ + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2198,7 +2254,7 @@ for (;;) if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) @@ -2224,6 +2280,15 @@ for (;;) break; /*-----------------------------------------------------------------*/ + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2234,7 +2299,7 @@ for (;;) if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) @@ -2260,13 +2325,18 @@ for (;;) break; /*-----------------------------------------------------------------*/ + case OP_EXACTI: + case OP_NOTEXACTI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) @@ -2290,6 +2360,15 @@ for (;;) break; /*-----------------------------------------------------------------*/ + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: @@ -2301,7 +2380,7 @@ for (;;) if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { #ifdef SUPPORT_UTF8 if (utf8 && d >= 128) @@ -2444,9 +2523,7 @@ for (;;) sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) @@ -2485,6 +2562,7 @@ for (;;) cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; + cb.mark = NULL; /* No (*MARK) support */ if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */ } if (rrc > 0) break; /* Fail this thread */ @@ -2511,7 +2589,7 @@ for (;;) { int value = GET2(code, LINK_SIZE+2); if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; - if (recursing > 0) + if (md->recursive != NULL) { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); } else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } } @@ -2535,9 +2613,7 @@ for (;;) sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == @@ -2552,28 +2628,47 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_RECURSE: { + dfa_recursion_info *ri; int local_offsets[1000]; int local_workspace[1000]; + const uschar *callpat = start_code + GET(code, 1); + int recno = (callpat == md->start_code)? 0 : + GET2(callpat, 1 + LINK_SIZE); int rc; - DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP, - recursing + 1)); + DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP)); + + /* Check for repeating a recursion without advancing the subject + pointer. This should catch convoluted mutual recursions. (Some simple + cases are caught at compile time.) */ + + for (ri = md->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && ptr == ri->subject_position) + return PCRE_ERROR_RECURSELOOP; + + /* Remember this recursion and where we started it so as to + catch infinite loops. */ + + new_recursive.group_num = recno; + new_recursive.subject_position = ptr; + new_recursive.prevrec = md->recursive; + md->recursive = &new_recursive; rc = internal_dfa_exec( md, /* fixed match data */ - start_code + GET(code, 1), /* this subexpression's code */ + callpat, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing + 1); /* regex recurse level */ + rlevel); /* function recursion level */ - DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP, - recursing + 1, rc)); + md->recursive = new_recursive.prevrec; /* Done this recursion */ + + DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP, + rc)); /* Ran out of internal offsets */ @@ -2605,8 +2700,98 @@ for (;;) } break; + /*-----------------------------------------------------------------*/ + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + { + int charcount, matched_count; + const uschar *local_ptr = ptr; + BOOL allow_zero; + + if (codevalue == OP_BRAPOSZERO) + { + allow_zero = TRUE; + codevalue = *(++code); /* Codevalue will be one of above BRAs */ + } + else allow_zero = FALSE; + + /* Loop to match the subpattern as many times as possible as if it were + a complete pattern. */ + + for (matched_count = 0;; matched_count++) + { + int local_offsets[2]; + int local_workspace[1000]; + + int rc = internal_dfa_exec( + md, /* fixed match data */ + code, /* this subexpression's code */ + local_ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(int), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + /* Failed to match */ + + if (rc < 0) + { + if (rc != PCRE_ERROR_NOMATCH) return rc; + break; + } + + /* Matched: break the loop if zero characters matched. */ + + charcount = local_offsets[1] - local_offsets[0]; + if (charcount == 0) break; + local_ptr += charcount; /* Advance temporary position ptr */ + } + + /* At this point we have matched the subpattern matched_count + times, and local_ptr is pointing to the character after the end of the + last match. */ + + if (matched_count > 0 || allow_zero) + { + const uschar *end_subpattern = code; + int next_state_offset; + + do { end_subpattern += GET(end_subpattern, 1); } + while (*end_subpattern == OP_ALT); + next_state_offset = + (int)(end_subpattern - start_code + LINK_SIZE + 1); + + /* Optimization: if there are no more active states, and there + are no new states yet set up, then skip over the subject string + right here, to save looping. Otherwise, set up the new state to swing + into action when the end of the matched substring is reached. */ + + if (i + 1 >= active_count && new_count == 0) + { + ptr = local_ptr; + clen = 0; + ADD_NEW(next_state_offset, 0); + } + else + { + const uschar *p = ptr; + const uschar *pp = local_ptr; + charcount = (int)(pp - p); + while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--; + ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + } + } + } + break; + /*-----------------------------------------------------------------*/ case OP_ONCE: + case OP_ONCE_NC: { int local_offsets[2]; int local_workspace[1000]; @@ -2620,9 +2805,7 @@ for (;;) sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc >= 0) { @@ -2656,7 +2839,7 @@ for (;;) /* Optimization: if there are no more active states, and there are no new states yet set up, then skip over the subject string right here, to save looping. Otherwise, set up the new state to swing - into action when the end of the substring is reached. */ + into action when the end of the matched substring is reached. */ else if (i + 1 >= active_count && new_count == 0) { @@ -2686,7 +2869,6 @@ for (;;) if (repeat_state_offset >= 0) { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } } - } else if (rc != PCRE_ERROR_NOMATCH) return rc; } @@ -2713,6 +2895,7 @@ for (;;) cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; + cb.mark = NULL; /* No (*MARK) support */ if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */ } if (rrc == 0) @@ -2963,15 +3146,21 @@ back the character offset. */ #ifdef SUPPORT_UTF8 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) { - int tb; - if ((tb = _pcre_valid_utf8((uschar *)subject, length)) >= 0) - return (tb == length && (options & PCRE_PARTIAL_HARD) != 0)? - PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; - if (start_offset > 0 && start_offset < length) + int erroroffset; + int errorcode = _pcre_valid_utf8((uschar *)subject, length, &erroroffset); + if (errorcode != 0) { - tb = ((USPTR)subject)[start_offset] & 0xc0; - if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET; + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } + return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; } + if (start_offset > 0 && start_offset < length && + (((USPTR)subject)[start_offset] & 0xc0) == 0x80) + return PCRE_ERROR_BADUTF8_OFFSET; } #endif @@ -3141,7 +3330,7 @@ for (;;) disabling is explicitly requested (and of course, by the test above, this code is not obeyed when restarting after a partial match). */ - if ((options & PCRE_NO_START_OPTIMIZE) == 0 && + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0) { /* If the pattern was studied, a minimum subject length may be set. This @@ -3209,6 +3398,7 @@ for (;;) /* OK, now we can do the business */ md->start_used_ptr = current_subject; + md->recursive = NULL; rc = internal_dfa_exec( md, /* fixed match data */ @@ -3219,9 +3409,7 @@ for (;;) offsetcount, /* size of same */ workspace, /* workspace vector */ wscount, /* size of same */ - re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */ - 0, /* function recurse level */ - 0); /* regex recurse level */ + 0); /* function recurse level */ /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ diff --git a/harbour/src/3rd/pcre/pcreexec.c b/harbour/src/3rd/pcre/pcreexec.c index e2cc68a296..43997d8422 100644 --- a/harbour/src/3rd/pcre/pcreexec.c +++ b/harbour/src/3rd/pcre/pcreexec.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-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -57,10 +57,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. */ @@ -73,18 +75,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, @@ -132,24 +128,27 @@ 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 if not matched, otherwise the number of subject bytes matched */ -static BOOL +static int match_ref(int offset, register USPTR eptr, int length, match_data *md, - unsigned long int ims) + BOOL caseless) { -USPTR p = md->start_subject + md->offset_vector[offset]; +USPTR eptr_start = eptr; +register USPTR p = md->start_subject + md->offset_vector[offset]; #ifdef PCRE_DEBUG if (eptr >= md->end_subject) @@ -164,27 +163,36 @@ 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). */ -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_UCP if (md->utf8) { - 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). */ + + USPTR endptr = p + length; + while (p < endptr) { int c, d; + if (eptr >= md->end_subject) return -1; GETCHARINC(c, eptr); GETCHARINC(d, p); - if (c != d && c != UCD_OTHERCASE(d)) return FALSE; + if (c != d && c != UCD_OTHERCASE(d)) return -1; } } else @@ -193,18 +201,23 @@ 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; } + { + if (eptr + length > md->end_subject) return -1; + while (length-- > 0) + { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; } + } } /* 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; } + { + if (eptr + length > md->end_subject) return -1; + while (length-- > 0) if (*p++ != *eptr++) return -1; + } -return TRUE; +return (int)(eptr - eptr_start); } @@ -256,7 +269,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 @@ -266,10 +279,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) \ @@ -278,8 +291,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 @@ -292,7 +305,7 @@ 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);\ @@ -300,11 +313,8 @@ argument of match(), which never changes. */ 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;\ @@ -338,11 +348,8 @@ typedef struct heapframe { USPTR Xeptr; const uschar *Xecode; USPTR Xmstart; - USPTR Xmarkptr; int Xoffset_top; - long int Xims; eptrblock *Xeptrb; - int Xflags; unsigned int Xrdepth; /* Function local variables */ @@ -363,15 +370,10 @@ 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]; #endif @@ -415,7 +417,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 @@ -426,14 +428,14 @@ 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); \ } @@ -447,16 +449,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 @@ -468,8 +464,7 @@ 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) + 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 @@ -481,6 +476,7 @@ register unsigned int c; /* Character values not kept over RMATCH() calls */ register BOOL utf8; /* Local copy of UTF-8 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 @@ -498,11 +494,8 @@ frame->Xprevframe = NULL; /* Marks the top level */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xmstart = mstart; -frame->Xmarkptr = markptr; frame->Xoffset_top = offset_top; -frame->Xims = ims; frame->Xeptrb = eptrb; -frame->Xflags = flags; frame->Xrdepth = rdepth; /* This is where control jumps back to to effect "recursion" */ @@ -514,11 +507,8 @@ 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 */ @@ -540,15 +530,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 @@ -578,32 +563,34 @@ 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_UTF8 +const uschar *charptr; +#endif +const uschar *callpat; +const uschar *data; +const uschar *next; +USPTR pp; +const uschar *prev; +USPTR 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]; #endif @@ -623,6 +610,17 @@ int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; #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 + /* These statements are here to stop the compiler complaining about unitialized variables. */ @@ -659,22 +657,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. */ @@ -687,9 +687,12 @@ for (;;) switch(op) { case OP_MARK: - markptr = ecode + 2; + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM55); + eptrb, RM55); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an argument, and we must check whether that argument matches this MARK's @@ -698,98 +701,191 @@ 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((char *)(ecode + 2), (char *)(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); + 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); + eptrb, RM51); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); - MRRETURN(MATCH_PRUNE); + RRETURN(MATCH_PRUNE); case OP_PRUNE_ARG: + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM56); + 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); + 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: + if (md->ignore_skip_arg) + { + ecode += _pcre_OP_lengths[*ecode] + ecode[1]; + break; + } RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM57); + 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); + 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 + _pcre_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; + 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); + } + 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 */ + { + md->match_function_type = MATCH_CBEGROUP; + 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 @@ -818,26 +914,227 @@ for (;;) md->offset_vector[md->offset_end - number] = (int)(eptr - md->start_subject); - flags = (op == OP_SCBRA)? match_cbegroup : 0; - do + for (;;) { + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; 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); + 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); + 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 += _pcre_OP_lengths[*ecode]; + goto TAIL_RECURSE; + } + + /* In all other cases, we have to make another call to match(). */ + + RMATCH(eptr, ecode + _pcre_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 uschar *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); + 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 + _pcre_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); } @@ -852,56 +1149,66 @@ 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 + _pcre_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. */ @@ -911,7 +1218,7 @@ for (;;) if (pcre_callout != NULL) { pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[LINK_SIZE+2]; cb.offset_vector = md->offset_vector; cb.subject = (PCRE_SPTR)md->start_subject; @@ -923,7 +1230,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 = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += _pcre_OP_lengths[OP_CALLOUT]; @@ -943,14 +1251,14 @@ 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; for (i = 0; i < md->name_count; i++) @@ -1076,21 +1384,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 */ } @@ -1101,26 +1414,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; } @@ -1151,35 +1470,23 @@ for (;;) 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. */ @@ -1188,47 +1495,53 @@ 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: + 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); + + /* PCRE does not allow THEN to escape beyond an assertion; it is treated + as NOMATCH. */ + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); - if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH); + + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ - if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + if (condassert) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ @@ -1244,24 +1557,32 @@ for (;;) case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: + 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); + 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; @@ -1279,7 +1600,7 @@ for (;;) while (i-- > 0) { eptr--; - if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr); } } @@ -1290,7 +1611,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 */ @@ -1307,7 +1628,7 @@ for (;;) if (pcre_callout != NULL) { pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; cb.subject = (PCRE_SPTR)md->start_subject; @@ -1319,7 +1640,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 = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; @@ -1329,38 +1651,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) @@ -1371,30 +1703,42 @@ for (;;) (int *)(pcre_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 { + if (cbegroup) md->match_function_type = MATCH_CBEGROUP; RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top, - md, ims, eptrb, flags, RM6); + 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); + + /* 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 to escape beyond a recursion; it is treated + as NOMATCH. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { DPRINTF(("Recursion gave error %d\n", rrc)); if (new_recursive.offset_save != stacksave) @@ -1403,8 +1747,6 @@ for (;;) } 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); @@ -1413,90 +1755,11 @@ for (;;) 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; + 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. */ @@ -1512,73 +1775,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; @@ -1588,64 +1857,100 @@ 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 */ + { + md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, prev, offset_top, md, eptrb, RM50); RRETURN(rrc); } ecode = prev; @@ -1653,39 +1958,48 @@ for (;;) } else /* OP_KETRMAX */ { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); + if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, prev, offset_top, md, eptrb, RM13); + if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; + RRETURN(MATCH_ONCE); + } ecode += 1 + LINK_SIZE; - flags = 0; goto TAIL_RECURSE; } /* Control never gets here */ - /* Start of subject unless notbol, or after internal newline if multiline */ + /* Not multiline mode: start of subject assertion, unless notbol. */ case OP_CIRC: - if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH); - if ((ims & PCRE_MULTILINE) != 0) - { - if (eptr != md->start_subject && - (eptr == md->end_subject || !WAS_NEWLINE(eptr))) - MRRETURN(MATCH_NOMATCH); - ecode++; - break; - } - /* ... else fall through */ + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); /* Start of subject assertion */ case OP_SOD: - if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Multiline mode: start of subject unless notbol, or after any newline. */ + + case OP_CIRCM: + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject && + (eptr == md->end_subject || !WAS_NEWLINE(eptr))) + RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: - if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1696,34 +2010,33 @@ 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)) 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; @@ -1734,7 +2047,7 @@ for (;;) ASSERT_NL_OR_EOS: if (eptr < md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); /* Either at end of string or \n before end. */ @@ -1856,22 +2169,23 @@ for (;;) 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 */ case OP_ANY: - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); /* Fall through */ 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); } + eptr++; if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; ecode++; break; @@ -1880,11 +2194,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; @@ -1892,7 +2207,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1901,7 +2216,7 @@ for (;;) #endif (md->ctypes[c] & ctype_digit) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1909,7 +2224,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1918,7 +2233,7 @@ for (;;) #endif (md->ctypes[c] & ctype_digit) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1926,7 +2241,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1935,7 +2250,7 @@ for (;;) #endif (md->ctypes[c] & ctype_space) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1943,7 +2258,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1952,7 +2267,7 @@ for (;;) #endif (md->ctypes[c] & ctype_space) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1960,7 +2275,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1969,7 +2284,7 @@ for (;;) #endif (md->ctypes[c] & ctype_word) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1977,7 +2292,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( @@ -1986,7 +2301,7 @@ for (;;) #endif (md->ctypes[c] & ctype_word) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1994,12 +2309,13 @@ 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++; break; @@ -2012,7 +2328,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } ecode++; @@ -2022,7 +2338,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2047,7 +2363,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; @@ -2056,12 +2372,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 */ @@ -2090,7 +2406,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2103,7 +2419,7 @@ for (;;) case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2112,12 +2428,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 */ @@ -2139,7 +2455,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); { @@ -2148,29 +2464,29 @@ 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); + 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 */ @@ -2178,14 +2494,14 @@ for (;;) case PT_ALNUM: if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_SPACE: /* Perl space */ if ((_pcre_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 */ @@ -2193,14 +2509,14 @@ for (;;) 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 || c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; /* This should never occur */ @@ -2220,23 +2536,16 @@ 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 (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } ecode++; break; @@ -2252,129 +2561,131 @@ for (;;) loops). */ case OP_REF: + case OP_REFI: + caseless = op == OP_REFI; + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 3; + + /* 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, 3); + if (max == 0) max = INT_MAX; + ecode += 5; + 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; + 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. */ - default: /* No repeat follows */ - if (!match_ref(offset, eptr, length, md, ims)) + 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++) + { + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) + { + 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) { 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); + break; } - eptr += length; + 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) + while (eptr >= pp) { - 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)) - { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); - } - eptr += length; - } - /* Control never gets here */ - } - - /* If maximizing, find the longest string and work backwards */ - - else - { - 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 */ @@ -2435,16 +2746,16 @@ for (;;) 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 ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } @@ -2457,10 +2768,10 @@ for (;;) 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); + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } @@ -2480,22 +2791,22 @@ for (;;) { 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 ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } @@ -2505,16 +2816,16 @@ for (;;) { 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); + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2551,7 +2862,7 @@ for (;;) } 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); @@ -2574,13 +2885,13 @@ for (;;) } 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); } } /* Control never gets here */ @@ -2632,10 +2943,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 (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the @@ -2650,16 +2961,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 (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -2683,12 +2994,12 @@ for (;;) } 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); } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -2707,9 +3018,9 @@ 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 @@ -2719,16 +3030,23 @@ for (;;) if (md->end_subject - eptr < 1) { SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH); + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; - /* Match a single character, caselessly */ + /* Match a single character, caselessly. If we are at the end of the + subject, give up immediately. */ + + case OP_CHARI: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } - case OP_CHARNC: #ifdef SUPPORT_UTF8 if (utf8) { @@ -2736,21 +3054,19 @@ for (;;) 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[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } - /* Otherwise we must pick up the subject character */ + /* Otherwise we must pick up the subject character. Note that we cannot + use the value of "length" to check for sufficient bytes left, because the + other case of the character may have more or fewer bytes. */ else { @@ -2766,7 +3082,7 @@ for (;;) #ifdef SUPPORT_UCP if (dc != UCD_OTHERCASE(fc)) #endif - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } } @@ -2775,12 +3091,7 @@ for (;;) /* Non-UTF-8 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 (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); ecode += 2; } break; @@ -2788,23 +3099,28 @@ for (;;) /* Match a single character repeatedly. */ case OP_EXACT: + case OP_EXACTI: min = max = GET2(ecode, 1); ecode += 3; 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; + minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; ecode += 3; goto REPEATCHAR; case OP_POSSTAR: + case OP_POSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -2812,6 +3128,7 @@ for (;;) goto REPEATCHAR; case OP_POSPLUS: + case OP_POSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -2819,6 +3136,7 @@ for (;;) goto REPEATCHAR; case OP_POSQUERY: + case OP_POSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -2826,14 +3144,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; @@ -2856,7 +3179,7 @@ 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); else oclength = 0; @@ -2874,7 +3197,7 @@ for (;;) else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } @@ -2884,9 +3207,9 @@ 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; #ifdef SUPPORT_UCP @@ -2897,7 +3220,7 @@ for (;;) else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2926,9 +3249,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); @@ -2963,7 +3286,7 @@ for (;;) DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_STARI) /* Caseless */ { fc = md->lcc[fc]; for (i = 1; i <= min; i++) @@ -2971,24 +3294,24 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } 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 != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3010,11 +3333,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 */ } @@ -3028,9 +3351,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; @@ -3039,15 +3362,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 */ } @@ -3068,11 +3391,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 */ @@ -3081,24 +3404,25 @@ 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) + if (op == OP_NOTI) /* The caseless case */ { #ifdef SUPPORT_UTF8 if (c < 256) #endif c = md->lcc[c]; - if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH); + if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); } - else + else /* Caseful */ { - if (*ecode++ == c) MRRETURN(MATCH_NOMATCH); + if (*ecode++ == c) RRETURN(MATCH_NOMATCH); } break; @@ -3110,19 +3434,23 @@ for (;;) about... */ case OP_NOTEXACT: + case OP_NOTEXACTI: min = max = GET2(ecode, 1); ecode += 3; goto REPEATNOTCHAR; case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: min = 0; max = GET2(ecode, 1); - minimize = *ecode == OP_NOTMINUPTO; + minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; ecode += 3; goto REPEATNOTCHAR; case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -3130,6 +3458,7 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -3137,6 +3466,7 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -3144,6 +3474,7 @@ for (;;) goto REPEATNOTCHAR; case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: possessive = TRUE; min = 0; max = GET2(ecode, 1); @@ -3151,12 +3482,18 @@ for (;;) 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 */ @@ -3178,7 +3515,7 @@ for (;;) DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_NOTSTARI) /* Caseless */ { fc = md->lcc[fc]; @@ -3192,11 +3529,11 @@ 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) RRETURN(MATCH_NOMATCH); } } else @@ -3209,9 +3546,9 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } } @@ -3226,17 +3563,17 @@ for (;;) 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) RRETURN(MATCH_NOMATCH); } } else @@ -3245,15 +3582,15 @@ for (;;) { 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 == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3286,7 +3623,7 @@ 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); @@ -3309,13 +3646,13 @@ for (;;) 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 */ } @@ -3334,10 +3671,10 @@ 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 @@ -3349,9 +3686,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); } } @@ -3366,16 +3703,16 @@ for (;;) 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 @@ -3384,15 +3721,15 @@ for (;;) { 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 */ @@ -3424,7 +3761,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); @@ -3447,13 +3784,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 */ @@ -3547,13 +3884,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); } @@ -3562,17 +3899,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; @@ -3582,12 +3920,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; @@ -3597,12 +3934,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; @@ -3612,28 +3948,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; @@ -3643,14 +3978,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; @@ -3660,31 +3994,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; @@ -3705,18 +4038,15 @@ 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 (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } } @@ -3736,9 +4066,9 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } @@ -3750,7 +4080,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; @@ -3758,7 +4088,7 @@ for (;;) break; case OP_ANYBYTE: - if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH); + if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH); eptr += min; break; @@ -3768,12 +4098,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; @@ -3786,7 +4117,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -3798,7 +4129,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3823,7 +4154,7 @@ for (;;) case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3834,12 +4165,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 */ @@ -3870,7 +4201,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3883,7 +4214,7 @@ for (;;) case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3894,12 +4225,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 */ @@ -3918,11 +4249,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; @@ -3932,10 +4263,10 @@ 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); + RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3946,10 +4277,10 @@ 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); + RRETURN(MATCH_NOMATCH); while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); } break; @@ -3960,10 +4291,10 @@ 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); + RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3974,10 +4305,10 @@ 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); + RRETURN(MATCH_NOMATCH); while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); } break; @@ -3988,10 +4319,10 @@ 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); + RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -4014,9 +4345,9 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); eptr++; } break; @@ -4025,7 +4356,7 @@ for (;;) if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4034,7 +4365,7 @@ for (;;) if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4045,21 +4376,23 @@ 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); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -4071,7 +4404,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4079,7 +4412,7 @@ for (;;) case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -4090,11 +4423,11 @@ 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 */ @@ -4109,7 +4442,7 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4119,7 +4452,7 @@ for (;;) case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -4130,11 +4463,11 @@ 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 */ @@ -4151,9 +4484,9 @@ 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 ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); } break; @@ -4163,9 +4496,9 @@ 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 ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); } break; @@ -4175,9 +4508,9 @@ 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 ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); } break; @@ -4187,9 +4520,9 @@ 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 ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); } break; @@ -4199,10 +4532,10 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if ((md->ctypes[*eptr++] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -4212,10 +4545,10 @@ for (;;) if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if ((md->ctypes[*eptr++] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -4242,170 +4575,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 */ @@ -4423,29 +4753,25 @@ 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 (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } } } - else #endif /* SUPPORT_UCP */ @@ -4455,16 +4781,16 @@ for (;;) { 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) { @@ -4476,7 +4802,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; @@ -4488,7 +4814,7 @@ for (;;) case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4516,14 +4842,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 */ @@ -4558,14 +4884,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 */ @@ -4579,32 +4905,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); + 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: @@ -4618,16 +4944,16 @@ for (;;) { 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) { @@ -4639,7 +4965,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; @@ -4650,7 +4976,7 @@ for (;;) case 0x000b: case 0x000c: case 0x0085: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4662,14 +4988,14 @@ for (;;) case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - 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 */ @@ -4686,14 +5012,14 @@ for (;;) case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - 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 */ @@ -4704,27 +5030,27 @@ for (;;) break; case OP_NOT_DIGIT: - if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH); + if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: - if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH); + if ((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 ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: - if ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH); + if ((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 ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: - if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH); + if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: @@ -4766,6 +5092,7 @@ for (;;) case PT_LAMP: for (i = min; i < max; i++) { + int chartype; int len = 1; if (eptr >= md->end_subject) { @@ -4773,10 +5100,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; } @@ -4792,9 +5119,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; @@ -4809,9 +5134,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; @@ -4826,9 +5149,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; @@ -4836,6 +5157,7 @@ for (;;) case PT_ALNUM: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4843,9 +5165,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; } @@ -4861,8 +5182,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; @@ -4880,8 +5200,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; @@ -4892,6 +5211,7 @@ for (;;) case PT_WORD: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4899,8 +5219,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; @@ -4916,7 +5236,7 @@ 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); @@ -4930,23 +5250,20 @@ 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 (!utf8) 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 (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } } @@ -4957,19 +5274,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 { 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--; } } @@ -5033,7 +5348,11 @@ for (;;) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } - else eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + else + { + eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + SCHECK_PARTIAL(); + } break; /* The byte case is the same as non-UTF8 */ @@ -5241,15 +5560,21 @@ 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 @@ -5448,20 +5773,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 */ @@ -5494,7 +5825,8 @@ 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) + LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) + LBL(65) LBL(66) #ifdef SUPPORT_UTF8 LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30) LBL(32) LBL(34) LBL(42) LBL(46) @@ -5523,7 +5855,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 @@ -5541,8 +5872,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 @@ -5599,12 +5928,11 @@ 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) { -int rc, resetcount, ocount; +int rc, ocount, arg_offset_max; int first_byte = -1; int req_byte = -1; int req_byte2 = -1; int newline; -unsigned long int ims; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; @@ -5636,8 +5964,61 @@ if (re == NULL || subject == 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. */ +/* 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. */ + +utf8 = md->utf8 = (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_UTF8 +if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) + { + int erroroffset; + int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset); + if (errorcode != 0) + { + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } + return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; + } + + /* Check that a start_offset points to the start of a UTF-8 character. */ + if (start_offset > 0 && start_offset < length && + (((USPTR)subject)[start_offset] & 0xc0) == 0x80) + 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. In particular, JIT does not support partial +matching. */ + +#ifdef SUPPORT_JIT +if (extra_data != NULL + && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 + && extra_data->executable_jit != NULL + && (extra_data->flags & PCRE_EXTRA_TABLES) == 0 + && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | + PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0) + return _pcre_jit_exec(re, extra_data->executable_jit, subject, length, + start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) + ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); +#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 = (uschar *)re + re->name_table_offset; md->name_count = re->name_count; @@ -5704,20 +6085,23 @@ 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->ctypes = tables + ctypes_offset; @@ -5795,36 +6179,13 @@ 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) { @@ -5841,22 +6202,19 @@ 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 @@ -5890,6 +6248,8 @@ if ((re->flags & PCRE_REQCHSET) != 0) } + + /* ==========================================================================*/ /* Loop for handling unanchored repeated matching attempts; for anchored regexs @@ -5900,15 +6260,6 @@ 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; - } - /* 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 newline. Implement this by temporarily adjusting end_subject so that we stop @@ -6014,7 +6365,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 @@ -6097,12 +6448,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. */ @@ -6114,18 +6478,13 @@ 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) @@ -6208,21 +6567,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); } - /* 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 = ocount; + iptr = offsets + md->end_offset_top; + iend = offsets + resetcount; + while (iptr < iend) *iptr++ = -1; + } /* If there is space, set up the whole thing as substring 0. The value of md->start_match_ptr might be modified if \K was encountered on the success @@ -6234,8 +6613,12 @@ 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) = (unsigned char *)(md->mark); DPRINTF((">>>> returning %d\n", rc)); - goto RETURN_MARK; + return rc; } /* Control gets here if there has been an error, or if the overall match @@ -6279,10 +6662,8 @@ 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) = (unsigned char *)(md->nomatch_mark); return rc; } diff --git a/harbour/src/3rd/pcre/pcrefinf.c b/harbour/src/3rd/pcre/pcrefinf.c index c2a17ad210..5e994635b6 100644 --- a/harbour/src/3rd/pcre/pcrefinf.c +++ b/harbour/src/3rd/pcre/pcrefinf.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-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -100,6 +100,19 @@ 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)? + _pcre_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; @@ -129,6 +142,12 @@ switch (what) (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; diff --git a/harbour/src/3rd/pcre/pcreinal.h b/harbour/src/3rd/pcre/pcreinal.h index 5f736d13ac..6ea397a39e 100644 --- a/harbour/src/3rd/pcre/pcreinal.h +++ b/harbour/src/3rd/pcre/pcreinal.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-2011 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -582,10 +582,6 @@ 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 @@ -598,11 +594,12 @@ compatibility. */ #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 */ +#define PCRE_HASTHEN 0x0040 /* pattern contains (*THEN) */ -/* Options for the "extra" block produced by pcre_study(). */ +/* Flags for the "extra" block produced by pcre_study(). */ -#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ -#define PCRE_STUDY_MINLEN 0x02 /* a minimum length field exists */ +#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */ +#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */ /* Masks for identifying the public options that are permitted at compile time, run time, or study time, respectively. */ @@ -628,7 +625,8 @@ 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 /* 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. */ @@ -1254,8 +1252,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-utf8 mode. In +non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. when PCRE_UCP is set, when replacement of \d etc by \p sequences is required. @@ -1299,6 +1297,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 */ @@ -1313,141 +1312,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 + UTF-8 character > 255 is encountered. */ + OP_XCLASS, /* 108 Extended class for handling UTF-8 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 @@ -1462,29 +1525,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" @@ -1505,18 +1584,25 @@ 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, /* noti */ \ + /* Positive single-char repeats ** These are */ \ + 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ + 4, 4, 4, /* upto, minupto, exact ** mode */ \ 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \ + 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ + 4, 4, 4, /* upto I, minupto I, exact I */ \ + 2, 2, 2, 4, /* *+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, 2, 2, 4, /* Possessive NOT *, +, ?, upto */ \ + 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ + 4, 4, 4, /* NOT upto I, minupto I, exact I */ \ + 2, 2, 2, 4, /* Possessive NOT *I, +I, ?I, upto I */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ 4, 4, 4, /* Type upto, minupto, exact */ \ @@ -1528,33 +1614,40 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 33, /* NCLASS */ \ 0, /* XCLASS - variable length */ \ 3, /* REF */ \ + 3, /* 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 */ \ + 1+LINK_SIZE, /* BRAPOS */ \ 3+LINK_SIZE, /* CBRA */ \ + 3+LINK_SIZE, /* CBRAPOS */ \ 1+LINK_SIZE, /* COND */ \ 1+LINK_SIZE, /* SBRA */ \ + 1+LINK_SIZE, /* SBRAPOS */ \ 3+LINK_SIZE, /* SCBRA */ \ + 3+LINK_SIZE, /* SCBRAPOS */ \ 1+LINK_SIZE, /* SCOND */ \ 3, 3, /* CREF, NCREF */ \ 3, 3, /* 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 */ \ + 3, 1 /* CLOSE, SKIPZERO */ /* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion" condition. */ @@ -1571,8 +1664,8 @@ 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, ERRCOUNT }; /* 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 @@ -1648,10 +1741,12 @@ typedef struct compile_data { uschar *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 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 */ @@ -1663,7 +1758,7 @@ typedef struct compile_data { } 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; @@ -1671,20 +1766,28 @@ typedef struct branch_chain { } 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 */ + USPTR 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; + USPTR 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; @@ -1708,8 +1811,8 @@ typedef struct match_data { 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 */ + 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 */ @@ -1721,7 +1824,9 @@ typedef struct match_data { 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 */ + BOOL hasthen; /* Pattern contains (*THEN) */ + BOOL ignore_skip_arg; /* For re-run when SKIP name not found */ + 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 */ @@ -1731,29 +1836,33 @@ typedef struct match_data { 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 uschar *mark; /* Mark pointer to pass back */ + const uschar *mark; /* Mark pointer to pass back on success */ + const uschar *nomatch_mark; /* Mark pointer to pass back on failure */ + const uschar *once_target; /* Where to back up to for atomic groups */ } 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 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 */ + dfa_recursion_info *recursive; /* Linked list of recursion data */ } dfa_match_data; /* Bit definitions for entries in the pcre_ctypes table. */ @@ -1811,6 +1920,10 @@ extern const int _pcre_utf8_table2[]; extern const int _pcre_utf8_table3[]; extern const uschar _pcre_utf8_table4[]; +#ifdef SUPPORT_JIT +extern const uschar _pcre_utf8_char_sizes[]; +#endif + extern const int _pcre_utf8_table1_size; extern const char _pcre_utt_names[]; @@ -1831,10 +1944,17 @@ 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 int _pcre_valid_utf8(USPTR, int, int *); extern BOOL _pcre_was_newline(USPTR, int, USPTR, int *, BOOL); extern BOOL _pcre_xclass(int, const uschar *); +#ifdef SUPPORT_JIT +extern void _pcre_jit_compile(const real_pcre *, pcre_extra *); +extern int _pcre_jit_exec(const real_pcre *, void *, PCRE_SPTR, + int, int, int, int, int *, int); +extern void _pcre_jit_free(void *); +extern int _pcre_jit_get_size(void *); +#endif /* Unicode character database (UCD) */ @@ -1848,14 +1968,16 @@ 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[]; - +#ifdef SUPPORT_JIT +extern const int _pcre_ucp_typerange[]; +#endif /* 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]) + UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE]) #define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype #define UCD_SCRIPT(ch) GET_UCD(ch)->script diff --git a/harbour/src/3rd/pcre/pcrejitc.c b/harbour/src/3rd/pcre/pcrejitc.c new file mode 100644 index 0000000000..a08ae246d9 --- /dev/null +++ b/harbour/src/3rd/pcre/pcrejitc.c @@ -0,0 +1,6605 @@ +/************************************************* +* 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-2008 University of Cambridge + + The machine code generator part (this module) was written by Zoltan Herczeg + Copyright (c) 2010-2011 + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcreinal.h" + +#ifdef SUPPORT_JIT + +/* All-in-one: Since we use the JIT compiler only from here, +we just include it. This way we don't need to touch the build +system files. */ + +#define SLJIT_MALLOC(size) (pcre_malloc)(size) +#define SLJIT_FREE(ptr) (pcre_free)(ptr) +#define SLJIT_CONFIG_AUTO 1 +#define SLJIT_CONFIG_STATIC 1 +#define SLJIT_VERBOSE 0 +#define SLJIT_DEBUG 0 + +#include "sljit/sljitLir.c" + +#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED +#error "Unsupported architecture" +#endif + +/* Allocate memory on the stack. Fast, but limited size. */ +#define LOCAL_SPACE_SIZE 32768 + +#define STACK_GROWTH_RATE 8192 + +/* Enable to check that the allocation could destroy temporaries. */ +#if defined SLJIT_DEBUG && SLJIT_DEBUG +#define DESTROY_REGISTERS 1 +#endif + +/* +Short summary about the backtracking mechanism empolyed by the jit code generator: + +The code generator follows the recursive nature of the PERL compatible regular +expressions. The basic blocks of regular expressions are condition checkers +whose execute different commands depending on the result of the condition check. +The relationship between the operators can be horizontal (concatenation) and +vertical (sub-expression) (See struct fallback_common for more details). + + 'ab' - 'a' and 'b' regexps are concatenated + 'a+' - 'a' is the sub-expression of the '+' operator + +The condition checkers are boolean (true/false) checkers. Machine code is generated +for the checker itself and for the actions depending on the result of the checker. +The 'true' case is called as the hot path (expected path), and the other is called as +the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken +branches on the hot path. + + Greedy star operator (*) : + Hot path: match happens. + Fallback path: match failed. + Non-greedy star operator (*?) : + Hot path: no need to perform a match. + Fallback path: match is required. + +The following example shows how the code generated for a capturing bracket +with two alternatives. Let A, B, C, D are arbirary regular expressions, and +we have the following regular expression: + + A(B|C)D + +The generated code will be the following: + + A hot path + '(' hot path (pushing arguments to the stack) + B hot path + ')' hot path (pushing arguments to the stack) + D hot path + return with successful match + + D fallback path + ')' fallback path (If we arrived from "C" jump to the fallback of "C") + B fallback path + C expected path + jump to D hot path + C fallback path + A fallback path + + Notice, that the order of fallback code paths are the opposite of the fast + code paths. In this way the topmost value on the stack is always belong + to the current fallback code path. The fallback code path must check + whether there is a next alternative. If so, it needs to jump back to + the hot path eventually. Otherwise it needs to clear out its own stack + frame and continue the execution on the fallback code paths. +*/ + +/* +Saved stack frames: + +Atomic blocks and asserts require reloading the values of local variables +when the fallback mechanism performed. Because of OP_RECURSE, the locals +are not necessarly known in compile time, thus we need a dynamic restore +mechanism. + +The stack frames are stored in a chain list, and have the following format: +([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] + +Thus we can restore the locals to a particular point in the stack. +*/ + +typedef struct jit_arguments { + /* Pointers first. */ + struct sljit_stack *stack; + PCRE_SPTR str; + PCRE_SPTR begin; + PCRE_SPTR end; + int *offsets; + uschar *ptr; + /* Everything else after. */ + int offsetcount; + int calllimit; + uschar notbol; + uschar noteol; + uschar notempty; + uschar notempty_atstart; +} jit_arguments; + +typedef struct executable_function { + void *executable_func; + pcre_jit_callback callback; + void *userdata; + sljit_uw executable_size; +} executable_function; + +typedef struct jump_list { + struct sljit_jump *jump; + struct jump_list *next; +} jump_list; + +enum stub_types { stack_alloc }; + +typedef struct stub_list { + enum stub_types type; + int data; + struct sljit_jump *start; + struct sljit_label *leave; + struct stub_list *next; +} stub_list; + +typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); + +/* The following structure is the key data type for the recursive +code generator. It is allocated by compile_hotpath, and contains +the aguments for compile_fallbackpath. Must be the first member +of its descendants. */ +typedef struct fallback_common { + /* Concatenation stack. */ + struct fallback_common *prev; + jump_list *nextfallbacks; + /* Internal stack (for component operators). */ + struct fallback_common *top; + jump_list *topfallbacks; + /* Opcode pointer. */ + uschar *cc; +} fallback_common; + +typedef struct assert_fallback { + fallback_common common; + jump_list *condfailed; + /* Less than 0 (-1) if a frame is not needed. */ + int framesize; + /* Points to our private memory word on the stack. */ + int localptr; + /* For iterators. */ + struct sljit_label *hotpath; +} assert_fallback; + +typedef struct bracket_fallback { + fallback_common common; + /* Where to coninue if an alternative is successfully matched. */ + struct sljit_label *althotpath; + /* For rmin and rmax iterators. */ + struct sljit_label *recursivehotpath; + /* For greedy ? operator. */ + struct sljit_label *zerohotpath; + /* Contains the branches of a failed condition. */ + union { + /* Both for OP_COND, OP_SCOND. */ + jump_list *condfailed; + assert_fallback *assert; + /* For OP_ONCE. -1 if not needed. */ + int framesize; + } u; + /* Points to our private memory word on the stack. */ + int localptr; +} bracket_fallback; + +typedef struct bracketpos_fallback { + fallback_common common; + /* Points to our private memory word on the stack. */ + int localptr; + /* Reverting stack is needed. */ + int framesize; + /* Allocated stack size. */ + int stacksize; +} bracketpos_fallback; + +typedef struct braminzero_fallback { + fallback_common common; + struct sljit_label *hotpath; +} braminzero_fallback; + +typedef struct iterator_fallback { + fallback_common common; + /* Next iteration. */ + struct sljit_label *hotpath; +} iterator_fallback; + +typedef struct recurse_entry { + struct recurse_entry *next; + /* Contains the function entry. */ + struct sljit_label *entry; + /* Collects the calls until the function is not created. */ + jump_list *calls; + /* Points to the starting opcode. */ + int start; +} recurse_entry; + +typedef struct recurse_fallback { + fallback_common common; +} recurse_fallback; + +typedef struct compiler_common { + struct sljit_compiler *compiler; + uschar *start; + int localsize; + int *localptrs; + const uschar *fcc; + sljit_w lcc; + int cbraptr; + int nltype; + int newline; + int bsr_nltype; + int endonly; + sljit_w ctypes; + sljit_uw name_table; + sljit_w name_count; + sljit_w name_entry_size; + struct sljit_label *acceptlabel; + stub_list *stubs; + recurse_entry *entries; + recurse_entry *currententry; + jump_list *accept; + jump_list *calllimit; + jump_list *stackalloc; + jump_list *revertframes; + jump_list *wordboundary; + jump_list *anynewline; + jump_list *hspace; + jump_list *vspace; + jump_list *casefulcmp; + jump_list *caselesscmp; + BOOL jscript_compat; +#ifdef SUPPORT_UTF8 + BOOL utf8; +#ifdef SUPPORT_UCP + BOOL useucp; +#endif + jump_list *utf8readchar; + jump_list *utf8readtype8; +#endif +#ifdef SUPPORT_UCP + jump_list *getucd; +#endif +} compiler_common; + +/* For byte_sequence_compare. */ + +typedef struct compare_context { + int length; + int sourcereg; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + int byteptr; + union { + int asint; + short asshort; + sljit_ub asbyte; + sljit_ub asbytes[4]; + } c; + union { + int asint; + short asshort; + sljit_ub asbyte; + sljit_ub asbytes[4]; + } oc; +#endif +} compare_context; + +enum { + frame_end = 0, + frame_setstrbegin = -1 +}; + +/* Used for accessing the elements of the stack. */ +#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) + +#define TMP1 SLJIT_TEMPORARY_REG1 +#define TMP2 SLJIT_TEMPORARY_REG3 +#define TMP3 SLJIT_TEMPORARY_EREG2 +#define STR_PTR SLJIT_GENERAL_REG1 +#define STR_END SLJIT_GENERAL_REG2 +#define STACK_TOP SLJIT_TEMPORARY_REG2 +#define STACK_LIMIT SLJIT_GENERAL_REG3 +#define ARGUMENTS SLJIT_GENERAL_EREG1 +#define CALL_COUNT SLJIT_GENERAL_EREG2 +#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 + +/* Locals layout. */ +/* These two locals can be used by the current opcode. */ +#define LOCALS0 (0 * sizeof(sljit_w)) +#define LOCALS1 (1 * sizeof(sljit_w)) +/* Two local variables for possessive quantifiers (char1 cannot use them). */ +#define POSSESSIVE0 (2 * sizeof(sljit_w)) +#define POSSESSIVE1 (3 * sizeof(sljit_w)) +/* Head of the last recursion. */ +#define RECURSIVE_HEAD (4 * sizeof(sljit_w)) +/* Max limit of recursions. */ +#define CALL_LIMIT (5 * sizeof(sljit_w)) +/* Last known position of the requested byte. */ +#define REQ_BYTE_PTR (6 * sizeof(sljit_w)) +/* End pointer of the first line. */ +#define FIRSTLINE_END (7 * sizeof(sljit_w)) +/* The output vector is stored on the stack, and contains pointers +to characters. The vector data is divided into two groups: the first +group contains the start / end character pointers, and the second is +the start pointers when the end of the capturing group has not yet reached. */ +#define OVECTOR_START (8 * sizeof(sljit_w)) +#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) +#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) +#define PRIV(cc) (common->localptrs[(cc) - common->start]) + +/* Shortcuts. */ +#define DEFINE_COMPILER \ + struct sljit_compiler *compiler = common->compiler +#define OP1(op, dst, dstw, src, srcw) \ + sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) +#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ + sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) +#define LABEL() \ + sljit_emit_label(compiler) +#define JUMP(type) \ + sljit_emit_jump(compiler, (type)) +#define JUMPTO(type, label) \ + sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) +#define JUMPHERE(jump) \ + sljit_set_label((jump), sljit_emit_label(compiler)) +#define CMP(type, src1, src1w, src2, src2w) \ + sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) +#define CMPTO(type, src1, src1w, src2, src2w, label) \ + sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) +#define COND_VALUE(op, dst, dstw, type) \ + sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) + +static uschar* bracketend(uschar* cc) +{ +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +do cc += GET(cc, 1); while (*cc == OP_ALT); +SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); +cc += 1 + LINK_SIZE; +return cc; +} + +/* Functions whose might need modification for all new supported opcodes: + next_opcode + get_localspace + set_localptrs + get_framesize + init_frame + get_localsize + copy_locals + compile_hotpath + compile_fallbackpath +*/ + +static uschar *next_opcode(compiler_common *common, uschar *cc) +{ +SLJIT_UNUSED_ARG(common); +switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_DEF: + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_SKIPZERO: + return cc + 1; + + case OP_ANYBYTE: +#ifdef SUPPORT_UTF8 + if (common->utf8) return NULL; +#endif + return cc + 1; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + cc += 2; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#endif + return cc; + + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSUPTO: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSUPTOI: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSUPTO: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSUPTOI: + cc += 4; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#endif + return cc; + + case OP_NOTPROP: + case OP_PROP: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + case OP_REF: + case OP_REFI: + case OP_CREF: + case OP_NCREF: + case OP_RREF: + case OP_NRREF: + case OP_CLOSE: + cc += 3; + return cc; + + case OP_CRRANGE: + case OP_CRMINRANGE: + return cc + 5; + + case OP_CLASS: + case OP_NCLASS: + return cc + 33; + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + return cc + GET(cc, 1); +#endif + + case OP_RECURSE: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_REVERSE: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_COND: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + return cc + 1 + LINK_SIZE; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + return cc + 1 + LINK_SIZE + 2; + + default: + return NULL; + } +} + +static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend) +{ +int localspace = 0; +uschar *alternative; +/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ +while (cc < ccend) + { + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE + 2; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + if (cc == NULL) + return -1; + break; + } + } +return localspace; +} + +static void set_localptrs(compiler_common *common, int localptr, uschar *ccend) +{ +uschar *cc = common->start; +uschar *alternative; +while (cc < ccend) + { + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE + 2; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + } + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +} + +/* Returns with -1 if no need for frame. */ +static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive) +{ +uschar *ccend = bracketend(cc); +int length = 0; +BOOL possessive = FALSE; +BOOL setsom_found = FALSE; + +if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) + { + length = 3; + possessive = TRUE; + } + +cc = next_opcode(common, cc); +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + case OP_RECURSE: + if (!setsom_found) + { + length += 2; + setsom_found = TRUE; + } + cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + length += 3; + cc += 1 + LINK_SIZE + 2; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +/* Possessive quantifiers can use a special case. */ +if (SLJIT_UNLIKELY(possessive) && length == 3) + return -1; + +if (length > 0) + return length + 1; +return -1; +} + +static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive) +{ +DEFINE_COMPILER; +uschar *ccend = bracketend(cc); +BOOL setsom_found = FALSE; +int offset; + +/* >= 1 + shortest item size (2) */ +SLJIT_ASSERT(stackpos >= stacktop + 2); + +stackpos = STACK(stackpos); +if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) + cc = next_opcode(common, cc); +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + case OP_RECURSE: + if (!setsom_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + setsom_found = TRUE; + } + cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + offset = (GET2(cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); + stackpos += (int)sizeof(sljit_w); + + cc += 1 + LINK_SIZE + 2; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); +SLJIT_ASSERT(stackpos == STACK(stacktop)); +} + +static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend) +{ +int localsize = 2; +uschar *alternative; +/* Calculate the sum of the local variables. */ +while (cc < ccend) + { + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + localsize++; + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + localsize++; + cc += 1 + LINK_SIZE + 2; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + localsize += 2; + cc += 1 + LINK_SIZE + 2; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + localsize++; + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +SLJIT_ASSERT(cc == ccend); +return localsize; +} + +static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend, + BOOL save, int stackptr, int stacktop) +{ +DEFINE_COMPILER; +int srcw[2]; +int count; +BOOL tmp1next = TRUE; +BOOL tmp1empty = TRUE; +BOOL tmp2empty = TRUE; +uschar *alternative; +enum { + start, + loop, + end +} status; + +status = save ? start : loop; +stackptr = STACK(stackptr - 2); +stacktop = STACK(stacktop - 1); + +if (!save) + { + stackptr += sizeof(sljit_w); + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + tmp1empty = FALSE; + } + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + tmp2empty = FALSE; + } + /* The tmp1next must be TRUE in either way. */ + } + +while (status != end) + { + count = 0; + switch(status) + { + case start: + SLJIT_ASSERT(save); + count = 1; + srcw[0] = RECURSIVE_HEAD; + status = loop; + break; + + case loop: + if (cc >= ccend) + { + status = end; + break; + } + + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + count = 1; + srcw[0] = PRIV(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + count = 1; + srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + cc += 1 + LINK_SIZE + 2; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + count = 2; + srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + srcw[0] = PRIV(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE + 2; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + count = 1; + srcw[0] = PRIV(cc); + SLJIT_ASSERT(srcw[0] != 0); + } + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + break; + + case end: + SLJIT_ASSERT_STOP(); + break; + } + + while (count > 0) + { + count--; + if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); + tmp1empty = FALSE; + tmp1next = FALSE; + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); + tmp2empty = FALSE; + tmp1next = TRUE; + } + } + else + { + if (tmp1next) + { + SLJIT_ASSERT(!tmp1empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0); + tmp1empty = stackptr >= stacktop; + if (!tmp1empty) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + } + tmp1next = FALSE; + } + else + { + SLJIT_ASSERT(!tmp2empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0); + tmp2empty = stackptr >= stacktop; + if (!tmp2empty) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + } + tmp1next = TRUE; + } + } + } + } + +if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + } + } +SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); +} + +static SLJIT_INLINE BOOL ispowerof2(unsigned int value) +{ +return (value & (value - 1)) == 0; +} + +static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) +{ +while (list) + { + /* sljit_set_label is clever enough to do nothing + if either the jump or the label is NULL */ + sljit_set_label(list->jump, label); + list = list->next; + } +} + +static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) +{ +jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); +if (list_item) + { + list_item->next = *list; + list_item->jump = jump; + *list = list_item; + } +} + +static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start) +{ +DEFINE_COMPILER; +stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); + +if (list_item) + { + list_item->type = type; + list_item->data = data; + list_item->start = start; + list_item->leave = LABEL(); + list_item->next = common->stubs; + common->stubs = list_item; + } +} + +static void flush_stubs(compiler_common *common) +{ +DEFINE_COMPILER; +stub_list* list_item = common->stubs; + +while (list_item) + { + JUMPHERE(list_item->start); + switch(list_item->type) + { + case stack_alloc: + add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); + break; + } + JUMPTO(SLJIT_JUMP, list_item->leave); + list_item = list_item->next; + } +common->stubs = NULL; +} + +static SLJIT_INLINE void decrease_call_count(compiler_common *common) +{ +DEFINE_COMPILER; + +OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); +add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); +} + +static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) +{ +/* May destroy all locals and registers except TMP2. */ +DEFINE_COMPILER; + +OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); +#ifdef DESTROY_REGISTERS +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); +OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); +#endif +add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); +} + +static SLJIT_INLINE void free_stack(compiler_common *common, int size) +{ +DEFINE_COMPILER; +OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); +} + +static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +int i; +/* At this point we can freely use all temporary registers. */ +/* TMP1 returns with begin - 1. */ +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1); +if (length < 8) + { + for (i = 0; i < length; i++) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); + } +else + { + OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, loop); + } +} + +static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *earlyexit; + +/* At this point we can freely use all registers. */ +OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); + +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START); +/* Unlikely, but possible */ +earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); +loop = LABEL(); +OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0); +OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); +/* Copy the integer value to the output buffer */ +OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_C_NOT_ZERO, loop); +JUMPHERE(earlyexit); + +/* Calculate the return value, which is the maximum ovector value. */ +if (topbracket > 1) + { + OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); + + /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */ + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); + OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); + } +else + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); +} + +static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc) +{ +/* Detects if the character has an othercase. */ +unsigned int c; + +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + GETCHAR(c, cc); + if (c > 127) + { +#ifdef SUPPORT_UCP + return c != UCD_OTHERCASE(c); +#else + return FALSE; +#endif + } + } +else +#endif + c = *cc; +return common->fcc[c] != c; +} + +static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) +{ +/* Returns with the othercase. */ +#ifdef SUPPORT_UTF8 +if (common->utf8 && c > 127) + { +#ifdef SUPPORT_UCP + return UCD_OTHERCASE(c); +#else + return c; +#endif + } +#endif +return common->fcc[c]; +} + +static unsigned int char_get_othercase_bit(compiler_common *common, uschar* cc) +{ +/* Detects if the character and its othercase has only 1 bit difference. */ +unsigned int c, oc, bit; +#ifdef SUPPORT_UTF8 +int n; +#endif + +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + GETCHAR(c, cc); + if (c <= 127) + oc = common->fcc[c]; + else + { +#ifdef SUPPORT_UCP + oc = UCD_OTHERCASE(c); +#else + oc = c; +#endif + } + } +else + { + c = *cc; + oc = common->fcc[c]; + } +#else +c = *cc; +oc = common->fcc[c]; +#endif + +SLJIT_ASSERT(c != oc); + +bit = c ^ oc; +/* Optimized for English alphabet. */ +if (c <= 127 && bit == 0x20) + return (0 << 8) | 0x20; + +/* Since c != oc, they must have at least 1 bit difference. */ +if (!ispowerof2(bit)) + return 0; + +#ifdef SUPPORT_UTF8 +if (common->utf8 && c > 127) + { + n = _pcre_utf8_table4[*cc & 0x3f]; + while ((bit & 0x3f) == 0) + { + n--; + bit >>= 6; + } + return (n << 8) | bit; + } +#endif +return (0 << 8) | bit; +} + +static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks) +{ +DEFINE_COMPILER; +add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); +} + +static void read_char(compiler_common *common) +{ +/* Reads the character into TMP1, updates STR_PTR. +Does not check STR_END. TMP2 Destroyed. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF8 +struct sljit_jump *jump; +#endif + +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); + } +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +} + +static void peek_char(compiler_common *common) +{ +/* Reads the character into TMP1, keeps STR_PTR. +Does not check STR_END. TMP2 Destroyed. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF8 +struct sljit_jump *jump; +#endif + +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif +} + +static void read_char8_type(compiler_common *common) +{ +/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF8 +struct sljit_jump *jump; +#endif + +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + /* This can be an extra read in some situations, but hopefully + it is a clever early read in most cases. */ + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); + add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); + return; + } +#endif +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); +} + +static void skip_char_back(compiler_common *common) +{ +/* Goes one character back. Only affects STR_PTR. Does not check begin. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF8 +struct sljit_label *label; + +if (common->utf8) + { + label = LABEL(); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); + return; + } +#endif +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +} + +static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue) +{ +/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ +DEFINE_COMPILER; + +if (nltype == NLTYPE_ANY) + { + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + } +else if (nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + } +else + { + SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255); + add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } +} + +#ifdef SUPPORT_UTF8 +static void do_utf8readchar(compiler_common *common) +{ +/* Fast decoding an utf8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* 2 byte sequence */ +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* 3 byte sequence */ +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 2); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* 4 byte sequence */ +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +/* 5 byte sequence */ +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void do_utf8readtype8(compiler_common *common) +{ +/* Fast decoding an utf8 character type. TMP2 contains the first byte +of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_jump *compare; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* 2 byte sequence */ +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); +compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(compare); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +/* We only have types for characters less than 256. */ +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes - 0xc0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#endif + +#ifdef SUPPORT_UCP + +/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ +#define UCD_BLOCK_MASK 127 +#define UCD_BLOCK_SHIFT 7 + +static void do_getucd(compiler_common *common) +{ +/* Search the UCD record for the character comes in TMP1. +Returns chartype in TMP1 and UCD offset in TMP2. */ +DEFINE_COMPILER; + +SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); +OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_ucd_stage1); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2); +OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, chartype)); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} +#endif + +static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *mainloop; +struct sljit_label *newlinelabel = NULL; +struct sljit_jump *start; +struct sljit_jump *end = NULL; +struct sljit_jump *nl = NULL; +#ifdef SUPPORT_UTF8 +struct sljit_jump *singlebyte; +#endif +jump_list *newline = NULL; +BOOL newlinecheck = FALSE; +BOOL readbyte = FALSE; + +if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || + common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) + newlinecheck = TRUE; + +if (firstline) + { + /* Search for the end of the first line. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + mainloop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1); + } + else + { + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + mainloop = LABEL(); + /* Continual stores does not cause data dependency. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0); + read_char(common); + check_newlinechar(common, common->nltype, &newline, TRUE); + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0); + set_jumps(newline, LABEL()); + } + + JUMPHERE(end); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + } + +start = JUMP(SLJIT_JUMP); + +if (newlinecheck) + { + newlinelabel = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + nl = JUMP(SLJIT_JUMP); + } + +mainloop = LABEL(); + +/* Increasing the STR_PTR here requires one less jump in the most common case. */ +#ifdef SUPPORT_UTF8 +if (common->utf8) readbyte = TRUE; +#endif +if (newlinecheck) readbyte = TRUE; + +if (readbyte) + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if (newlinecheck) + CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlebyte); + } +#endif +JUMPHERE(start); + +if (newlinecheck) + { + JUMPHERE(end); + JUMPHERE(nl); + } + +return mainloop; +} + +static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *leave; +struct sljit_jump *found; +pcre_uint16 oc, bit; + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); + } + +start = LABEL(); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if ((firstbyte & REQ_CASELESS) == 0) + found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff); +else + { + firstbyte &= 0xff; + oc = common->fcc[firstbyte]; + bit = firstbyte ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit); + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, firstbyte); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + found = JUMP(SLJIT_C_NOT_ZERO); + } + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(leave); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *lastchar; +struct sljit_jump *firstchar; +struct sljit_jump *leave; +struct sljit_jump *foundcr = NULL; +struct sljit_jump *notfoundnl; +jump_list *newline = NULL; + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); + } + +if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + + loop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); + + JUMPHERE(leave); + JUMPHERE(firstchar); + JUMPHERE(lastchar); + + if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + return; + } + +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); +skip_char_back(common); + +loop = LABEL(); +read_char(common); +lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); +check_newlinechar(common, common->nltype, &newline, FALSE); +set_jumps(newline, loop); + +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + { + leave = JUMP(SLJIT_JUMP); + JUMPHERE(foundcr); + notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(notfoundnl); + JUMPHERE(leave); + } +JUMPHERE(lastchar); +JUMPHERE(firstchar); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *leave; +struct sljit_jump *found; + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); + } + +start = LABEL(); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF8 +if (common->utf8) + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +#endif +OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits); +OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); +found = JUMP(SLJIT_C_NOT_ZERO); + +#ifdef SUPPORT_UTF8 +if (common->utf8) + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(leave); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uint16 reqbyte, BOOL has_firstbyte) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *toolong; +struct sljit_jump *alreadyfound; +struct sljit_jump *found; +struct sljit_jump *foundoc = NULL; +struct sljit_jump *notfound; +pcre_uint16 oc, bit; + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR); +OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); +toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); +alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); + +if (has_firstbyte) + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1); +else + OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); + +loop = LABEL(); +notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); + +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0); +if ((reqbyte & REQ_CASELESS) == 0) + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff); +else + { + reqbyte &= 0xff; + oc = common->fcc[reqbyte]; + bit = reqbyte ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit); + } + else + { + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte); + foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); + } + } +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_JUMP, loop); + +JUMPHERE(found); +if (foundoc) + JUMPHERE(foundoc); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0); +JUMPHERE(alreadyfound); +JUMPHERE(toolong); +return notfound; +} + +static void do_revertframes(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *mainloop; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); +OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); + +/* Drop frames until we reach STACK_TOP. */ +mainloop = LABEL(); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); +jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); +JUMPTO(SLJIT_JUMP, mainloop); + +JUMPHERE(jump); +jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); +/* End of dropping frames. */ +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); +/* Set string begin. */ +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); +JUMPTO(SLJIT_JUMP, mainloop); + +JUMPHERE(jump); +/* Unknown command. */ +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); +JUMPTO(SLJIT_JUMP, mainloop); +} + +static void check_wordboundary(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *beginend; +#ifdef SUPPORT_UTF8 +struct sljit_jump *jump; +#endif + +SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); + +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize); +/* Get type of the previous char, and put it to LOCALS1. */ +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); +beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); +skip_char_back(common); +read_char(common); + +/* Testing char type. */ +#ifdef SUPPORT_UCP +if (common->useucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); + } +else +#endif + { +#ifdef SUPPORT_UTF8 + /* Here LOCALS1 has already been zeroed. */ + jump = NULL; + if (common->utf8) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); +#ifdef SUPPORT_UTF8 + if (jump != NULL) + JUMPHERE(jump); +#endif + } +JUMPHERE(beginend); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); +beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +peek_char(common); + +/* Testing char type. This is a code duplication. */ +#ifdef SUPPORT_UCP +if (common->useucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + JUMPHERE(jump); + } +else +#endif + { +#ifdef SUPPORT_UTF8 + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = NULL; + if (common->utf8) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +#ifdef SUPPORT_UTF8 + if (jump != NULL) + JUMPHERE(jump); +#endif + } +JUMPHERE(beginend); + +OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +} + +static void check_anynewline(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); + } +#endif +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_hspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); + +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); + } +#endif +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_vspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#ifdef SUPPORT_UTF8 +if (common->utf8) + { + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); + } +#endif +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define CHAR1 STR_END +#define CHAR2 STACK_TOP + +static void do_casefulcmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + +label = LABEL(); +OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1); +OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1); +jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_C_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define LCC_TABLE STACK_LIMIT + +static void do_caselesscmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0); +OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + +label = LABEL(); +OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1); +OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1); +OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); +OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); +jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_C_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#undef LCC_TABLE +#undef CHAR1 +#undef CHAR2 + +#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UCP + +static uschar * SLJIT_CALL do_utf8caselesscmp(uschar *src1, jit_arguments *args, uschar *end1) +{ +/* This function would be ineffective to do in JIT level. */ +int c1, c2; +uschar *src2 = args->ptr; +uschar *end2 = (uschar*)args->end; + +while (src1 < end1) + { + if (src2 >= end2) + return 0; + GETCHARINC(c1, src1); + GETCHARINC(c2, src2); + if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0; + } +return src2; +} + +#endif +#endif + +static uschar *byte_sequence_compare(compiler_common *common, BOOL caseless, uschar *cc, + compare_context* context, jump_list **fallbacks) +{ +DEFINE_COMPILER; +unsigned int othercasebit = 0; +uschar *othercasebyte = NULL; +#ifdef SUPPORT_UTF8 +int utf8length; +#endif + +if (caseless && char_has_othercase(common, cc)) + { + othercasebit = char_get_othercase_bit(common, cc); + SLJIT_ASSERT(othercasebit); + /* Extracting bit difference info. */ + othercasebyte = cc + (othercasebit >> 8); + othercasebit &= 0xff; + } + +if (context->sourcereg == -1) + { +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + context->sourcereg = TMP2; + } + +#ifdef SUPPORT_UTF8 +utf8length = 1; +if (common->utf8 && *cc >= 0xc0) + utf8length += _pcre_utf8_table4[*cc & 0x3f]; + +do + { +#endif + + context->length--; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + + /* Unaligned read is supported. */ + if (othercasebit != 0 && othercasebyte == cc) + { + context->c.asbytes[context->byteptr] = *cc | othercasebit; + context->oc.asbytes[context->byteptr] = othercasebit; + } + else + { + context->c.asbytes[context->byteptr] = *cc; + context->oc.asbytes[context->byteptr] = 0; + } + context->byteptr++; + + if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1)) + { + if (context->length >= 4) + OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_SH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 1) + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + switch(context->byteptr) + { + case 4: + if (context->oc.asint != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); + break; + + case 2: + if (context->oc.asshort != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asshort); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asshort | context->oc.asshort)); + break; + + case 1: + if (context->oc.asbyte != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + context->byteptr = 0; + } + +#else + + /* Unaligned read is unsupported. */ + if (context->length > 0) + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + if (othercasebit != 0 && othercasebyte == cc) + { + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); + } + else + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); + +#endif + + cc++; +#ifdef SUPPORT_UTF8 + utf8length--; + } +while (utf8length > 0); +#endif + +return cc; +} + +#ifdef SUPPORT_UTF8 + +#define SET_TYPE_OFFSET(value) \ + if ((value) != typeoffset) \ + { \ + if ((value) > typeoffset) \ + OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ + else \ + OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ + } \ + typeoffset = (value); + +#define SET_CHAR_OFFSET(value) \ + if ((value) != charoffset) \ + { \ + if ((value) > charoffset) \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \ + else \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \ + } \ + charoffset = (value); + +static void compile_xclass_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks; +unsigned int c; +int compares; +struct sljit_jump *jump = NULL; +uschar *ccbegin; +#ifdef SUPPORT_UCP +BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; +BOOL charsaved = FALSE; +int typereg = TMP1, scriptreg = TMP1; +unsigned int typeoffset; +#endif +int invertcmp, numberofcmps; +unsigned int charoffset; + +/* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */ +check_input_end(common, fallbacks); +read_char(common); + +if ((*cc++ & XCL_MAP) != 0) + { + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); + if (common->utf8) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); + + if (common->utf8) + JUMPHERE(jump); + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +#ifdef SUPPORT_UCP + charsaved = TRUE; +#endif + cc += 32; + } + +/* Scanning the necessary info. */ +ccbegin = cc; +compares = 0; +while (*cc != XCL_END) + { + compares++; + if (*cc == XCL_SINGLE) + { + cc += 2; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#endif +#ifdef SUPPORT_UCP + needschar = TRUE; +#endif + } + else if (*cc == XCL_RANGE) + { + cc += 2; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#endif + cc++; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#endif +#ifdef SUPPORT_UCP + needschar = TRUE; +#endif + } +#ifdef SUPPORT_UCP + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + switch(*cc) + { + case PT_ANY: + break; + + case PT_LAMP: + case PT_GC: + case PT_PC: + case PT_ALNUM: + needstype = TRUE; + break; + + case PT_SC: + needsscript = TRUE; + break; + + case PT_SPACE: + case PT_PXSPACE: + case PT_WORD: + needstype = TRUE; + needschar = TRUE; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += 2; + } +#endif + } + +#ifdef SUPPORT_UCP +/* Simple register allocation. TMP1 is preferred if possible. */ +if (needstype || needsscript) + { + if (needschar && !charsaved) + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + if (needschar) + { + if (needstype) + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + typereg = RETURN_ADDR; + } + + if (needsscript) + scriptreg = TMP3; + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + } + else if (needstype && needsscript) + scriptreg = TMP3; + /* In all other cases only one of them was specified, and that can goes to TMP1. */ + + if (needsscript) + { + if (scriptreg == TMP1) + { + OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); + } + else + { + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); + } + } + } +#endif + +/* Generating code. */ +cc = ccbegin; +charoffset = 0; +numberofcmps = 0; +#ifdef SUPPORT_UCP +typeoffset = 0; +#endif + +while (*cc != XCL_END) + { + compares--; + invertcmp = (compares == 0 && list != fallbacks); + jump = NULL; + + if (*cc == XCL_SINGLE) + { + cc ++; +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); + numberofcmps = 0; + } + } + else if (*cc == XCL_RANGE) + { + cc ++; +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + SET_CHAR_OFFSET(c); +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); + numberofcmps = 0; + } + } +#ifdef SUPPORT_UCP + else + { + if (*cc == XCL_NOTPROP) + invertcmp ^= 0x1; + cc++; + switch(*cc) + { + case PT_ANY: + if (list != fallbacks) + { + if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) + continue; + } + else if (cc[-1] == XCL_NOTPROP) + continue; + jump = JUMP(SLJIT_JUMP); + break; + + case PT_LAMP: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_GC: + c = _pcre_ucp_typerange[(int)cc[1] * 2]; + SET_TYPE_OFFSET(c); + jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, _pcre_ucp_typerange[(int)cc[1] * 2 + 1] - c); + break; + + case PT_PC: + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); + break; + + case PT_SC: + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); + break; + + case PT_SPACE: + case PT_PXSPACE: + if (*cc == PT_SPACE) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset); + } + SET_CHAR_OFFSET(9); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + if (*cc == PT_SPACE) + JUMPHERE(jump); + + SET_TYPE_OFFSET(ucp_Zl); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_WORD: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + /* ... fall through */ + + case PT_ALNUM: + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + SET_TYPE_OFFSET(ucp_Nd); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + } + cc += 2; + } +#endif + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : fallbacks, jump); + } + +if (found != NULL) + set_jumps(found, LABEL()); +} + +#undef SET_TYPE_OFFSET +#undef SET_CHAR_OFFSET + +#endif + +static uschar *compile_char1_hotpath(compiler_common *common, uschar type, uschar *cc, jump_list **fallbacks) +{ +DEFINE_COMPILER; +int length; +unsigned int c, oc, bit; +compare_context context; +struct sljit_jump *jump[4]; +#ifdef SUPPORT_UTF8 +struct sljit_label *label; +#ifdef SUPPORT_UCP +uschar propdata[5]; +#endif +#endif + +switch(type) + { + case OP_SOD: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_SOM: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + + case OP_NOT_DIGIT: + case OP_DIGIT: + check_input_end(common, fallbacks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + check_input_end(common, fallbacks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); + add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + check_input_end(common, fallbacks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); + add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_ANY: + check_input_end(common, fallbacks); + read_char(common); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); + JUMPHERE(jump[1]); + JUMPHERE(jump[0]); + } + else + check_newlinechar(common, common->nltype, fallbacks, TRUE); + return cc; + + case OP_ALLANY: + check_input_end(common, fallbacks); +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc; + } +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + return cc; + + case OP_ANYBYTE: + check_input_end(common, fallbacks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + return cc; + +#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UCP + case OP_NOTPROP: + case OP_PROP: + propdata[0] = 0; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + compile_xclass_hotpath(common, propdata, fallbacks); + return cc + 2; +#endif +#endif + + case OP_ANYNL: + check_input_end(common, fallbacks); + read_char(common); + jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + jump[3] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE); + JUMPHERE(jump[1]); + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + return cc; + + case OP_NOT_HSPACE: + case OP_HSPACE: + check_input_end(common, fallbacks); + read_char(common); + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + + case OP_NOT_VSPACE: + case OP_VSPACE: + check_input_end(common, fallbacks); + read_char(common); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + +#ifdef SUPPORT_UCP + case OP_EXTUNI: + check_input_end(common, fallbacks); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); + + label = LABEL(); + jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(jump[0]); + return cc; +#endif + + case OP_EODN: + jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } + else + { + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_C_GREATER); + add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1); + jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1); + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); + read_char(common); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + return cc; + + case OP_EOD: + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + return cc; + + case OP_CIRC: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + return cc; + + case OP_CIRCM: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0)); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2); + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + skip_char_back(common); + read_char(common); + check_newlinechar(common, common->nltype, fallbacks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_DOLL: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + + if (!common->endonly) + compile_char1_hotpath(common, OP_EODN, cc, fallbacks); + else + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); + return cc; + + case OP_DOLLM: + jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2); + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char(common); + check_newlinechar(common, common->nltype, fallbacks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_CHAR: + case OP_CHARI: + length = 1; +#ifdef SUPPORT_UTF8 + if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f]; +#endif + if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length); + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + + context.length = length; + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.byteptr = 0; +#endif + return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); + } + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + read_char(common); +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + GETCHAR(c, cc); + } + else +#endif + c = *cc; + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); + return cc + length; + + case OP_NOT: + case OP_NOTI: + length = 1; +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f]; + + check_input_end(common, fallbacks); + GETCHAR(c, cc); + + if (c <= 127) + { + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); + } + /* Skip the variable-length character. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc + length; + } + else + read_char(common); + } + else +#endif + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1); + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1); + c = *cc; + } + + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + oc = char_othercase(common, c); + bit = c ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + } + else + { + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + } + } + return cc + length; + + case OP_CLASS: + case OP_NCLASS: + check_input_end(common, fallbacks); + read_char(common); +#ifdef SUPPORT_UTF8 + jump[0] = NULL; + if (common->utf8) + { + jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (type == OP_CLASS) + { + add_jump(compiler, fallbacks, jump[0]); + jump[0] = NULL; + } + } +#endif + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); +#ifdef SUPPORT_UTF8 + if (jump[0] != NULL) + JUMPHERE(jump[0]); +#endif + return cc + 32; + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks); + return cc + GET(cc, 0) - 1; +#endif + + case OP_REVERSE: + length = GET(cc, 0); + SLJIT_ASSERT(length > 0); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); + label = LABEL(); + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0)); + skip_char_back(common); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + return cc + LINK_SIZE; + } +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length); + add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); + return cc + LINK_SIZE; + } +SLJIT_ASSERT_STOP(); +return cc; +} + +static SLJIT_INLINE uschar *compile_charn_hotpath(compiler_common *common, uschar *cc, uschar *ccend, jump_list **fallbacks) +{ +/* This function consumes at least one input character. */ +/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ +DEFINE_COMPILER; +uschar *ccbegin = cc; +compare_context context; +int size; + +context.length = 0; +do + { + if (cc >= ccend) + break; + + if (*cc == OP_CHAR) + { + size = 1; +#ifdef SUPPORT_UTF8 + if (common->utf8 && cc[1] >= 0xc0) + size += _pcre_utf8_table4[cc[1] & 0x3f]; +#endif + } + else if (*cc == OP_CHARI) + { + size = 1; +#ifdef SUPPORT_UTF8 + if (common->utf8) + { + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + else if (cc[1] >= 0xc0) + size += _pcre_utf8_table4[cc[1] & 0x3f]; + } + else +#endif + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + } + else + size = 0; + + cc += 1 + size; + context.length += size; + } +while (size > 0 && context.length <= 128); + +cc = ccbegin; +if (context.length > 0) + { + /* We have a fixed-length byte sequence. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.byteptr = 0; +#endif + do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0); + return cc; + } + +/* A non-fixed length character will be checked if length == 0. */ +return compile_char1_hotpath(common, *cc, cc + 1, fallbacks); +} + +static struct sljit_jump *compile_ref_checks(compiler_common *common, uschar *cc, jump_list **fallbacks) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1) << 1; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); +if (!common->jscript_compat) + { + if (fallbacks == NULL) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + return JUMP(SLJIT_C_NOT_ZERO); + } + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + } +return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); +} + +/* Forward definitions. */ +static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *); +static void compile_fallbackpath(compiler_common *, struct fallback_common *); + +#define PUSH_FALLBACK(size, ccstart, error) \ + do \ + { \ + fallback = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return error; \ + memset(fallback, 0, size); \ + fallback->prev = parent->top; \ + fallback->cc = (ccstart); \ + parent->top = fallback; \ + } \ + while (0) + +#define PUSH_FALLBACK_NOVALUE(size, ccstart) \ + do \ + { \ + fallback = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + memset(fallback, 0, size); \ + fallback->prev = parent->top; \ + fallback->cc = (ccstart); \ + parent->top = fallback; \ + } \ + while (0) + +#define FALLBACK_AS(type) ((type*)fallback) + +static uschar *compile_ref_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1) << 1; +struct sljit_jump *jump = NULL; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); +if (withchecks && !common->jscript_compat) + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + +#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UCP +if (common->utf8 && *cc == OP_REFI) + { + SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + if (withchecks) + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); + + /* Needed to save important temporary registers. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf8caselesscmp)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + } +else +#endif +#endif + { + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); + if (withchecks) + jump = JUMP(SLJIT_C_ZERO); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + + add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + } + +if (jump != NULL) + { + if (emptyfail) + add_jump(compiler, fallbacks, jump); + else + JUMPHERE(jump); + } +return cc + 3; +} + +static SLJIT_INLINE uschar *compile_ref_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; +uschar type; +struct sljit_label *label; +struct sljit_jump *zerolength; +struct sljit_jump *jump = NULL; +uschar *ccbegin = cc; +int min = 0, max = 0; +BOOL minimize; + +PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL); + +type = cc[3]; +minimize = (type & 0x1) != 0; +switch(type) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + min = 0; + max = 0; + cc += 4; + break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + max = 0; + cc += 4; + break; + case OP_CRQUERY: + case OP_CRMINQUERY: + min = 0; + max = 1; + cc += 4; + break; + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(cc, 3 + 1); + max = GET2(cc, 3 + 3); + cc += 8; + break; + default: + SLJIT_ASSERT_STOP(); + break; + } + +if (!minimize) + { + if (min == 0) + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + /* Temporary release of STR_PTR. */ + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + zerolength = compile_ref_checks(common, ccbegin, NULL); + /* Restore if not zero length. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + else + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks); + } + + if (min > 1 || max > 1) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); + + label = LABEL(); + compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE); + + if (min > 1 || max > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + if (min > 1) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); + if (max > 1) + { + jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + JUMPHERE(jump); + } + } + + if (max == 0) + { + /* Includes min > 1 case as well. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + } + + JUMPHERE(zerolength); + FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); + + decrease_call_count(common); + return cc; + } + +allocate_stack(common, 2); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); +if (type != OP_CRMINSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + +if (min == 0) + { + zerolength = compile_ref_checks(common, ccbegin, NULL); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + jump = JUMP(SLJIT_JUMP); + } +else + zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks); + +FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); +if (max > 0) + add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); + +compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +if (min > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath); + } +else if (max > 0) + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + +if (jump != NULL) + JUMPHERE(jump); +JUMPHERE(zerolength); + +decrease_call_count(common); +return cc; +} + +static SLJIT_INLINE uschar *compile_recurse_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; +recurse_entry *entry = common->entries; +recurse_entry *prev = NULL; +int start = GET(cc, 1); + +PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL); +while (entry != NULL) + { + if (entry->start == start) + break; + prev = entry; + entry = entry->next; + } + +if (entry == NULL) + { + entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + entry->next = NULL; + entry->entry = NULL; + entry->calls = NULL; + entry->start = start; + + if (prev != NULL) + prev->next = entry; + else + common->entries = entry; + } + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); +allocate_stack(common, 1); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + +if (entry->entry == NULL) + add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); +else + JUMPTO(SLJIT_FAST_CALL, entry->entry); +/* Leave if the match is failed. */ +add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); +return cc + 1 + LINK_SIZE; +} + +static uschar *compile_assert_hotpath(compiler_common *common, uschar *cc, assert_fallback *fallback, BOOL conditional) +{ +DEFINE_COMPILER; +int framesize; +int localptr; +fallback_common altfallback; +uschar *ccbegin; +uschar opcode; +uschar bra = OP_BRA; +jump_list *tmp = NULL; +jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; +jump_list **found; +/* Saving previous accept variables. */ +struct sljit_label *save_acceptlabel = common->acceptlabel; +struct sljit_jump *jump; +struct sljit_jump *brajump = NULL; +jump_list *save_accept = common->accept; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + SLJIT_ASSERT(!conditional); + bra = *cc; + cc++; + } +localptr = PRIV(cc); +SLJIT_ASSERT(localptr != 0); +framesize = get_framesize(common, cc, FALSE); +fallback->framesize = framesize; +fallback->localptr = localptr; +opcode = *cc; +SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); +found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; +ccbegin = cc; +cc += GET(cc, 1); + +if (bra == OP_BRAMINZERO) + { + /* This is a braminzero fallback path. */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (framesize < 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } +else + { + allocate_stack(common, framesize + 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, framesize + 1, 2, FALSE); + } + +memset(&altfallback, 0, sizeof(fallback_common)); +while (1) + { + common->acceptlabel = NULL; + common->accept = NULL; + altfallback.top = NULL; + altfallback.topfallbacks = NULL; + + if (*ccbegin == OP_ALT) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + altfallback.cc = ccbegin; + compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->acceptlabel = save_acceptlabel; + common->accept = save_accept; + return NULL; + } + common->acceptlabel = LABEL(); + if (common->accept != NULL) + set_jumps(common->accept, common->acceptlabel); + + /* Reset stack. */ + if (framesize < 0) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + else { + if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); + } + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + } + + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + /* We know that STR_PTR was stored on the top of the stack. */ + if (conditional) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (bra == OP_BRAZERO) + { + if (framesize < 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else if (framesize >= 0) + { + /* For OP_BRA and OP_BRAMINZERO. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + } + } + add_jump(compiler, found, JUMP(SLJIT_JUMP)); + + compile_fallbackpath(common, altfallback.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->acceptlabel = save_acceptlabel; + common->accept = save_accept; + return NULL; + } + set_jumps(altfallback.topfallbacks, LABEL()); + + if (*cc != OP_ALT) + break; + + ccbegin = cc; + cc += GET(cc, 1); + } +/* None of them matched. */ + +if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) + { + /* Assert is failed. */ + if (conditional || bra == OP_BRAZERO) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + if (framesize < 0) + { + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + else + free_stack(common, 1); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + { + free_stack(common, framesize + 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + jump = JUMP(SLJIT_JUMP); + if (bra != OP_BRAZERO) + add_jump(compiler, target, jump); + + /* Assert is successful. */ + set_jumps(tmp, LABEL()); + if (framesize < 0) + { + /* We know that STR_PTR was stored on the top of the stack. */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + /* Keep the STR_PTR on the top of the stack. */ + if (bra == OP_BRAZERO) + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + else if (bra == OP_BRAMINZERO) + { + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + else + { + if (bra == OP_BRA) + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + } + else + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); + } + } + + if (bra == OP_BRAZERO) + { + fallback->hotpath = LABEL(); + sljit_set_label(jump, fallback->hotpath); + } + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, fallback->hotpath); + JUMPHERE(brajump); + if (framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + } + set_jumps(fallback->common.topfallbacks, LABEL()); + } + } +else + { + /* AssertNot is successful. */ + if (framesize < 0) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra != OP_BRA) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + else + free_stack(common, 1); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* The topmost item should be 0. */ + if (bra != OP_BRA) + { + free_stack(common, framesize + 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + + if (bra == OP_BRAZERO) + fallback->hotpath = LABEL(); + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, fallback->hotpath); + JUMPHERE(brajump); + } + + if (bra != OP_BRA) + { + SLJIT_ASSERT(found == &fallback->common.topfallbacks); + set_jumps(fallback->common.topfallbacks, LABEL()); + fallback->common.topfallbacks = NULL; + } + } + +common->acceptlabel = save_acceptlabel; +common->accept = save_accept; +return cc + 1 + LINK_SIZE; +} + +static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table) +{ +int condition = FALSE; +uschar *slotA = name_table; +uschar *slotB; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w no_capture; +int i; + +locals += OVECTOR_START / sizeof(sljit_w); +no_capture = locals[1]; + +for (i = 0; i < name_count; i++) + { + if (GET2(slotA, 0) == refno) break; + slotA += name_entry_size; + } + +if (i < name_count) + { + /* Found a name for the number - there can be only one; duplicate names + for different numbers are allowed, but not vice versa. First scan down + for duplicates. */ + + slotB = slotA; + while (slotB > name_table) + { + slotB -= name_entry_size; + if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + { + condition = locals[GET2(slotB, 0) << 1] != no_capture; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + if (!condition) + { + slotB = slotA; + for (i++; i < name_count; i++) + { + slotB += name_entry_size; + if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + { + condition = locals[GET2(slotB, 0) << 1] != no_capture; + if (condition) break; + } + else break; + } + } + } +return condition; +} + +static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table) +{ +int condition = FALSE; +uschar *slotA = name_table; +uschar *slotB; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)]; +int i; + +for (i = 0; i < name_count; i++) + { + if (GET2(slotA, 0) == recno) break; + slotA += name_entry_size; + } + +if (i < name_count) + { + /* Found a name for the number - there can be only one; duplicate + names for different numbers are allowed, but not vice versa. First + scan down for duplicates. */ + + slotB = slotA; + while (slotB > name_table) + { + slotB -= name_entry_size; + if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + { + condition = GET2(slotB, 0) == group_num; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + if (!condition) + { + slotB = slotA; + for (i++; i < name_count; i++) + { + slotB += name_entry_size; + if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + { + condition = GET2(slotB, 0) == group_num; + if (condition) break; + } + else break; + } + } + } +return condition; +} + +/* + Handling bracketed expressions is probably the most complex part. + + Stack layout naming characters: + S - Push the current STR_PTR + 0 - Push a 0 (NULL) + A - Push the current STR_PTR. Needed for restoring the STR_PTR + before the next alternative. Not pushed if there are no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. + L - Push the previous local (pointed by localptr) to the stack + () - opional values stored on the stack + ()* - optonal, can be stored multiple times + + The following list shows the regular expression templates, their PCRE byte codes + and stack layout supported by pcre-sljit. + + (?:) OP_BRA | OP_KET A M + () OP_CBRA | OP_KET C M + (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* + OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* + (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* + OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* + ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* + ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* + (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) + (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) + ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) + ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) + (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* + OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* + (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* + OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* + ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* + OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* + ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* + OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* + + + Stack layout naming characters: + A - Push the alternative index (starting from 0) on the stack. + Not pushed if there is no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + + The next list shows the possible content of a bracket: + (|) OP_*BRA | OP_ALT ... M A + (?()|) OP_*COND | OP_ALT M A + (?>|) OP_ONCE | OP_ALT ... [stack trace] M A + (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A + Or nothing, if trace is unnecessary +*/ + +static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; +uschar opcode; +int localptr = 0; +int offset = 0; +int stacksize; +uschar *ccbegin; +uschar *hotpath; +uschar bra = OP_BRA; +uschar ket; +assert_fallback *assert; +BOOL has_alternatives; +struct sljit_jump *jump; +struct sljit_jump *skip; +struct sljit_label *rmaxlabel = NULL; +struct sljit_jump *braminzerojump = NULL; + +PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL); + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + opcode = *cc; + } + +opcode = *cc; +ccbegin = cc; +hotpath = ccbegin + 1 + LINK_SIZE; + +if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) + { + /* Drop this bracket_fallback. */ + parent->top = fallback->prev; + return bracketend(cc); + } + +ket = *(bracketend(cc) - 1 - LINK_SIZE); +SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); +SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); +cc += GET(cc, 1); + +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE; + if (*hotpath == OP_NRREF) + { + stacksize = GET2(hotpath, 1); + if (common->currententry == NULL || stacksize == RREF_ANY) + has_alternatives = FALSE; + else if (common->currententry->start == 0) + has_alternatives = stacksize != 0; + else + has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + } + } + +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Capturing brackets has a pre-allocated space. */ + offset = GET2(ccbegin, 1 + LINK_SIZE); + localptr = OVECTOR_PRIV(offset); + offset <<= 1; + FALLBACK_AS(bracket_fallback)->localptr = localptr; + hotpath += 2; + } +else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Other brackets simply allocate the next entry. */ + localptr = PRIV(ccbegin); + SLJIT_ASSERT(localptr != 0); + FALLBACK_AS(bracket_fallback)->localptr = localptr; + if (opcode == OP_ONCE) + FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE); + } + +/* Instructions before the first alternative. */ +stacksize = 0; +if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + stacksize++; +if (bra == OP_BRAZERO) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (bra == OP_BRAZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + +if (bra == OP_BRAMINZERO) + { + /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (ket != OP_KETRMIN) + { + free_stack(common, 1); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + else + { + if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* Nothing stored during the first run. */ + skip = JUMP(SLJIT_JUMP); + JUMPHERE(jump); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0) + { + /* When we come from outside, localptr contains the previous STR_PTR. */ + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + } + else + { + /* Except when the whole stack frame must be saved. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w)); + } + JUMPHERE(skip); + } + else + { + jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPHERE(jump); + } + } + } + +if (ket == OP_KETRMIN) + FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL(); + +if (ket == OP_KETRMAX) + { + rmaxlabel = LABEL(); + if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) + FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel; + } + +/* Handling capturing brackets and alternatives. */ +if (opcode == OP_ONCE) + { + if (FALLBACK_AS(bracket_fallback)->u.framesize < 0) + { + /* Neither capturing brackets nor recursions are not found in the block. */ + if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + else if (ket == OP_KETRMAX || has_alternatives) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + } + else + { + if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) + { + allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE); + } + else + { + allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE); + } + } + } +else if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Saving the previous values. */ + allocate_stack(common, 3); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Saving the previous value. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } +else if (has_alternatives) + { + /* Pushing the starting string pointer. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + +/* Generating code for the first alternative. */ +if (opcode == OP_COND || opcode == OP_SCOND) + { + if (*hotpath == OP_CREF) + { + SLJIT_ASSERT(has_alternatives); + add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), + CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + hotpath += 3; + } + else if (*hotpath == OP_NCREF) + { + SLJIT_ASSERT(has_alternatives); + stacksize = GET2(hotpath, 1); + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + + JUMPHERE(jump); + hotpath += 3; + } + else if (*hotpath == OP_RREF || *hotpath == OP_NRREF) + { + /* Never has other case. */ + FALLBACK_AS(bracket_fallback)->u.condfailed = NULL; + + stacksize = GET2(hotpath, 1); + if (common->currententry == NULL) + stacksize = 0; + else if (stacksize == RREF_ANY) + stacksize = 1; + else if (common->currententry->start == 0) + stacksize = stacksize == 0; + else + stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + + if (*hotpath == OP_RREF || stacksize || common->currententry == NULL) + { + SLJIT_ASSERT(!has_alternatives); + if (stacksize != 0) + hotpath += 3; + else + { + if (*cc == OP_ALT) + { + hotpath = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } + else + hotpath = cc; + } + } + else + { + SLJIT_ASSERT(has_alternatives); + + stacksize = GET2(hotpath, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + hotpath += 3; + } + } + else + { + SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT); + /* Similar code as PUSH_FALLBACK macro. */ + assert = sljit_alloc_memory(compiler, sizeof(assert_fallback)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + memset(assert, 0, sizeof(assert_fallback)); + assert->common.cc = hotpath; + FALLBACK_AS(bracket_fallback)->u.assert = assert; + hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE); + } + } + +compile_hotpath(common, hotpath, cc, fallback); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + +if (opcode == OP_ONCE) + { + if (FALLBACK_AS(bracket_fallback)->u.framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + /* TMP2 which is set here used by OP_KETRMAX below. */ + if (ket == OP_KETRMAX) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (ket == OP_KETRMIN) + { + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); + } + } + else + { + stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w)); + if (ket == OP_KETRMAX) + { + /* TMP2 which is set here used by OP_KETRMAX below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + } + } + +stacksize = 0; +if (ket != OP_KET || bra != OP_BRA) + stacksize++; +if (has_alternatives && opcode != OP_ONCE) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if (ket != OP_KET) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + stacksize++; + } +else if (bra != OP_BRA) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (has_alternatives) + { + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + if (ket != OP_KETRMAX) + FALLBACK_AS(bracket_fallback)->althotpath = LABEL(); + } + +/* Must be after the hotpath label. */ +if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); + } + +if (ket == OP_KETRMAX) + { + if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + if (has_alternatives) + FALLBACK_AS(bracket_fallback)->althotpath = LABEL(); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE) + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); + else + /* TMP2 must contain the starting STR_PTR. */ + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel); + } + else + JUMPTO(SLJIT_JUMP, rmaxlabel); + FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL(); + } + +if (bra == OP_BRAZERO) + FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL(); + +if (bra == OP_BRAMINZERO) + { + /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ + JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath); + if (braminzerojump != NULL) + { + JUMPHERE(braminzerojump); + /* We need to release the end pointer to perform the + fallback for the zero-length iteration. When + framesize is < 0, OP_ONCE will do the release itself. */ + if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + else if (ket == OP_KETRMIN && opcode != OP_ONCE) + free_stack(common, 1); + } + /* Continue to the normal fallback. */ + } + +if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) + decrease_call_count(common); + +/* Skip the other alternatives. */ +while (*cc == OP_ALT) + cc += GET(cc, 1); +cc += 1 + LINK_SIZE; +return cc; +} + +static uschar *compile_bracketpos_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; +uschar opcode; +int localptr; +int cbraprivptr = 0; +int framesize; +int stacksize; +int offset = 0; +BOOL zero = FALSE; +uschar *ccbegin = NULL; +int stack; +struct sljit_label *loop = NULL; +struct jump_list *emptymatch = NULL; + +PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL); +if (*cc == OP_BRAPOSZERO) + { + zero = TRUE; + cc++; + } + +opcode = *cc; +localptr = PRIV(cc); +SLJIT_ASSERT(localptr != 0); +FALLBACK_AS(bracketpos_fallback)->localptr = localptr; +switch(opcode) + { + case OP_BRAPOS: + case OP_SBRAPOS: + ccbegin = cc + 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + offset = GET2(cc, 1 + LINK_SIZE); + cbraprivptr = OVECTOR_PRIV(offset); + offset <<= 1; + ccbegin = cc + 1 + LINK_SIZE + 2; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +framesize = get_framesize(common, cc, FALSE); +FALLBACK_AS(bracketpos_fallback)->framesize = framesize; +if (framesize < 0) + { + stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; + if (!zero) + stacksize++; + FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; + allocate_stack(common, stacksize); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); + } +else + { + stacksize = framesize + 1; + if (!zero) + stacksize++; + if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + stacksize++; + FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; + allocate_stack(common, stacksize); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + stack = 0; + if (!zero) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); + stack++; + } + if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); + stack++; + } + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); + init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); + } + +if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + +loop = LABEL(); +while (*cc != OP_KETRPOS) + { + fallback->top = NULL; + fallback->topfallbacks = NULL; + cc += GET(cc, 1); + + compile_hotpath(common, ccbegin, cc, fallback); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + + if (framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + } + else + { + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + } + else + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w)); + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0); + } + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + { + if (framesize < 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + JUMPTO(SLJIT_JUMP, loop); + flush_stubs(common); + + compile_fallbackpath(common, fallback->top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + set_jumps(fallback->topfallbacks, LABEL()); + + if (framesize < 0) + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + else + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + /* Last alternative. */ + if (*cc == OP_KETRPOS) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); + } + } + + if (*cc == OP_KETRPOS) + break; + ccbegin = cc + 1 + LINK_SIZE; + } + +fallback->topfallbacks = NULL; +if (!zero) + { + if (framesize < 0) + add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); + else /* TMP2 is set to [localptr] above. */ + add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); + } + +/* None of them matched. */ +set_jumps(emptymatch, LABEL()); +decrease_call_count(common); +return cc + 1 + LINK_SIZE; +} + +static SLJIT_INLINE uschar *get_iterator_parameters(compiler_common *common, uschar *cc, uschar *opcode, uschar *type, int *arg1, int *arg2, uschar **end) +{ +int class_len; + +*opcode = *cc; +if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) + { + cc++; + *type = OP_CHAR; + } +else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) + { + cc++; + *type = OP_CHARI; + *opcode -= OP_STARI - OP_STAR; + } +else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) + { + cc++; + *type = OP_NOT; + *opcode -= OP_NOTSTAR - OP_STAR; + } +else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) + { + cc++; + *type = OP_NOTI; + *opcode -= OP_NOTSTARI - OP_STAR; + } +else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) + { + cc++; + *opcode -= OP_TYPESTAR - OP_STAR; + *type = 0; + } +else + { + SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); + *type = *opcode; + cc++; + class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0); + *opcode = cc[class_len - 1]; + if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) + { + *opcode -= OP_CRSTAR - OP_STAR; + if (end != NULL) + *end = cc + class_len; + } + else + { + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE); + *arg1 = GET2(cc, (class_len + 2)); + *arg2 = GET2(cc, class_len); + + if (*arg2 == 0) + { + SLJIT_ASSERT(*arg1 != 0); + *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO; + } + if (*arg1 == *arg2) + *opcode = OP_EXACT; + + if (end != NULL) + *end = cc + class_len + 4; + } + return cc; + } + +if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) + { + *arg1 = GET2(cc, 0); + cc += 2; + } + +if (*type == 0) + { + *type = *cc; + if (end != NULL) + *end = next_opcode(common, cc); + cc++; + return cc; + } + +if (end != NULL) + { + *end = cc + 1; +#ifdef SUPPORT_UTF8 + if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f]; +#endif + } +return cc; +} + +static uschar *compile_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; +uschar opcode; +uschar type; +int arg1 = -1, arg2 = -1; +uschar* end; +jump_list *nomatch = NULL; +struct sljit_jump *jump = NULL; +struct sljit_label *label; + +PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); + +switch(opcode) + { + case OP_STAR: + case OP_PLUS: + case OP_UPTO: + case OP_CRRANGE: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + if (opcode == OP_STAR || opcode == OP_UPTO) + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + } + else + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + if (opcode == OP_UPTO || opcode == OP_CRRANGE) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); + + label = LABEL(); + compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); + if (opcode == OP_UPTO || opcode == OP_CRRANGE) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + if (opcode == OP_CRRANGE && arg2 > 0) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label); + if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0)) + jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + } + + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + if (jump != NULL) + JUMPHERE(jump); + } + else + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + label = LABEL(); + compile_char1_hotpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) + { + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + JUMPTO(SLJIT_JUMP, label); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + } + set_jumps(nomatch, LABEL()); + if (opcode == OP_PLUS || opcode == OP_CRRANGE) + add_jump(compiler, &fallback->topfallbacks, + CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); + break; + + case OP_MINSTAR: + case OP_MINPLUS: + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode == OP_MINPLUS) + add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); + FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); + break; + + case OP_MINUPTO: + case OP_CRMINRANGE: + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + if (opcode == OP_CRMINRANGE) + add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); + FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); + break; + + case OP_QUERY: + case OP_MINQUERY: + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode == OP_QUERY) + compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); + FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); + break; + + case OP_EXACT: + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); + label = LABEL(); + compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + break; + + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSUPTO: + if (opcode != OP_POSSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + label = LABEL(); + compile_char1_hotpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + if (opcode != OP_POSUPTO) + { + if (opcode == OP_POSPLUS) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2); + JUMPTO(SLJIT_JUMP, label); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + } + set_jumps(nomatch, LABEL()); + if (opcode == OP_POSPLUS) + add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + break; + + case OP_POSQUERY: + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + compile_char1_hotpath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + set_jumps(nomatch, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +decrease_call_count(common); +return end; +} + +static SLJIT_INLINE uschar *compile_fail_accept_hotpath(compiler_common *common, uschar *cc, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; + +PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL); + +if (*cc == OP_FAIL) + { + add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); + return cc + 1; + } + +if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL) + { + /* No need to check notempty conditions. */ + if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->acceptlabel); + return cc + 1; + } + +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0))); +else + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); +add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); +else + CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); +else + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); +add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); +return cc + 1; +} + +static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1); + +/* Data will be discarded anyway... */ +if (common->currententry != NULL) + return cc + 3; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); +offset <<= 1; +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); +return cc + 3; +} + +static void compile_hotpath(compiler_common *common, uschar *cc, uschar *ccend, fallback_common *parent) +{ +DEFINE_COMPILER; +fallback_common *fallback; + +while (cc < ccend) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_NOTPROP: + case OP_PROP: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_NOT: + case OP_NOTI: + case OP_REVERSE: + cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); + break; + + case OP_SET_SOM: + PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); + allocate_stack(common, 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + cc++; + break; + + case OP_CHAR: + case OP_CHARI: + cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + cc = compile_iterator_hotpath(common, cc, parent); + break; + + case OP_CLASS: + case OP_NCLASS: + if (cc[33] >= OP_CRSTAR && cc[33] <= OP_CRMINRANGE) + cc = compile_iterator_hotpath(common, cc, parent); + else + cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); + break; + +#ifdef SUPPORT_UTF8 + case OP_XCLASS: + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) + cc = compile_iterator_hotpath(common, cc, parent); + else + cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); + break; +#endif + + case OP_REF: + case OP_REFI: + if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE) + cc = compile_ref_iterator_hotpath(common, cc, parent); + else + cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE); + break; + + case OP_RECURSE: + cc = compile_recurse_hotpath(common, cc, parent); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc); + cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE); + break; + + case OP_BRAMINZERO: + PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc); + cc = bracketend(cc + 1); + if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); + } + FALLBACK_AS(braminzero_fallback)->hotpath = LABEL(); + if (cc[1] > OP_ASSERTBACK_NOT) + decrease_call_count(common); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + cc = compile_bracket_hotpath(common, cc, parent); + break; + + case OP_BRAZERO: + if (cc[1] > OP_ASSERTBACK_NOT) + cc = compile_bracket_hotpath(common, cc, parent); + else + { + PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc); + cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE); + } + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + cc = compile_bracketpos_hotpath(common, cc, parent); + break; + + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + cc = compile_fail_accept_hotpath(common, cc, parent); + break; + + case OP_CLOSE: + cc = compile_close_hotpath(common, cc); + break; + + case OP_SKIPZERO: + cc = bracketend(cc + 1); + break; + + default: + SLJIT_ASSERT_STOP(); + return; + } + if (cc == NULL) + return; + } +SLJIT_ASSERT(cc == ccend); +} + +#undef PUSH_FALLBACK +#undef PUSH_FALLBACK_NOVALUE +#undef FALLBACK_AS + +#define COMPILE_FALLBACKPATH(current) \ + do \ + { \ + compile_fallbackpath(common, (current)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + } \ + while (0) + +#define CURRENT_AS(type) ((type*)current) + +static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; +uschar *cc = current->cc; +uschar opcode; +uschar type; +int arg1 = -1, arg2 = -1; +struct sljit_label *label = NULL; +struct sljit_jump *jump = NULL; + +cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); + +switch(opcode) + { + case OP_STAR: + case OP_PLUS: + case OP_UPTO: + case OP_CRRANGE: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + set_jumps(current->topfallbacks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); + } + else + { + if (opcode == OP_STAR || opcode == OP_UPTO) + arg2 = 0; + else if (opcode == OP_PLUS) + arg2 = 1; + jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1); + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + skip_char_back(common); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); + if (opcode == OP_PLUS || opcode == OP_CRRANGE) + set_jumps(current->topfallbacks, LABEL()); + JUMPHERE(jump); + free_stack(common, 2); + } + break; + + case OP_MINSTAR: + case OP_MINPLUS: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (opcode == OP_MINPLUS) + { + set_jumps(current->topfallbacks, LABEL()); + current->topfallbacks = NULL; + } + compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); + set_jumps(current->topfallbacks, LABEL()); + free_stack(common, 1); + break; + + case OP_MINUPTO: + case OP_CRMINRANGE: + if (opcode == OP_CRMINRANGE) + { + set_jumps(current->topfallbacks, LABEL()); + current->topfallbacks = NULL; + label = LABEL(); + } + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + + if (opcode == OP_CRMINRANGE) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); + + if (opcode == OP_CRMINRANGE && arg1 == 0) + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); + else + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath); + + set_jumps(current->topfallbacks, LABEL()); + free_stack(common, 2); + break; + + case OP_QUERY: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topfallbacks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); + JUMPHERE(jump); + free_stack(common, 1); + break; + + case OP_MINQUERY: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); + set_jumps(current->topfallbacks, LABEL()); + JUMPHERE(jump); + free_stack(common, 1); + break; + + case OP_EXACT: + case OP_POSPLUS: + set_jumps(current->topfallbacks, LABEL()); + break; + + case OP_POSSTAR: + case OP_POSQUERY: + case OP_POSUPTO: + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } +} + +static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; +uschar *cc = current->cc; +uschar type; + +type = cc[3]; +if ((type & 0x1) == 0) + { + set_jumps(current->topfallbacks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); + return; + } + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); +set_jumps(current->topfallbacks, LABEL()); +free_stack(common, 2); +} + +static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; + +set_jumps(current->topfallbacks, LABEL()); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +free_stack(common, 1); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); +} + +static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; +uschar *cc = current->cc; +uschar bra = OP_BRA; +struct sljit_jump *brajump = NULL; + +SLJIT_ASSERT(*cc != OP_BRAMINZERO); +if (*cc == OP_BRAZERO) + { + bra = *cc; + cc++; + } + +if (bra == OP_BRAZERO) + { + SLJIT_ASSERT(current->topfallbacks == NULL); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + +if (CURRENT_AS(assert_fallback)->framesize < 0) + { + set_jumps(current->topfallbacks, LABEL()); + + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath); + free_stack(common, 1); + } + return; + } + +if (bra == OP_BRAZERO) + { + if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath); + free_stack(common, 1); + return; + } + free_stack(common, 1); + brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w)); + + set_jumps(current->topfallbacks, LABEL()); + } +else + set_jumps(current->topfallbacks, LABEL()); + +if (bra == OP_BRAZERO) + { + /* We know there is enough place on the stack. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath); + JUMPHERE(brajump); + } +} + +static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; +int opcode; +int offset = 0; +int localptr = CURRENT_AS(bracket_fallback)->localptr; +int stacksize; +int count; +uschar *cc = current->cc; +uschar *ccbegin; +uschar *ccprev; +jump_list *jumplist = NULL; +jump_list *jumplistitem = NULL; +uschar bra = OP_BRA; +uschar ket; +assert_fallback *assert; +BOOL has_alternatives; +struct sljit_jump *brazero = NULL; +struct sljit_jump *once = NULL; +struct sljit_jump *cond = NULL; +struct sljit_label *rminlabel = NULL; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + } + +opcode = *cc; +ccbegin = cc; +ket = *(bracketend(ccbegin) - 1 - LINK_SIZE); +cc += GET(cc, 1); +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL; +if (opcode == OP_CBRA || opcode == OP_SCBRA) + offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +if (ket == OP_KETRMAX) + { + if (bra != OP_BRAZERO) + free_stack(common, 1); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } + } +else if (ket == OP_KETRMIN) + { + if (bra != OP_BRAMINZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (opcode >= OP_SBRA || opcode == OP_ONCE) + { + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0) + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath); + } + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath); + } + rminlabel = LABEL(); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } + +if (SLJIT_UNLIKELY(opcode == OP_ONCE)) + { + if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + once = JUMP(SLJIT_JUMP); + } +else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + if (has_alternatives) + { + /* Always exactly one alternative. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + + jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); + if (SLJIT_UNLIKELY(!jumplistitem)) + return; + jumplist = jumplistitem; + jumplistitem->next = NULL; + jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1); + } + } +else if (*cc == OP_ALT) + { + /* Build a jump list. Get the last successfully matched branch index. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + count = 1; + do + { + /* Append as the last item. */ + if (jumplist != NULL) + { + jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list)); + jumplistitem = jumplistitem->next; + } + else + { + jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); + jumplist = jumplistitem; + } + + if (SLJIT_UNLIKELY(!jumplistitem)) + return; + + jumplistitem->next = NULL; + jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++); + cc += GET(cc, 1); + } + while (*cc == OP_ALT); + + cc = ccbegin + GET(ccbegin, 1); + } + +COMPILE_FALLBACKPATH(current->top); +if (current->topfallbacks) + set_jumps(current->topfallbacks, LABEL()); + +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + /* Conditional block always has at most one alternative. */ + if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) + { + SLJIT_ASSERT(has_alternatives); + assert = CURRENT_AS(bracket_fallback)->u.assert; + if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); + } + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL()); + } + else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL) + { + SLJIT_ASSERT(has_alternatives); + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL()); + } + else + SLJIT_ASSERT(!has_alternatives); + } + +if (has_alternatives) + { + count = 1; + do + { + current->top = NULL; + current->topfallbacks = NULL; + current->nextfallbacks = NULL; + if (*cc == OP_ALT) + { + ccprev = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + if (opcode != OP_COND && opcode != OP_SCOND) + { + if (localptr != 0 && opcode != OP_ONCE) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + compile_hotpath(common, ccprev, cc, current); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + } + + /* Instructions after the current alternative is succesfully matched. */ + /* There is a similar code in compile_bracket_hotpath. */ + if (opcode == OP_ONCE) + { + if (CURRENT_AS(bracket_fallback)->u.framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + /* TMP2 which is set here used by OP_KETRMAX below. */ + if (ket == OP_KETRMAX) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (ket == OP_KETRMIN) + { + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); + } + } + else + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w)); + if (ket == OP_KETRMAX) + { + /* TMP2 which is set here used by OP_KETRMAX below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + } + } + + stacksize = 0; + if (opcode != OP_ONCE) + stacksize++; + if (ket != OP_KET || bra != OP_BRA) + stacksize++; + + if (stacksize > 0) { + if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0) + allocate_stack(common, stacksize); + else + { + /* We know we have place at least for one item on the top of the stack. */ + SLJIT_ASSERT(stacksize == 1); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + } + + stacksize = 0; + if (ket != OP_KET || bra != OP_BRA) + { + if (ket != OP_KET) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); + + if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); + } + + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath); + + if (opcode != OP_ONCE) + { + SLJIT_ASSERT(jumplist); + JUMPHERE(jumplist->jump); + jumplist = jumplist->next; + } + + COMPILE_FALLBACKPATH(current->top); + if (current->topfallbacks) + set_jumps(current->topfallbacks, LABEL()); + SLJIT_ASSERT(!current->nextfallbacks); + } + while (*cc == OP_ALT); + SLJIT_ASSERT(!jumplist); + + if (cond != NULL) + { + SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); + assert = CURRENT_AS(bracket_fallback)->u.assert; + if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) + + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); + } + JUMPHERE(cond); + } + + /* Free the STR_PTR. */ + if (localptr == 0) + free_stack(common, 1); + } + +if (offset != 0) + { + /* Using both tmp register is better for instruction scheduling. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + } +else if (opcode == OP_ONCE) + { + cc = ccbegin + GET(ccbegin, 1); + if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) + { + /* Reset head and drop saved frame. */ + stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; + free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize); + } + else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) + { + /* The STR_PTR must be released. */ + free_stack(common, 1); + } + + JUMPHERE(once); + /* Restore previous localptr */ + if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w)); + else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* See the comment below. */ + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + } + +if (ket == OP_KETRMAX) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath); + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath); + JUMPHERE(brazero); + } + free_stack(common, 1); + } +else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + /* OP_ONCE removes everything in case of a fallback, so we don't + need to explicitly release the STR_PTR. The extra release would + affect badly the free_stack(2) above. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel); + if (opcode == OP_ONCE) + free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); + else if (bra == OP_BRAMINZERO) + free_stack(common, 1); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath); + JUMPHERE(brazero); + } +} + +static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; +int offset; +struct sljit_jump *jump; + +if (CURRENT_AS(bracketpos_fallback)->framesize < 0) + { + if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) + { + offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + } + set_jumps(current->topfallbacks, LABEL()); + free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); + return; + } + +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr); +add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + +if (current->topfallbacks) + { + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topfallbacks, LABEL()); + /* Drop the stack frame. */ + free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); + JUMPHERE(jump); + } +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w)); +} + +static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +assert_fallback fallback; + +current->top = NULL; +current->topfallbacks = NULL; +current->nextfallbacks = NULL; +if (current->cc[1] > OP_ASSERTBACK_NOT) + { + /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */ + compile_bracket_hotpath(common, current->cc, current); + compile_bracket_fallbackpath(common, current->top); + } +else + { + memset(&fallback, 0, sizeof(fallback)); + fallback.common.cc = current->cc; + fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath; + /* Manual call of compile_assert_hotpath. */ + compile_assert_hotpath(common, current->cc, &fallback, FALSE); + } +SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks); +} + +static void compile_fallbackpath(compiler_common *common, struct fallback_common *current) +{ +DEFINE_COMPILER; + +while (current) + { + if (current->nextfallbacks != NULL) + set_jumps(current->nextfallbacks, LABEL()); + switch(*current->cc) + { + case OP_SET_SOM: + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + compile_iterator_fallbackpath(common, current); + break; + + case OP_REF: + case OP_REFI: + compile_ref_iterator_fallbackpath(common, current); + break; + + case OP_RECURSE: + compile_recurse_fallbackpath(common, current); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + compile_assert_fallbackpath(common, current); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + compile_bracket_fallbackpath(common, current); + break; + + case OP_BRAZERO: + if (current->cc[1] > OP_ASSERTBACK_NOT) + compile_bracket_fallbackpath(common, current); + else + compile_assert_fallbackpath(common, current); + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + compile_bracketpos_fallbackpath(common, current); + break; + + case OP_BRAMINZERO: + compile_braminzero_fallbackpath(common, current); + break; + + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + set_jumps(current->topfallbacks, LABEL()); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + current = current->prev; + } +} + +static SLJIT_INLINE void compile_recurse(compiler_common *common) +{ +DEFINE_COMPILER; +uschar *cc = common->start + common->currententry->start; +uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2); +uschar *ccend = bracketend(cc); +int localsize = get_localsize(common, ccbegin, ccend); +int framesize = get_framesize(common, cc, TRUE); +int alternativesize; +BOOL needsframe; +fallback_common altfallback; +struct sljit_jump *jump; + +SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); +needsframe = framesize >= 0; +if (!needsframe) + framesize = 0; +alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; + +SLJIT_ASSERT(common->currententry->entry == NULL); +common->currententry->entry = LABEL(); +set_jumps(common->currententry->calls, common->currententry->entry); + +sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize); +allocate_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); +copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0); +if (needsframe) + init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE); + +if (alternativesize > 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +memset(&altfallback, 0, sizeof(fallback_common)); +common->acceptlabel = NULL; +common->accept = NULL; +altfallback.cc = ccbegin; +cc += GET(cc, 1); +while (1) + { + altfallback.top = NULL; + altfallback.topfallbacks = NULL; + + if (altfallback.cc != ccbegin) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + compile_hotpath(common, altfallback.cc, cc, &altfallback); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + + compile_fallbackpath(common, altfallback.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + set_jumps(altfallback.topfallbacks, LABEL()); + + if (*cc != OP_ALT) + break; + + altfallback.cc = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } +/* None of them matched. */ +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_JUMP); + +set_jumps(common->accept, LABEL()); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD); +if (needsframe) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0); + } +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + +JUMPHERE(jump); +copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize); +free_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); +OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0); +sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); +} + +#undef COMPILE_FALLBACKPATH +#undef CURRENT_AS + +void +_pcre_jit_compile(const real_pcre *re, pcre_extra *extra) +{ +struct sljit_compiler *compiler; +fallback_common rootfallback; +compiler_common common_data; +compiler_common *common = &common_data; +const uschar *tables = re->tables; +pcre_study_data *study; +uschar *ccend; +executable_function *function; +void *executable_func; +sljit_uw executable_size; +struct sljit_label *leave; +struct sljit_label *mainloop = NULL; +struct sljit_label *empty_match_found; +struct sljit_label *empty_match_fallback; +struct sljit_jump *alloc_error; +struct sljit_jump *reqbyte_notfound = NULL; +struct sljit_jump *empty_match; + +SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); +study = extra->study_data; + +if (!tables) + tables = _pcre_default_tables; + +memset(&rootfallback, 0, sizeof(fallback_common)); +rootfallback.cc = (uschar *)re + re->name_table_offset + re->name_count * re->name_entry_size; + +common->compiler = NULL; +common->start = rootfallback.cc; +common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); +common->fcc = tables + fcc_offset; +common->lcc = (sljit_w)(tables + lcc_offset); +common->nltype = NLTYPE_FIXED; +switch(re->options & PCRE_NEWLINE_BITS) + { + case 0: + /* Compile-time default */ + switch (NEWLINE) + { + case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; + case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + default: common->newline = NEWLINE; break; + } + break; + case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; + case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; + case PCRE_NEWLINE_CR+ + PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; + case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + default: return; + } +if ((re->options & PCRE_BSR_ANYCRLF) != 0) + common->bsr_nltype = NLTYPE_ANYCRLF; +else if ((re->options & PCRE_BSR_UNICODE) != 0) + common->bsr_nltype = NLTYPE_ANY; +else + { +#ifdef BSR_ANYCRLF + common->bsr_nltype = NLTYPE_ANYCRLF; +#else + common->bsr_nltype = NLTYPE_ANY; +#endif + } +common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; +common->ctypes = (sljit_w)(tables + ctypes_offset); +common->name_table = (sljit_w)re + re->name_table_offset; +common->name_count = re->name_count; +common->name_entry_size = re->name_entry_size; +common->acceptlabel = NULL; +common->stubs = NULL; +common->entries = NULL; +common->currententry = NULL; +common->accept = NULL; +common->calllimit = NULL; +common->stackalloc = NULL; +common->revertframes = NULL; +common->wordboundary = NULL; +common->anynewline = NULL; +common->hspace = NULL; +common->vspace = NULL; +common->casefulcmp = NULL; +common->caselesscmp = NULL; +common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; +#ifdef SUPPORT_UTF8 +common->utf8 = (re->options & PCRE_UTF8) != 0; +#ifdef SUPPORT_UCP +common->useucp = (re->options & PCRE_UCP) != 0; +#endif +common->utf8readchar = NULL; +common->utf8readtype8 = NULL; +#endif +#ifdef SUPPORT_UCP +common->getucd = NULL; +#endif +ccend = bracketend(rootfallback.cc); +SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); +common->localsize = get_localspace(common, rootfallback.cc, ccend); +if (common->localsize < 0) + return; +common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); +if (common->localsize > SLJIT_MAX_LOCAL_SIZE) + return; +common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); +if (!common->localptrs) + return; +memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); +set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); + +compiler = sljit_create_compiler(); +if (!compiler) + { + SLJIT_FREE(common->localptrs); + return; + } +common->compiler = compiler; + +/* Main pcre_jit_exec entry. */ +sljit_emit_enter(compiler, 1, 5, 5, common->localsize); + +/* Register init. */ +reset_ovector(common, (re->top_bracket + 1) * 2); +if ((re->flags & PCRE_REQCHSET) != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0); + +OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); + +/* Main part of the matching */ +if ((re->options & PCRE_ANCHORED) == 0) + { + mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); + /* Forward search if possible. */ + if ((re->flags & PCRE_FIRSTSET) != 0) + fast_forward_first_byte(common, re->first_byte, (re->options & PCRE_FIRSTLINE) != 0); + else if ((re->flags & PCRE_STARTLINE) != 0) + fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); + else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) + fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); + } +if ((re->flags & PCRE_REQCHSET) != 0) + reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0); + +/* Store the current STR_PTR in OVECTOR(0). */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); +/* Copy the limit of allowed recursions. */ +OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); + +compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + +empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); +empty_match_found = LABEL(); + +common->acceptlabel = LABEL(); +if (common->accept != NULL) + set_jumps(common->accept, common->acceptlabel); + +/* This means we have a match. Update the ovector. */ +copy_ovector(common, re->top_bracket + 1); +leave = LABEL(); +sljit_emit_return(compiler, SLJIT_UNUSED, 0); + +empty_match_fallback = LABEL(); +compile_fallbackpath(common, rootfallback.top); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + +SLJIT_ASSERT(rootfallback.prev == NULL); + +/* Check we have remaining characters. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + +if ((re->options & PCRE_ANCHORED) == 0) + { + if ((re->options & PCRE_FIRSTLINE) == 0) + { + if (study != NULL && study->minlength > 1) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); + } + else + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); + } + else + { + if (study != NULL && study->minlength > 1) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); + JUMPTO(SLJIT_C_ZERO, mainloop); + } + else + CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop); + } + } + +if (reqbyte_notfound != NULL) + JUMPHERE(reqbyte_notfound); +/* Copy OVECTOR(1) to OVECTOR(0) */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); +JUMPTO(SLJIT_JUMP, leave); + +flush_stubs(common); + +JUMPHERE(empty_match); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); +CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); +CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); +JUMPTO(SLJIT_JUMP, empty_match_fallback); + +common->currententry = common->entries; +while (common->currententry != NULL) + { + /* Might add new entries. */ + compile_recurse(common); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + flush_stubs(common); + common->currententry = common->currententry->next; + } + +/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ +/* This is a (really) rare case. */ +set_jumps(common->stackalloc, LABEL()); +/* RETURN_ADDR is not a saved register. */ +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); +OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); + +sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); +alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + +/* Allocation failed. */ +JUMPHERE(alloc_error); +/* We break the return address cache here, but this is a really rare case. */ +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); +JUMPTO(SLJIT_JUMP, leave); + +/* Call limit reached. */ +set_jumps(common->calllimit, LABEL()); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); +JUMPTO(SLJIT_JUMP, leave); + +if (common->revertframes != NULL) + { + set_jumps(common->revertframes, LABEL()); + do_revertframes(common); + } +if (common->wordboundary != NULL) + { + set_jumps(common->wordboundary, LABEL()); + check_wordboundary(common); + } +if (common->anynewline != NULL) + { + set_jumps(common->anynewline, LABEL()); + check_anynewline(common); + } +if (common->hspace != NULL) + { + set_jumps(common->hspace, LABEL()); + check_hspace(common); + } +if (common->vspace != NULL) + { + set_jumps(common->vspace, LABEL()); + check_vspace(common); + } +if (common->casefulcmp != NULL) + { + set_jumps(common->casefulcmp, LABEL()); + do_casefulcmp(common); + } +if (common->caselesscmp != NULL) + { + set_jumps(common->caselesscmp, LABEL()); + do_caselesscmp(common); + } +#ifdef SUPPORT_UTF8 +if (common->utf8readchar != NULL) + { + set_jumps(common->utf8readchar, LABEL()); + do_utf8readchar(common); + } +if (common->utf8readtype8 != NULL) + { + set_jumps(common->utf8readtype8, LABEL()); + do_utf8readtype8(common); + } +#endif +#ifdef SUPPORT_UCP +if (common->getucd != NULL) + { + set_jumps(common->getucd, LABEL()); + do_getucd(common); + } +#endif + +SLJIT_FREE(common->localptrs); +executable_func = sljit_generate_code(compiler); +executable_size = sljit_get_generated_code_size(compiler); +sljit_free_compiler(compiler); +if (executable_func == NULL) + return; + +function = SLJIT_MALLOC(sizeof(executable_function)); +if (function == NULL) + { + /* This case is highly unlikely since we just recently + freed a lot of memory. Although not impossible. */ + sljit_free_code(executable_func); + return; + } + +function->executable_func = executable_func; +function->executable_size = executable_size; +function->callback = NULL; +function->userdata = NULL; +extra->executable_jit = function; +extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; +} + +static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function) +{ +union { + void* executable_func; + jit_function call_executable_func; +} convert_executable_func; +uschar local_area[LOCAL_SPACE_SIZE]; +struct sljit_stack local_stack; + +local_stack.top = (sljit_w)&local_area; +local_stack.base = local_stack.top; +local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; +local_stack.max_limit = local_stack.limit; +arguments->stack = &local_stack; +convert_executable_func.executable_func = function->executable_func; +return convert_executable_func.call_executable_func(arguments); +} + +int +_pcre_jit_exec(const real_pcre *re, void *executable_func, + PCRE_SPTR subject, int length, int start_offset, int options, + int match_limit, int *offsets, int offsetcount) +{ +executable_function *function = (executable_function*)executable_func; +union { + void* executable_func; + jit_function call_executable_func; +} convert_executable_func; +jit_arguments arguments; +int maxoffsetcount; +int retval; + +/* Sanity checks should be handled by pcre_exec. */ +arguments.stack = NULL; +arguments.str = subject + start_offset; +arguments.begin = subject; +arguments.end = subject + length; +arguments.calllimit = match_limit; /* JIT decreases this value less times. */ +arguments.notbol = (options & PCRE_NOTBOL) != 0; +arguments.noteol = (options & PCRE_NOTEOL) != 0; +arguments.notempty = (options & PCRE_NOTEMPTY) != 0; +arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; +arguments.offsets = offsets; + +/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of +the output vector for storing captured strings, with the remainder used as +workspace. We don't need the workspace here. For compatibility, we limit the +number of captured strings in the same way as pcre_exec(), so that the user +gets the same result with and without JIT. */ + +offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3; +maxoffsetcount = (re->top_bracket + 1) * 2; +if (offsetcount > maxoffsetcount) + offsetcount = maxoffsetcount; +arguments.offsetcount = offsetcount; + +if (function->callback) + arguments.stack = (struct sljit_stack*)function->callback(function->userdata); +else + arguments.stack = (struct sljit_stack*)function->userdata; + +if (arguments.stack == NULL) + retval = jit_machine_stack_exec(&arguments, function); +else + { + convert_executable_func.executable_func = function->executable_func; + retval = convert_executable_func.call_executable_func(&arguments); + } + +if (retval * 2 > offsetcount) + retval = 0; +return retval; +} + +void +_pcre_jit_free(void *executable_func) +{ +executable_function *function = (executable_function*)executable_func; +sljit_free_code(function->executable_func); +SLJIT_FREE(function); +} + +int +_pcre_jit_get_size(void *executable_func) +{ +return ((executable_function*)executable_func)->executable_size; +} + +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +{ +if (startsize < 1 || maxsize < 1) + return NULL; +if (startsize > maxsize) + startsize = maxsize; +startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); +maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); +return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize); +} + +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +{ +sljit_free_stack((struct sljit_stack*)stack); +} + +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +{ +executable_function *function; +if (extra != NULL && + (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + { + function = (executable_function*)extra->executable_jit; + function->callback = callback; + function->userdata = userdata; + } +} + +#else /* SUPPORT_JIT */ + +/* These are dummy functions to avoid linking errors when JIT support is not +being compiled. */ + +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +{ +(void)startsize; +(void)maxsize; +return NULL; +} + +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +{ +(void)stack; +} + +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +{ +(void)extra; +(void)callback; +(void)userdata; +} + +#endif + +/* End of pcre_jit_compile.c */ diff --git a/harbour/src/3rd/pcre/pcreprni.h b/harbour/src/3rd/pcre/pcreprni.h index c7d8629477..5074cd5f92 100644 --- a/harbour/src/3rd/pcre/pcreprni.h +++ b/harbour/src/3rd/pcre/pcreprni.h @@ -180,6 +180,7 @@ utf8 = (options & PCRE_UTF8) != 0; for(;;) { uschar *ccode; + const char *flag = " "; int c; int extra = 0; @@ -214,10 +215,6 @@ for(;;) fprintf(f, "------------------------------------------------------------------\n"); return; - case OP_OPT: - fprintf(f, " %.2x %s", code[1], OP_names[*code]); - break; - case OP_CHAR: fprintf(f, " "); do @@ -229,28 +226,33 @@ for(;;) fprintf(f, "\n"); continue; - case OP_CHARNC: - fprintf(f, " NC "); + case OP_CHARI: + fprintf(f, " /i "); do { code++; code += 1 + print_char(f, code, utf8); } - while (*code == OP_CHARNC); + while (*code == OP_CHARI); fprintf(f, "\n"); continue; case OP_CBRA: + case OP_CBRAPOS: case OP_SCBRA: + case OP_SCBRAPOS: if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); else fprintf(f, " "); fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE)); break; case OP_BRA: + case OP_BRAPOS: case OP_SBRA: + case OP_SBRAPOS: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: case OP_ALT: case OP_KET: case OP_ASSERT: @@ -258,6 +260,7 @@ for(;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_ONCE_NC: case OP_COND: case OP_SCOND: case OP_REVERSE: @@ -295,6 +298,17 @@ for(;;) fprintf(f, " Cond def"); break; + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + flag = "/i"; + /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -313,7 +327,7 @@ for(;;) case OP_TYPEQUERY: case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: - fprintf(f, " "); + fprintf(f, " %s ", flag); if (*code >= OP_TYPESTAR) { fprintf(f, "%s", OP_names[code[1]]); @@ -327,17 +341,23 @@ for(;;) fprintf(f, "%s", OP_names[*code]); break; + case OP_EXACTI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + flag = "/i"; + /* Fall through */ case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: - fprintf(f, " "); + fprintf(f, " %s ", flag); extra = print_char(f, code+3, utf8); fprintf(f, "{"); - if (*code != OP_EXACT) fprintf(f, "0,"); + if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_MINUPTO) fprintf(f, "?"); - else if (*code == OP_POSUPTO) fprintf(f, "+"); + if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?"); + else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+"); break; case OP_TYPEEXACT: @@ -357,12 +377,27 @@ for(;;) else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); break; + case OP_NOTI: + flag = "/i"; + /* Fall through */ case OP_NOT: c = code[1]; - if (PRINTABLE(c)) fprintf(f, " [^%c]", c); - else fprintf(f, " [^\\x%02x]", c); + if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c); + else fprintf(f, " %s [^\\x%02x]", flag, c); break; + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + flag = "/i"; + /* Fall through */ + case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPOSSTAR: @@ -373,22 +408,30 @@ for(;;) case OP_NOTMINQUERY: case OP_NOTPOSQUERY: c = code[1]; - if (PRINTABLE(c)) fprintf(f, " [^%c]", c); - else fprintf(f, " [^\\x%02x]", c); + if (PRINTABLE(c)) fprintf(f, " %s [^%c]", flag, c); + else fprintf(f, " %s [^\\x%02x]", flag, c); fprintf(f, "%s", OP_names[*code]); break; + case OP_NOTEXACTI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + flag = "/i"; + /* Fall through */ + case OP_NOTEXACT: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: c = code[3]; - if (PRINTABLE(c)) fprintf(f, " [^%c]{", c); - else fprintf(f, " [^\\x%02x]{", c); - if (*code != OP_NOTEXACT) fprintf(f, "0,"); + if (PRINTABLE(c)) fprintf(f, " %s [^%c]{", flag, c); + else fprintf(f, " %s [^\\x%02x]{", flag, c); + if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_NOTMINUPTO) fprintf(f, "?"); - else if (*code == OP_NOTPOSUPTO) fprintf(f, "+"); + if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); + else + if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); break; case OP_RECURSE: @@ -397,8 +440,11 @@ for(;;) fprintf(f, "%s", OP_names[*code]); break; + case OP_REFI: + flag = "/i"; + /* Fall through */ case OP_REF: - fprintf(f, " \\%d", GET2(code,1)); + fprintf(f, " %s \\%d", flag, GET2(code,1)); ccode = code + _pcre_OP_lengths[*code]; goto CLASS_REF_REPEAT; @@ -542,25 +588,23 @@ for(;;) break; case OP_THEN: - if (print_lengths) - fprintf(f, " %s %d", OP_names[*code], GET(code, 1)); - else - fprintf(f, " %s", OP_names[*code]); + fprintf(f, " %s", OP_names[*code]); break; case OP_THEN_ARG: - if (print_lengths) - fprintf(f, " %s %d %s", OP_names[*code], GET(code, 1), - code + 2 + LINK_SIZE); - else - fprintf(f, " %s %s", OP_names[*code], code + 2 + LINK_SIZE); - extra += code[1+LINK_SIZE]; + fprintf(f, " %s %s", OP_names[*code], code + 2); + extra += code[1]; break; - /* Anything else is just an item with no data*/ + case OP_CIRCM: + case OP_DOLLM: + flag = "/m"; + /* Fall through */ + + /* Anything else is just an item with no data, but possibly a flag. */ default: - fprintf(f, " %s", OP_names[*code]); + fprintf(f, " %s %s", flag, OP_names[*code]); break; } diff --git a/harbour/src/3rd/pcre/pcrestud.c b/harbour/src/3rd/pcre/pcrestud.c index 7acdb5deb4..9ac6ae7897 100644 --- a/harbour/src/3rd/pcre/pcrestud.c +++ b/harbour/src/3rd/pcre/pcrestud.c @@ -52,7 +52,7 @@ supporting functions. */ /* Returns from set_start_bits() */ -enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE }; +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; @@ -66,17 +66,20 @@ 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 uschar *code, const uschar *startcode, int options, + int recurse_depth) { int length = -1; BOOL utf8 = (options & PCRE_UTF8) != 0; @@ -84,7 +87,8 @@ BOOL had_recurse = FALSE; register int branchlength = 0; register uschar *cc = (uschar *)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 += 2; /* 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. */ @@ -118,26 +122,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; @@ -160,14 +178,15 @@ 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]; @@ -177,6 +196,7 @@ for (;;) case OP_BRAZERO: case OP_BRAMINZERO: + case OP_BRAPOSZERO: case OP_SKIPZERO: cc += _pcre_OP_lengths[*cc]; do cc += GET(cc, 1); while (*cc == OP_ALT); @@ -186,14 +206,21 @@ 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 @@ -212,7 +239,9 @@ 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 @@ -249,14 +278,17 @@ 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 @@ -337,6 +369,7 @@ 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)); @@ -347,7 +380,10 @@ 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; @@ -364,6 +400,12 @@ for (;;) cc++; break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + cc++; + break; + case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(cc, 1); @@ -378,36 +420,68 @@ 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; 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: + case OP_NOTPOSQUERYI: + cc += _pcre_OP_lengths[op]; #ifdef SUPPORT_UTF8 if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; @@ -419,20 +493,27 @@ for (;;) case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: + case OP_THEN_ARG: cc += _pcre_OP_lengths[op] + cc[1]; break; - case OP_THEN_ARG: - cc += _pcre_OP_lengths[op] + cc[1+LINK_SIZE]; - break; + /* The remaining opcodes are just skipped over. */ - /* 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. */ - - default: + case OP_CLOSE: + case OP_COMMIT: + case OP_FAIL: + case OP_PRUNE: + case OP_SET_SOM: + case OP_SKIP: + case OP_THEN: cc += _pcre_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: + return -3; } } /* Control never gets here */ @@ -578,18 +659,18 @@ 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 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 uschar *code, uschar *start_bits, BOOL utf8, + compile_data *cd) { register int c; int yield = SSB_DONE; @@ -614,19 +695,106 @@ volatile int dummy; do { - const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE; BOOL try_next = TRUE; + const uschar *tcode = code + 1 + LINK_SIZE; + + if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += 2; 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: + case OP_XCLASS: return SSB_FAIL; + /* We can ignore word boundary tests. */ + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + tcode++; + break; + /* If we hit a bracket or a positive lookahead assertion, recurse to set bits from within the subpattern. If it can't find anything, we have to give up. If it finds some mandatory character(s), we are done for this @@ -636,10 +804,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, utf8, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; if (rc == SSB_DONE) try_next = FALSE; else { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); @@ -662,6 +835,7 @@ do case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: return SSB_CONTINUE; /* Skip over callout */ @@ -679,19 +853,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, utf8, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; /* ========================================================================= See the comment at the head of this function concerning the next line, which was an old fudge for the benefit of OS/2. @@ -717,7 +885,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, utf8); + 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, utf8); break; /* Single-char upto sets the bit and tries the next */ @@ -725,20 +902,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 + 3, FALSE, cd, utf8); + break; + + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + tcode = set_table_bit(start_bits, tcode + 3, TRUE, cd, utf8); break; /* At least one single char sets the bit and stops */ - case OP_EXACT: /* Fall through */ + case OP_EXACT: tcode += 2; - + /* 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, utf8); + try_next = FALSE; + break; + + case OP_EXACTI: + tcode += 2; + /* Fall through */ + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf8); try_next = FALSE; break; @@ -968,7 +1161,8 @@ do for (c = 0; c < 32; c++) start_bits[c] |= tcode[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; switch (*tcode) @@ -1004,6 +1198,8 @@ return yield; + + /************************************************* * Study a compiled expression * *************************************************/ @@ -1029,7 +1225,7 @@ pcre_study(const pcre *external_re, int options, const char **errorptr) int min; BOOL bits_set = FALSE; uschar start_bits[32]; -pcre_extra *extra; +pcre_extra *extra = NULL; pcre_study_data *study; const uschar *tables; uschar *code; @@ -1060,6 +1256,8 @@ 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; @@ -1075,55 +1273,116 @@ 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; + 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_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) != 0 +#endif + ) { - study->flags |= PCRE_STUDY_MAPPED; - memcpy(study->start_bits, start_bits, sizeof(start_bits)); - } + extra = (pcre_extra *)(pcre_malloc) + (sizeof(pcre_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(pcre_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(uschar)); + + /* 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) _pcre_jit_compile(re, extra); + if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0) + { + pcre_free_study(extra); + 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_extra block +Returns: nothing +*/ + +PCRE_EXP_DEFN void +pcre_free_study(pcre_extra *extra) +{ +#ifdef SUPPORT_JIT +if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + _pcre_jit_free(extra->executable_jit); +#endif +pcre_free(extra); +} + /* End of pcre_study.c */ diff --git a/harbour/src/3rd/pcre/pcretabs.c b/harbour/src/3rd/pcre/pcretabs.c index 6fca301417..6609b21fd1 100644 --- a/harbour/src/3rd/pcre/pcretabs.c +++ b/harbour/src/3rd/pcre/pcretabs.c @@ -87,6 +87,19 @@ const uschar _pcre_utf8_table4[] = { 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 }; +#ifdef SUPPORT_JIT +/* Full table of the number of extra bytes when the +character code is greater or equal than 0xc0. +See _pcre_utf8_table4 above. */ + +const uschar _pcre_utf8_char_sizes[] = { + 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,4,4,4,4, +}; +#endif + /* Table to translate from particular type value to the general value. */ const int _pcre_ucp_gentype[] = { @@ -100,6 +113,21 @@ const int _pcre_ucp_gentype[] = { ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; +#ifdef SUPPORT_JIT +/* This table reverses _pcre_ucp_gentype. We can save the cost +of a memory load. */ + +const int _pcre_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 + /* The pcre_utt[] table below translates Unicode property names into type and code values. It is searched by binary chop, so must be in collating sequence of name. Originally, the table contained pointers to the name strings in the first @@ -110,7 +138,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 @@ -123,8 +151,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" @@ -186,6 +216,7 @@ 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" @@ -260,8 +291,10 @@ const char _pcre_utt_names[] = STRING_Avestan0 STRING_Balinese0 STRING_Bamum0 + STRING_Batak0 STRING_Bengali0 STRING_Bopomofo0 + STRING_Brahmi0 STRING_Braille0 STRING_Buginese0 STRING_Buhid0 @@ -323,6 +356,7 @@ const char _pcre_utt_names[] = STRING_Lydian0 STRING_M0 STRING_Malayalam0 + STRING_Mandaic0 STRING_Mc0 STRING_Me0 STRING_Meetei_Mayek0 @@ -397,135 +431,138 @@ const ucp_type_table _pcre_utt[] = { { 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_Cham }, + { 136, PT_SC, ucp_Cherokee }, + { 145, PT_PC, ucp_Cn }, + { 148, PT_PC, ucp_Co }, + { 151, PT_SC, ucp_Common }, + { 158, PT_SC, ucp_Coptic }, + { 165, PT_PC, ucp_Cs }, + { 168, PT_SC, ucp_Cuneiform }, + { 178, PT_SC, ucp_Cypriot }, + { 186, PT_SC, ucp_Cyrillic }, + { 195, PT_SC, ucp_Deseret }, + { 203, PT_SC, ucp_Devanagari }, + { 214, PT_SC, ucp_Egyptian_Hieroglyphs }, + { 235, PT_SC, ucp_Ethiopic }, + { 244, PT_SC, ucp_Georgian }, + { 253, PT_SC, ucp_Glagolitic }, + { 264, PT_SC, ucp_Gothic }, + { 271, PT_SC, ucp_Greek }, + { 277, PT_SC, ucp_Gujarati }, + { 286, PT_SC, ucp_Gurmukhi }, + { 295, PT_SC, ucp_Han }, + { 299, PT_SC, ucp_Hangul }, + { 306, PT_SC, ucp_Hanunoo }, + { 314, PT_SC, ucp_Hebrew }, + { 321, PT_SC, ucp_Hiragana }, + { 330, PT_SC, ucp_Imperial_Aramaic }, + { 347, PT_SC, ucp_Inherited }, + { 357, PT_SC, ucp_Inscriptional_Pahlavi }, + { 379, PT_SC, ucp_Inscriptional_Parthian }, + { 402, PT_SC, ucp_Javanese }, + { 411, PT_SC, ucp_Kaithi }, + { 418, PT_SC, ucp_Kannada }, + { 426, PT_SC, ucp_Katakana }, + { 435, PT_SC, ucp_Kayah_Li }, + { 444, PT_SC, ucp_Kharoshthi }, + { 455, PT_SC, ucp_Khmer }, + { 461, PT_GC, ucp_L }, + { 463, PT_LAMP, 0 }, + { 466, PT_SC, ucp_Lao }, + { 470, PT_SC, ucp_Latin }, + { 476, PT_SC, ucp_Lepcha }, + { 483, PT_SC, ucp_Limbu }, + { 489, PT_SC, ucp_Linear_B }, + { 498, PT_SC, ucp_Lisu }, + { 503, PT_PC, ucp_Ll }, + { 506, PT_PC, ucp_Lm }, + { 509, PT_PC, ucp_Lo }, + { 512, PT_PC, ucp_Lt }, + { 515, PT_PC, ucp_Lu }, + { 518, PT_SC, ucp_Lycian }, + { 525, PT_SC, ucp_Lydian }, + { 532, PT_GC, ucp_M }, + { 534, PT_SC, ucp_Malayalam }, + { 544, PT_SC, ucp_Mandaic }, + { 552, PT_PC, ucp_Mc }, + { 555, PT_PC, ucp_Me }, + { 558, PT_SC, ucp_Meetei_Mayek }, + { 571, PT_PC, ucp_Mn }, + { 574, PT_SC, ucp_Mongolian }, + { 584, PT_SC, ucp_Myanmar }, + { 592, PT_GC, ucp_N }, + { 594, PT_PC, ucp_Nd }, + { 597, PT_SC, ucp_New_Tai_Lue }, + { 609, PT_SC, ucp_Nko }, + { 613, PT_PC, ucp_Nl }, + { 616, PT_PC, ucp_No }, + { 619, PT_SC, ucp_Ogham }, + { 625, PT_SC, ucp_Ol_Chiki }, + { 634, PT_SC, ucp_Old_Italic }, + { 645, PT_SC, ucp_Old_Persian }, + { 657, PT_SC, ucp_Old_South_Arabian }, + { 675, PT_SC, ucp_Old_Turkic }, + { 686, PT_SC, ucp_Oriya }, + { 692, PT_SC, ucp_Osmanya }, + { 700, PT_GC, ucp_P }, + { 702, PT_PC, ucp_Pc }, + { 705, PT_PC, ucp_Pd }, + { 708, PT_PC, ucp_Pe }, + { 711, PT_PC, ucp_Pf }, + { 714, PT_SC, ucp_Phags_Pa }, + { 723, PT_SC, ucp_Phoenician }, + { 734, PT_PC, ucp_Pi }, + { 737, PT_PC, ucp_Po }, + { 740, PT_PC, ucp_Ps }, + { 743, PT_SC, ucp_Rejang }, + { 750, PT_SC, ucp_Runic }, + { 756, PT_GC, ucp_S }, + { 758, PT_SC, ucp_Samaritan }, + { 768, PT_SC, ucp_Saurashtra }, + { 779, PT_PC, ucp_Sc }, + { 782, PT_SC, ucp_Shavian }, + { 790, PT_SC, ucp_Sinhala }, + { 798, PT_PC, ucp_Sk }, + { 801, PT_PC, ucp_Sm }, + { 804, PT_PC, ucp_So }, + { 807, PT_SC, ucp_Sundanese }, + { 817, PT_SC, ucp_Syloti_Nagri }, + { 830, PT_SC, ucp_Syriac }, + { 837, PT_SC, ucp_Tagalog }, + { 845, PT_SC, ucp_Tagbanwa }, + { 854, PT_SC, ucp_Tai_Le }, + { 861, PT_SC, ucp_Tai_Tham }, + { 870, PT_SC, ucp_Tai_Viet }, + { 879, PT_SC, ucp_Tamil }, + { 885, PT_SC, ucp_Telugu }, + { 892, PT_SC, ucp_Thaana }, + { 899, PT_SC, ucp_Thai }, + { 904, PT_SC, ucp_Tibetan }, + { 912, PT_SC, ucp_Tifinagh }, + { 921, PT_SC, ucp_Ugaritic }, + { 930, PT_SC, ucp_Vai }, + { 934, PT_ALNUM, 0 }, + { 938, PT_PXSPACE, 0 }, + { 942, PT_SPACE, 0 }, + { 946, PT_WORD, 0 }, + { 950, PT_SC, ucp_Yi }, + { 953, PT_GC, ucp_Z }, + { 955, PT_PC, ucp_Zl }, + { 958, PT_PC, ucp_Zp }, + { 961, PT_PC, ucp_Zs } }; const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table); diff --git a/harbour/src/3rd/pcre/pcreucd.c b/harbour/src/3rd/pcre/pcreucd.c index 61fac0c087..2ab63d2786 100644 --- a/harbour/src/3rd/pcre/pcreucd.c +++ b/harbour/src/3rd/pcre/pcreucd.c @@ -6,7 +6,7 @@ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 56880 bytes, block size: 128. */ +/* Total size: 60384 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 */ @@ -32,7 +32,7 @@ pcre_int32 property_2; } ucd_record; */ -const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */ +const ucd_record _pcre_ucd_records[] = { /* 4320 bytes, record size 8 */ { 9, 0, 0, }, /* 0 */ { 9, 29, 0, }, /* 1 */ { 9, 21, 0, }, /* 2 */ @@ -103,454 +103,476 @@ 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, -209, }, /* 71 */ + { 33, 5, -211, }, /* 72 */ + { 33, 5, 10743, }, /* 73 */ + { 33, 5, 10749, }, /* 74 */ + { 33, 5, -213, }, /* 75 */ + { 33, 5, -214, }, /* 76 */ + { 33, 5, 10727, }, /* 77 */ + { 33, 5, -218, }, /* 78 */ + { 33, 5, -69, }, /* 79 */ + { 33, 5, -217, }, /* 80 */ + { 33, 5, -71, }, /* 81 */ + { 33, 5, -219, }, /* 82 */ + { 33, 6, 0, }, /* 83 */ + { 9, 6, 0, }, /* 84 */ + { 3, 24, 0, }, /* 85 */ + { 27, 12, 0, }, /* 86 */ + { 27, 12, 84, }, /* 87 */ + { 19, 9, 1, }, /* 88 */ + { 19, 5, -1, }, /* 89 */ + { 19, 24, 0, }, /* 90 */ + { 9, 2, 0, }, /* 91 */ + { 19, 6, 0, }, /* 92 */ + { 19, 5, 130, }, /* 93 */ + { 19, 9, 38, }, /* 94 */ + { 19, 9, 37, }, /* 95 */ + { 19, 9, 64, }, /* 96 */ + { 19, 9, 63, }, /* 97 */ + { 19, 5, 0, }, /* 98 */ + { 19, 9, 32, }, /* 99 */ + { 19, 5, -38, }, /* 100 */ + { 19, 5, -37, }, /* 101 */ + { 19, 5, -32, }, /* 102 */ + { 19, 5, -31, }, /* 103 */ + { 19, 5, -64, }, /* 104 */ + { 19, 5, -63, }, /* 105 */ + { 19, 9, 8, }, /* 106 */ + { 19, 5, -62, }, /* 107 */ + { 19, 5, -57, }, /* 108 */ + { 19, 9, 0, }, /* 109 */ + { 19, 5, -47, }, /* 110 */ + { 19, 5, -54, }, /* 111 */ + { 19, 5, -8, }, /* 112 */ + { 10, 9, 1, }, /* 113 */ + { 10, 5, -1, }, /* 114 */ + { 19, 5, -86, }, /* 115 */ + { 19, 5, -80, }, /* 116 */ + { 19, 5, 7, }, /* 117 */ + { 19, 9, -60, }, /* 118 */ + { 19, 5, -96, }, /* 119 */ + { 19, 25, 0, }, /* 120 */ + { 19, 9, -7, }, /* 121 */ + { 19, 9, -130, }, /* 122 */ + { 12, 9, 80, }, /* 123 */ + { 12, 9, 32, }, /* 124 */ + { 12, 5, -32, }, /* 125 */ + { 12, 5, -80, }, /* 126 */ + { 12, 9, 1, }, /* 127 */ + { 12, 5, -1, }, /* 128 */ + { 12, 26, 0, }, /* 129 */ + { 12, 12, 0, }, /* 130 */ + { 12, 11, 0, }, /* 131 */ + { 12, 9, 15, }, /* 132 */ + { 12, 5, -15, }, /* 133 */ + { 1, 9, 48, }, /* 134 */ + { 1, 6, 0, }, /* 135 */ + { 1, 21, 0, }, /* 136 */ + { 1, 5, -48, }, /* 137 */ + { 1, 5, 0, }, /* 138 */ + { 1, 17, 0, }, /* 139 */ + { 25, 12, 0, }, /* 140 */ + { 25, 17, 0, }, /* 141 */ + { 25, 21, 0, }, /* 142 */ + { 25, 7, 0, }, /* 143 */ + { 0, 1, 0, }, /* 144 */ + { 0, 25, 0, }, /* 145 */ + { 0, 21, 0, }, /* 146 */ + { 0, 23, 0, }, /* 147 */ + { 0, 26, 0, }, /* 148 */ + { 0, 12, 0, }, /* 149 */ + { 0, 7, 0, }, /* 150 */ + { 0, 6, 0, }, /* 151 */ + { 0, 13, 0, }, /* 152 */ + { 49, 21, 0, }, /* 153 */ + { 49, 1, 0, }, /* 154 */ + { 49, 7, 0, }, /* 155 */ + { 49, 12, 0, }, /* 156 */ + { 55, 7, 0, }, /* 157 */ + { 55, 12, 0, }, /* 158 */ + { 63, 13, 0, }, /* 159 */ + { 63, 7, 0, }, /* 160 */ + { 63, 12, 0, }, /* 161 */ + { 63, 6, 0, }, /* 162 */ + { 63, 26, 0, }, /* 163 */ + { 63, 21, 0, }, /* 164 */ + { 89, 7, 0, }, /* 165 */ + { 89, 12, 0, }, /* 166 */ + { 89, 6, 0, }, /* 167 */ + { 89, 21, 0, }, /* 168 */ + { 94, 7, 0, }, /* 169 */ + { 94, 12, 0, }, /* 170 */ + { 94, 21, 0, }, /* 171 */ + { 14, 12, 0, }, /* 172 */ + { 14, 10, 0, }, /* 173 */ + { 14, 7, 0, }, /* 174 */ + { 14, 13, 0, }, /* 175 */ + { 14, 6, 0, }, /* 176 */ + { 2, 12, 0, }, /* 177 */ + { 2, 10, 0, }, /* 178 */ + { 2, 7, 0, }, /* 179 */ + { 2, 13, 0, }, /* 180 */ + { 2, 23, 0, }, /* 181 */ + { 2, 15, 0, }, /* 182 */ + { 2, 26, 0, }, /* 183 */ + { 21, 12, 0, }, /* 184 */ + { 21, 10, 0, }, /* 185 */ + { 21, 7, 0, }, /* 186 */ + { 21, 13, 0, }, /* 187 */ + { 20, 12, 0, }, /* 188 */ + { 20, 10, 0, }, /* 189 */ + { 20, 7, 0, }, /* 190 */ + { 20, 13, 0, }, /* 191 */ + { 20, 23, 0, }, /* 192 */ + { 43, 12, 0, }, /* 193 */ + { 43, 10, 0, }, /* 194 */ + { 43, 7, 0, }, /* 195 */ + { 43, 13, 0, }, /* 196 */ + { 43, 26, 0, }, /* 197 */ + { 43, 15, 0, }, /* 198 */ + { 53, 12, 0, }, /* 199 */ + { 53, 7, 0, }, /* 200 */ + { 53, 10, 0, }, /* 201 */ + { 53, 13, 0, }, /* 202 */ + { 53, 15, 0, }, /* 203 */ + { 53, 26, 0, }, /* 204 */ + { 53, 23, 0, }, /* 205 */ + { 54, 10, 0, }, /* 206 */ + { 54, 7, 0, }, /* 207 */ + { 54, 12, 0, }, /* 208 */ + { 54, 13, 0, }, /* 209 */ + { 54, 15, 0, }, /* 210 */ + { 54, 26, 0, }, /* 211 */ + { 28, 10, 0, }, /* 212 */ + { 28, 7, 0, }, /* 213 */ + { 28, 12, 0, }, /* 214 */ + { 28, 13, 0, }, /* 215 */ + { 36, 10, 0, }, /* 216 */ + { 36, 7, 0, }, /* 217 */ + { 36, 12, 0, }, /* 218 */ + { 36, 13, 0, }, /* 219 */ + { 36, 15, 0, }, /* 220 */ + { 36, 26, 0, }, /* 221 */ + { 47, 10, 0, }, /* 222 */ + { 47, 7, 0, }, /* 223 */ + { 47, 12, 0, }, /* 224 */ + { 47, 21, 0, }, /* 225 */ + { 56, 7, 0, }, /* 226 */ + { 56, 12, 0, }, /* 227 */ + { 56, 6, 0, }, /* 228 */ + { 56, 21, 0, }, /* 229 */ + { 56, 13, 0, }, /* 230 */ + { 32, 7, 0, }, /* 231 */ + { 32, 12, 0, }, /* 232 */ + { 32, 6, 0, }, /* 233 */ + { 32, 13, 0, }, /* 234 */ + { 57, 7, 0, }, /* 235 */ + { 57, 26, 0, }, /* 236 */ + { 57, 21, 0, }, /* 237 */ + { 57, 12, 0, }, /* 238 */ + { 57, 13, 0, }, /* 239 */ + { 57, 15, 0, }, /* 240 */ + { 57, 22, 0, }, /* 241 */ + { 57, 18, 0, }, /* 242 */ + { 57, 10, 0, }, /* 243 */ + { 38, 7, 0, }, /* 244 */ + { 38, 10, 0, }, /* 245 */ + { 38, 12, 0, }, /* 246 */ + { 38, 13, 0, }, /* 247 */ + { 38, 21, 0, }, /* 248 */ + { 38, 26, 0, }, /* 249 */ + { 16, 9, 7264, }, /* 250 */ + { 16, 7, 0, }, /* 251 */ + { 16, 6, 0, }, /* 252 */ + { 23, 7, 0, }, /* 253 */ + { 15, 7, 0, }, /* 254 */ + { 15, 12, 0, }, /* 255 */ + { 15, 26, 0, }, /* 256 */ + { 15, 21, 0, }, /* 257 */ + { 15, 15, 0, }, /* 258 */ + { 8, 7, 0, }, /* 259 */ + { 7, 17, 0, }, /* 260 */ + { 7, 7, 0, }, /* 261 */ + { 7, 21, 0, }, /* 262 */ + { 40, 29, 0, }, /* 263 */ + { 40, 7, 0, }, /* 264 */ + { 40, 22, 0, }, /* 265 */ + { 40, 18, 0, }, /* 266 */ + { 45, 7, 0, }, /* 267 */ + { 45, 14, 0, }, /* 268 */ + { 50, 7, 0, }, /* 269 */ + { 50, 12, 0, }, /* 270 */ + { 24, 7, 0, }, /* 271 */ + { 24, 12, 0, }, /* 272 */ + { 6, 7, 0, }, /* 273 */ + { 6, 12, 0, }, /* 274 */ + { 51, 7, 0, }, /* 275 */ + { 51, 12, 0, }, /* 276 */ + { 31, 7, 0, }, /* 277 */ + { 31, 1, 0, }, /* 278 */ + { 31, 10, 0, }, /* 279 */ + { 31, 12, 0, }, /* 280 */ + { 31, 21, 0, }, /* 281 */ + { 31, 6, 0, }, /* 282 */ + { 31, 23, 0, }, /* 283 */ + { 31, 13, 0, }, /* 284 */ + { 31, 15, 0, }, /* 285 */ + { 37, 21, 0, }, /* 286 */ + { 37, 17, 0, }, /* 287 */ + { 37, 12, 0, }, /* 288 */ + { 37, 29, 0, }, /* 289 */ + { 37, 13, 0, }, /* 290 */ + { 37, 7, 0, }, /* 291 */ + { 37, 6, 0, }, /* 292 */ + { 34, 7, 0, }, /* 293 */ + { 34, 12, 0, }, /* 294 */ + { 34, 10, 0, }, /* 295 */ + { 34, 26, 0, }, /* 296 */ + { 34, 21, 0, }, /* 297 */ + { 34, 13, 0, }, /* 298 */ + { 52, 7, 0, }, /* 299 */ + { 39, 7, 0, }, /* 300 */ + { 39, 10, 0, }, /* 301 */ + { 39, 13, 0, }, /* 302 */ + { 39, 15, 0, }, /* 303 */ + { 39, 26, 0, }, /* 304 */ + { 31, 26, 0, }, /* 305 */ + { 5, 7, 0, }, /* 306 */ + { 5, 12, 0, }, /* 307 */ + { 5, 10, 0, }, /* 308 */ + { 5, 21, 0, }, /* 309 */ + { 90, 7, 0, }, /* 310 */ + { 90, 10, 0, }, /* 311 */ + { 90, 12, 0, }, /* 312 */ + { 90, 13, 0, }, /* 313 */ + { 90, 21, 0, }, /* 314 */ + { 90, 6, 0, }, /* 315 */ + { 61, 12, 0, }, /* 316 */ + { 61, 10, 0, }, /* 317 */ + { 61, 7, 0, }, /* 318 */ + { 61, 13, 0, }, /* 319 */ + { 61, 21, 0, }, /* 320 */ + { 61, 26, 0, }, /* 321 */ + { 75, 12, 0, }, /* 322 */ + { 75, 10, 0, }, /* 323 */ + { 75, 7, 0, }, /* 324 */ + { 75, 13, 0, }, /* 325 */ + { 92, 7, 0, }, /* 326 */ + { 92, 12, 0, }, /* 327 */ + { 92, 10, 0, }, /* 328 */ + { 92, 21, 0, }, /* 329 */ + { 69, 7, 0, }, /* 330 */ + { 69, 10, 0, }, /* 331 */ + { 69, 12, 0, }, /* 332 */ + { 69, 21, 0, }, /* 333 */ + { 69, 13, 0, }, /* 334 */ + { 72, 13, 0, }, /* 335 */ + { 72, 7, 0, }, /* 336 */ + { 72, 6, 0, }, /* 337 */ + { 72, 21, 0, }, /* 338 */ + { 9, 10, 0, }, /* 339 */ + { 9, 7, 0, }, /* 340 */ + { 12, 5, 0, }, /* 341 */ + { 12, 6, 0, }, /* 342 */ + { 33, 5, 35332, }, /* 343 */ + { 33, 5, 3814, }, /* 344 */ + { 33, 5, -59, }, /* 345 */ + { 33, 9, -7615, }, /* 346 */ + { 19, 5, 8, }, /* 347 */ + { 19, 9, -8, }, /* 348 */ + { 19, 5, 74, }, /* 349 */ + { 19, 5, 86, }, /* 350 */ + { 19, 5, 100, }, /* 351 */ + { 19, 5, 128, }, /* 352 */ + { 19, 5, 112, }, /* 353 */ + { 19, 5, 126, }, /* 354 */ + { 19, 8, -8, }, /* 355 */ + { 19, 5, 9, }, /* 356 */ + { 19, 9, -74, }, /* 357 */ + { 19, 8, -9, }, /* 358 */ + { 19, 5, -7205, }, /* 359 */ + { 19, 9, -86, }, /* 360 */ + { 19, 9, -100, }, /* 361 */ + { 19, 9, -112, }, /* 362 */ + { 19, 9, -128, }, /* 363 */ + { 19, 9, -126, }, /* 364 */ + { 27, 1, 0, }, /* 365 */ + { 9, 27, 0, }, /* 366 */ + { 9, 28, 0, }, /* 367 */ + { 27, 11, 0, }, /* 368 */ + { 9, 9, 0, }, /* 369 */ + { 9, 5, 0, }, /* 370 */ + { 19, 9, -7517, }, /* 371 */ + { 33, 9, -8383, }, /* 372 */ + { 33, 9, -8262, }, /* 373 */ + { 33, 9, 28, }, /* 374 */ + { 33, 5, -28, }, /* 375 */ + { 33, 14, 16, }, /* 376 */ + { 33, 14, -16, }, /* 377 */ + { 33, 14, 0, }, /* 378 */ + { 9, 26, 26, }, /* 379 */ + { 9, 26, -26, }, /* 380 */ + { 4, 26, 0, }, /* 381 */ + { 17, 9, 48, }, /* 382 */ + { 17, 5, -48, }, /* 383 */ + { 33, 9, -10743, }, /* 384 */ + { 33, 9, -3814, }, /* 385 */ + { 33, 9, -10727, }, /* 386 */ + { 33, 5, -10795, }, /* 387 */ + { 33, 5, -10792, }, /* 388 */ + { 33, 9, -10780, }, /* 389 */ + { 33, 9, -10749, }, /* 390 */ + { 33, 9, -10783, }, /* 391 */ + { 33, 9, -10782, }, /* 392 */ + { 33, 9, -10815, }, /* 393 */ + { 10, 5, 0, }, /* 394 */ + { 10, 26, 0, }, /* 395 */ + { 10, 12, 0, }, /* 396 */ + { 10, 21, 0, }, /* 397 */ + { 10, 15, 0, }, /* 398 */ + { 16, 5, -7264, }, /* 399 */ + { 58, 7, 0, }, /* 400 */ + { 58, 6, 0, }, /* 401 */ + { 58, 21, 0, }, /* 402 */ + { 58, 12, 0, }, /* 403 */ + { 22, 26, 0, }, /* 404 */ + { 22, 6, 0, }, /* 405 */ + { 22, 14, 0, }, /* 406 */ + { 23, 12, 0, }, /* 407 */ + { 26, 7, 0, }, /* 408 */ + { 26, 6, 0, }, /* 409 */ + { 29, 7, 0, }, /* 410 */ + { 29, 6, 0, }, /* 411 */ + { 3, 7, 0, }, /* 412 */ + { 23, 26, 0, }, /* 413 */ + { 29, 26, 0, }, /* 414 */ + { 22, 7, 0, }, /* 415 */ + { 60, 7, 0, }, /* 416 */ + { 60, 6, 0, }, /* 417 */ + { 60, 26, 0, }, /* 418 */ + { 85, 7, 0, }, /* 419 */ + { 85, 6, 0, }, /* 420 */ + { 85, 21, 0, }, /* 421 */ + { 76, 7, 0, }, /* 422 */ + { 76, 6, 0, }, /* 423 */ + { 76, 21, 0, }, /* 424 */ + { 76, 13, 0, }, /* 425 */ + { 12, 7, 0, }, /* 426 */ + { 12, 21, 0, }, /* 427 */ + { 78, 7, 0, }, /* 428 */ + { 78, 14, 0, }, /* 429 */ + { 78, 12, 0, }, /* 430 */ + { 78, 21, 0, }, /* 431 */ + { 33, 9, -35332, }, /* 432 */ + { 33, 9, -42280, }, /* 433 */ + { 48, 7, 0, }, /* 434 */ + { 48, 12, 0, }, /* 435 */ + { 48, 10, 0, }, /* 436 */ + { 48, 26, 0, }, /* 437 */ + { 64, 7, 0, }, /* 438 */ + { 64, 21, 0, }, /* 439 */ + { 74, 10, 0, }, /* 440 */ + { 74, 7, 0, }, /* 441 */ + { 74, 12, 0, }, /* 442 */ + { 74, 21, 0, }, /* 443 */ + { 74, 13, 0, }, /* 444 */ + { 14, 21, 0, }, /* 445 */ + { 68, 13, 0, }, /* 446 */ + { 68, 7, 0, }, /* 447 */ + { 68, 12, 0, }, /* 448 */ + { 68, 21, 0, }, /* 449 */ + { 73, 7, 0, }, /* 450 */ + { 73, 12, 0, }, /* 451 */ + { 73, 10, 0, }, /* 452 */ + { 73, 21, 0, }, /* 453 */ + { 83, 12, 0, }, /* 454 */ + { 83, 10, 0, }, /* 455 */ + { 83, 7, 0, }, /* 456 */ + { 83, 21, 0, }, /* 457 */ + { 83, 6, 0, }, /* 458 */ + { 83, 13, 0, }, /* 459 */ + { 67, 7, 0, }, /* 460 */ + { 67, 12, 0, }, /* 461 */ + { 67, 10, 0, }, /* 462 */ + { 67, 13, 0, }, /* 463 */ + { 67, 21, 0, }, /* 464 */ + { 38, 6, 0, }, /* 465 */ + { 91, 7, 0, }, /* 466 */ + { 91, 12, 0, }, /* 467 */ + { 91, 6, 0, }, /* 468 */ + { 91, 21, 0, }, /* 469 */ + { 86, 7, 0, }, /* 470 */ + { 86, 10, 0, }, /* 471 */ + { 86, 12, 0, }, /* 472 */ + { 86, 21, 0, }, /* 473 */ + { 86, 13, 0, }, /* 474 */ + { 9, 4, 0, }, /* 475 */ + { 9, 3, 0, }, /* 476 */ + { 25, 25, 0, }, /* 477 */ + { 0, 24, 0, }, /* 478 */ + { 35, 7, 0, }, /* 479 */ + { 19, 14, 0, }, /* 480 */ + { 19, 15, 0, }, /* 481 */ + { 19, 26, 0, }, /* 482 */ + { 70, 7, 0, }, /* 483 */ + { 66, 7, 0, }, /* 484 */ + { 41, 7, 0, }, /* 485 */ + { 41, 15, 0, }, /* 486 */ + { 18, 7, 0, }, /* 487 */ + { 18, 14, 0, }, /* 488 */ + { 59, 7, 0, }, /* 489 */ + { 59, 21, 0, }, /* 490 */ + { 42, 7, 0, }, /* 491 */ + { 42, 21, 0, }, /* 492 */ + { 42, 14, 0, }, /* 493 */ + { 13, 9, 40, }, /* 494 */ + { 13, 5, -40, }, /* 495 */ + { 46, 7, 0, }, /* 496 */ + { 44, 7, 0, }, /* 497 */ + { 44, 13, 0, }, /* 498 */ + { 11, 7, 0, }, /* 499 */ + { 80, 7, 0, }, /* 500 */ + { 80, 21, 0, }, /* 501 */ + { 80, 15, 0, }, /* 502 */ + { 65, 7, 0, }, /* 503 */ + { 65, 15, 0, }, /* 504 */ + { 65, 21, 0, }, /* 505 */ + { 71, 7, 0, }, /* 506 */ + { 71, 21, 0, }, /* 507 */ + { 30, 7, 0, }, /* 508 */ + { 30, 12, 0, }, /* 509 */ + { 30, 15, 0, }, /* 510 */ + { 30, 21, 0, }, /* 511 */ + { 87, 7, 0, }, /* 512 */ + { 87, 15, 0, }, /* 513 */ + { 87, 21, 0, }, /* 514 */ + { 77, 7, 0, }, /* 515 */ + { 77, 21, 0, }, /* 516 */ + { 82, 7, 0, }, /* 517 */ + { 82, 15, 0, }, /* 518 */ + { 81, 7, 0, }, /* 519 */ + { 81, 15, 0, }, /* 520 */ + { 88, 7, 0, }, /* 521 */ + { 0, 15, 0, }, /* 522 */ + { 93, 10, 0, }, /* 523 */ + { 93, 12, 0, }, /* 524 */ + { 93, 7, 0, }, /* 525 */ + { 93, 21, 0, }, /* 526 */ + { 93, 15, 0, }, /* 527 */ + { 93, 13, 0, }, /* 528 */ + { 84, 12, 0, }, /* 529 */ + { 84, 10, 0, }, /* 530 */ + { 84, 7, 0, }, /* 531 */ + { 84, 21, 0, }, /* 532 */ + { 84, 1, 0, }, /* 533 */ + { 62, 7, 0, }, /* 534 */ + { 62, 14, 0, }, /* 535 */ + { 62, 21, 0, }, /* 536 */ + { 79, 7, 0, }, /* 537 */ + { 19, 12, 0, }, /* 538 */ + { 26, 26, 0, }, /* 539 */ }; const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ @@ -558,24 +580,24 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ - 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 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 94, 94, 94, 94, /* U+4800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+5000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+5800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+6000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+6800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+7000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+7800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+8000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+8800 */ - 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 */ + 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, 17, 78, 79, 80, 81, 82, 83, 84, 85, /* U+2800 */ + 86, 87, 88, 89, 90, 91, 92, 70, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+4000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, /* U+4800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+9000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 95, /* U+9800 */ + 96, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99,100,101,102,103, /* U+A000 */ +104,105,106,107,108,109,110,111, 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 */ @@ -585,21 +607,21 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ +114,114, 93, 93,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 */ +141,142, 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 */ +143,143,143,143,143,143,144, 17,145, 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 */ +146,146,146,146,146,146,146,146,147, 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 */ +148,148,148,148,149, 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 */ @@ -608,40 +630,40 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ +150, 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 */ + 70,151,152,153,154, 17,155, 17,156,157,158,159,160,161,162,163, /* 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 */ +164,165,166,167,168, 17,169,170,171,172,173,174,175,176,177, 17, /* U+1F000 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* 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 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+22000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+22800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+23000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+23800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+24000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+24800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+25000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+25800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+26000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+26800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+27000 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+27800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28000 */ - 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, 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 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,178, 93, 93, /* U+2A000 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+2A800 */ + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,179, 93, /* U+2B000 */ +180, 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 */ @@ -649,7 +671,7 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ + 93, 93, 93, 93,180, 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 */ @@ -1002,7 +1024,7 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ +181, 17,182,183, 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 */ @@ -1065,7 +1087,7 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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,184, /* 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 */ @@ -1097,10 +1119,10 @@ const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ 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 */ +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,184, /* U+10F800 */ }; -const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ +const pcre_uint16 _pcre_ucd_stage2[] = { /* 47360 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, @@ -1148,528 +1170,528 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 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, + 66, 14, 14, 69, 14, 70, 14, 14, 71, 72, 14, 73, 14, 14, 14, 72, + 14, 74, 75, 14, 14, 76, 14, 14, 14, 14, 14, 14, 14, 77, 14, 14, /* 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, + 78, 14, 14, 78, 14, 14, 14, 14, 78, 79, 80, 80, 81, 14, 14, 14, + 14, 14, 82, 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, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 83, 83, 83, 83, 83, 10, 10, 10, 10, 10, 85, 85, 84, 10, 84, 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, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 88, 89, 88, 89, 84, 90, 88, 89, 91, 91, 92, 93, 93, 93, 2, 91, /* 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, + 91, 91, 91, 91, 90, 10, 94, 2, 95, 95, 95, 91, 96, 91, 97, 97, + 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 91, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,101, + 98,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,103,102,102,102,102,102,102,102,102,102,104,105,105,106, +107,108,109,109,109,110,111,112, 88, 89, 88, 89, 88, 89, 88, 89, + 88, 89,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +115,116,117, 98,118,119,120, 88, 89,121, 88, 89, 98,122,122,122, /* 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, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +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, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, /* 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, +127,128,129,130,130, 86, 86,130,131,131,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +132,127,128,127,128,127,128,127,128,127,128,127,128,127,128,133, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, /* 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, -135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91, + 91,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134, 91, 91,135,136,136,136,136,136,136, + 91,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, /* 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, +137,137,137,137,137,137,137,138, 91, 2,139, 91, 91, 91, 91, 91, + 91,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,141,140, +142,140,140,142,140,140,142,140, 91, 91, 91, 91, 91, 91, 91, 91, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143, 91, 91, 91, 91, 91, +143,143,143,142,142, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +144,144,144,144, 91, 91,145,145,145,146,146,147, 2,146,148,148, +149,149,149,149,149,149,149,149,149,149,149, 2, 91, 91,146, 2, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, + 84,150,150,150,150,150,150,150,150,150,150, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86,149,149,149,149,149,149,149,149,149, 86, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,146,146,146,146,150,150, + 86,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,146,150,149,149,149,149,149,149,149, 16,148,149, +149,149,149,149,149,151,151,149,149,148,149,149,149,149,150,150, +152,152,152,152,152,152,152,152,152,152,150,150,150,148,148,150, /* 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, +153,153,153,153,153,153,153,153,153,153,153,153,153,153, 91,154, +155,156,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,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156, 91, 91,155,155,155, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +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,157,157, +157,157,157,157,157,157,158,158,158,158,158,158,158,158,158,158, +158,157, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +159,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,161,161,161,161,161, +161,161,161,161,162,162,163,164,164,164,162, 91, 91, 91, 91, 91, /* 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, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,166,166,166,166,167,166,166,166,166,166, +166,166,166,166,167,166,166,166,167,166,166,166,166,166, 91, 91, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 91, +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,170,170,170, 91, 91,171, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +172,172,172,173,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,172,173,172,174,173,173, +173,172,172,172,172,172,172,172,172,173,173,173,173,172,173,173, +174, 86, 86,172,172,172,172,172,174,174,174,174,174,174,174,174, +174,174,172,172, 2, 2,175,175,175,175,175,175,175,175,175,175, + 2,176,174,174,174,174,174,174, 91,174,174,174,174,174,174,174, /* 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, + 91,177,178,178, 91,179,179,179,179,179,179,179,179, 91, 91,179, +179, 91, 91,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179, 91,179,179,179,179,179,179, +179, 91,179, 91, 91, 91,179,179,179,179, 91, 91,177,179,178,178, +178,177,177,177,177, 91, 91,178,178, 91, 91,178,178,177,179, 91, + 91, 91, 91, 91, 91, 91, 91,178, 91, 91, 91, 91,179,179, 91,179, +179,179,177,177, 91, 91,180,180,180,180,180,180,180,180,180,180, +179,179,181,181,182,182,182,182,182,182,183,181, 91, 91, 91, 91, /* 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, + 91,184,184,185, 91,186,186,186,186,186,186, 91, 91, 91, 91,186, +186, 91, 91,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186, 91,186,186,186,186,186,186, +186, 91,186,186, 91,186,186, 91,186,186, 91, 91,184, 91,185,185, +185,184,184, 91, 91, 91, 91,184,184, 91, 91,184,184,184, 91, 91, + 91,184, 91, 91, 91, 91, 91, 91, 91,186,186,186,186, 91,186, 91, + 91, 91, 91, 91, 91, 91,187,187,187,187,187,187,187,187,187,187, +184,184,186,186,186,184, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91,188,188,189, 91,190,190,190,190,190,190,190,190,190, 91,190, +190,190, 91,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190, 91,190,190,190,190,190,190, +190, 91,190,190, 91,190,190,190,190,190, 91, 91,188,190,189,189, +189,188,188,188,188,188, 91,188,188,189, 91,189,189,188, 91, 91, +190, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +190,190,188,188, 91, 91,191,191,191,191,191,191,191,191,191,191, + 91,192, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91,193,194,194, 91,195,195,195,195,195,195,195,195, 91, 91,195, +195, 91, 91,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195, 91,195,195,195,195,195,195, +195, 91,195,195, 91,195,195,195,195,195, 91, 91,193,195,194,193, +194,193,193,193,193, 91, 91,194,194, 91, 91,194,194,193, 91, 91, + 91, 91, 91, 91, 91, 91,193,194, 91, 91, 91, 91,195,195, 91,195, +195,195,193,193, 91, 91,196,196,196,196,196,196,196,196,196,196, +197,195,198,198,198,198,198,198, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91, 91,199,200, 91,200,200,200,200,200,200, 91, 91, 91,200,200, +200, 91,200,200,200,200, 91, 91, 91,200,200, 91,200, 91,200,200, + 91, 91, 91,200,200, 91, 91, 91,200,200,200, 91, 91, 91,200,200, +200,200,200,200,200,200,200,200,200,200, 91, 91, 91, 91,201,201, +199,201,201, 91, 91, 91,201,201,201, 91,201,201,201,199, 91, 91, +200, 91, 91, 91, 91, 91, 91,201, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91,202,202,202,202,202,202,202,202,202,202, +203,203,203,204,204,204,204,204,204,205,204, 91, 91, 91, 91, 91, /* 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, + 91,206,206,206, 91,207,207,207,207,207,207,207,207, 91,207,207, +207, 91,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207, 91,207,207,207,207,207,207, +207,207,207,207, 91,207,207,207,207,207, 91, 91, 91,207,208,208, +208,206,206,206,206, 91,208,208,208, 91,208,208,208,208, 91, 91, + 91, 91, 91, 91, 91,208,208, 91,207,207, 91, 91, 91, 91, 91, 91, +207,207,208,208, 91, 91,209,209,209,209,209,209,209,209,209,209, + 91, 91, 91, 91, 91, 91, 91, 91,210,210,210,210,210,210,210,211, /* 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, + 91, 91,212,212, 91,213,213,213,213,213,213,213,213, 91,213,213, +213, 91,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213, 91,213,213,213,213,213,213, +213,213,213,213, 91,213,213,213,213,213, 91, 91,214,213,212,214, +212,212,212,212,212, 91,214,212,212, 91,212,212,214,214, 91, 91, + 91, 91, 91, 91, 91,212,212, 91, 91, 91, 91, 91, 91, 91,213, 91, +213,213,214,214, 91, 91,215,215,215,215,215,215,215,215,215,215, + 91,213,213, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91, 91,216,216, 91,217,217,217,217,217,217,217,217, 91,217,217, +217, 91,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217, 91, 91,217,216,216, +216,218,218,218,218, 91,216,216,216, 91,216,216,216,218,217, 91, + 91, 91, 91, 91, 91, 91, 91,216, 91, 91, 91, 91, 91, 91, 91, 91, +217,217,218,218, 91, 91,219,219,219,219,219,219,219,219,219,219, +220,220,220,220,220,220, 91, 91, 91,221,217,217,217,217,217,217, /* 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, + 91, 91,222,222, 91,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223, 91, 91, 91,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223, 91,223,223,223,223,223,223,223,223,223, 91,223, 91, 91, +223,223,223,223,223,223,223, 91, 91, 91,224, 91, 91, 91, 91,222, +222,222,224,224,224, 91,224, 91,222,222,222,222,222,222,222,222, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91,222,222,225, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,227,226,226,227,227,227,227,227,227,227, 91, 91, 91, 91, 3, +226,226,226,226,226,226,228,227,227,227,227,227,227,227,227,229, +230,230,230,230,230,230,230,230,230,230,229,229, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91,231,231, 91,231, 91, 91,231,231, 91,231, 91, 91,231, 91, 91, + 91, 91, 91, 91,231,231,231,231, 91,231,231,231,231,231,231,231, + 91,231,231,231, 91,231, 91,231, 91, 91,231,231, 91,231,231,231, +231,232,231,231,232,232,232,232,232,232, 91,232,232,231, 91, 91, +231,231,231,231,231, 91,233, 91,232,232,232,232,232,232, 91, 91, +234,234,234,234,234,234,234,234,234,234, 91, 91,231,231, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +235,236,236,236,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,236,236,236,236,236,238,238,236,236,236,236,236,236, +239,239,239,239,239,239,239,239,239,239,240,240,240,240,240,240, +240,240,240,240,236,238,236,238,236,238,241,242,241,242,243,243, +235,235,235,235,235,235,235,235, 91,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235, 91, 91, 91, + 91,238,238,238,238,238,238,238,238,238,238,238,238,238,238,243, /* 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, +238,238,238,238,238,237,238,238,235,235,235,235,235,238,238,238, +238,238,238,238,238,238,238,238, 91,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, 91,236,236, +236,236,236,236,236,236,238,236,236,236,236,236,236, 91,236,236, +237,237,237,237,237, 13, 13, 13, 13,237,237, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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,244,244,244,244,244,245,245,246,246,246, +246,245,246,246,246,246,246,246,245,246,246,245,245,246,246,244, +247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248, +244,244,244,244,244,244,245,245,246,246,244,244,244,244,246,246, +246,244,245,245,245,244,244,245,245,245,245,245,245,245,244,244, +244,246,246,246,246,244,244,244,244,244,244,244,244,244,244,244, /* 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, +244,244,246,245,245,246,246,245,245,245,245,245,245,246,244,245, +247,247,247,247,247,247,247,247,247,247,245,245,245,246,249,249, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251, 2,252, 91, 91, 91, /* 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, +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,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, /* 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, +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,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, 91,254,254,254,254, 91, 91, +254,254,254,254,254,254,254, 91,254, 91,254,254,254,254, 91, 91, +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, /* 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, +254,254,254,254,254,254,254,254,254, 91,254,254,254,254, 91, 91, +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, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254, 91, +254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254, 91,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,254,254, /* 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, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254, 91,254,254,254,254, 91, 91,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,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, 91, 91,255,255,255, +256,257,257,257,257,257,257,257,257,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258, 91, 91, 91, /* 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, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +256,256,256,256,256,256,256,256,256,256, 91, 91, 91, 91, 91, 91, +259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259, +259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259, +259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259, +259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259, +259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259, +259,259,259,259,259, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +260,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,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, /* 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, +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,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, /* 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, +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,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,262,262,261, +261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, /* 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, +263,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264, +264,264,264,264,264,264,264,264,264,264,264,265,266, 91, 91, 91, +267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, +267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, +267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, +267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, +267,267,267,267,267,267,267,267,267,267,267, 2, 2, 2,268,268, +268, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +269,269,269,269,269,269,269,269,269,269,269,269,269, 91,269,269, +269,269,270,270,270, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,272,272,272, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, +273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273, +273,273,274,274, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +275,275,275,275,275,275,275,275,275,275,275,275,275, 91,275,275, +275, 91,276,276, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,277,277,278,278,279,280,280,280,280,280,280,280,279,279, +279,279,279,279,279,279,280,279,279,280,280,280,280,280,280,280, +280,280,280,280,281,281,281,282,281,281,281,283,277,280, 91, 91, +284,284,284,284,284,284,284,284,284,284, 91, 91, 91, 91, 91, 91, +285,285,285,285,285,285,285,285,285,285, 91, 91, 91, 91, 91, 91, /* 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, +286,286, 2, 2,286, 2,287,286,286,286,286,288,288,288,289, 91, +290,290,290,290,290,290,290,290,290,290, 91, 91, 91, 91, 91, 91, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,292,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +291,291,291,291,291,291,291,291,291,288,291, 91, 91, 91, 91, 91, +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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +293,293,293,293,293,293,293,293,293,293,293,293,293, 91, 91, 91, +294,294,294,295,295,295,295,294,294,295,295,295, 91, 91, 91, 91, +295,295,294,295,295,295,295,295,295,294,294,294, 91, 91, 91, 91, +296, 91, 91, 91,297,297,298,298,298,298,298,298,298,298,298,298, +299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299, +299,299,299,299,299,299,299,299,299,299,299,299,299,299, 91, 91, +299,299,299,299,299, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, +300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300, +300,300,300,300,300,300,300,300,300,300,300,300, 91, 91, 91, 91, +301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301, +301,300,300,300,300,300,300,300,301,301, 91, 91, 91, 91, 91, 91, +302,302,302,302,302,302,302,302,302,302,303, 91, 91, 91,304,304, +305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305, +305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305, /* 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, +306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, +306,306,306,306,306,306,306,307,307,308,308,308, 91, 91,309,309, +310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310, +310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310, +310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310, +310,310,310,310,310,311,312,311,312,312,312,312,312,312,312, 91, +312,311,312,311,311,312,312,312,312,312,312,312,312,311,311,311, +311,311,311,312,312,312,312,312,312,312,312,312,312, 91, 91,312, /* 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, +313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91, +313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91, +314,314,314,314,314,314,314,315,314,314,314,314,314,314, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +316,316,316,316,317,318,318,318,318,318,318,318,318,318,318,318, +318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318, +318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318, +318,318,318,318,316,317,316,316,316,316,316,317,316,317,317,317, +317,317,316,317,317,318,318,318,318,318,318,318, 91, 91, 91, 91, +319,319,319,319,319,319,319,319,319,319,320,320,320,320,320,320, +320,321,321,321,321,321,321,321,321,321,321,316,316,316,316,316, +316,316,316,316,321,321,321,321,321,321,321,321,321, 91, 91, 91, /* 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, +322,322,323,324,324,324,324,324,324,324,324,324,324,324,324,324, +324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324, +324,323,322,322,322,322,323,323,322,322,323, 91, 91, 91,324,324, +325,325,325,325,325,325,325,325,325,325, 91, 91, 91, 91, 91, 91, +326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326, +326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326, +326,326,326,326,326,326,327,328,327,327,328,328,328,327,328,327, +327,327,328,328, 91, 91, 91, 91, 91, 91, 91, 91,329,329,329,329, /* 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, +330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330, +330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330, +330,330,330,330,331,331,331,331,331,331,331,331,332,332,332,332, +332,332,332,332,331,331,332,332, 91, 91, 91,333,333,333,333,333, +334,334,334,334,334,334,334,334,334,334, 91, 91, 91,330,330,330, +335,335,335,335,335,335,335,335,335,335,336,336,336,336,336,336, +336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336, +336,336,336,336,336,336,336,336,337,337,337,337,337,337,338,338, /* 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, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 86, 86, 86, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86,339, 86, 86, 86, 86, 86, 86, 86,340,340,340,340, 86,340,340, +340,340,339, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 14, 14, 14, 14, 14, 14, 98, 98, 98, 98, 98,341, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92, 92, 92, + 92, 92, 14, 14, 14, 14, 98, 98, 98, 98, 98, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14,342,343, 14, 14, 14,344, 14, 14, /* 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, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 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, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 86, 86, 86, 86, /* block 57 */ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, @@ -1683,7 +1705,7 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ /* 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, 14, 14, 14, 14, 14,345, 14, 14,346, 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, @@ -1692,57 +1714,57 @@ const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, /* 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, +347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348, +347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91, +347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348, +347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348, +347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91, + 98,347, 98,347, 98,347, 98,347, 91,348, 91,348, 91,348, 91,348, +347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348, +349,349,350,350,350,350,351,351,352,352,353,353,354,354, 91, 91, /* 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, +347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355, +347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355, +347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355, +347,347, 98,356, 98, 91, 98, 98,348,348,357,357,358, 90,359, 90, + 90, 90, 98,356, 98, 91, 98, 98,360,360,360,360,358, 90, 90, 90, +347,347, 98, 98, 91, 91, 98, 98,348,348,361,361, 91, 90, 90, 90, +347,347, 98, 98, 98,117, 98, 98,348,348,362,362,121, 90, 90, 90, + 91, 91, 98,356, 98, 91, 98, 98,363,363,364,364,358, 90, 90, 91, /* 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,365,365, 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,366,367, 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, 91, 91, 91, 91, 91, 16, 16, 16, 16, 16, 16, + 17, 83, 91, 91, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 83, /* 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, 91, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 91, 91, 91, 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, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,368,368,368, +368, 86,368,368,368, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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,369, 13, 13, 13, 13,369, 13, 13,370,369,369,369,370,370, +369,369,369,370, 13,369, 13, 13, 6,369,369,369,369,369, 13, 13, + 13, 13, 13, 13,369, 13,371, 13,369, 13,372,373,369,369, 13,370, +369,369,374,369,370,340,340,340,340,370, 13, 13,370,370,369,369, + 6, 6, 6, 6, 6,369,370,370,370,370, 13, 6, 13, 13,375, 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, +376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, +377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377, /* block 64 */ -367,367,367, 21, 22,367,367,367,367, 17, 89, 89, 89, 89, 89, 89, +378,378,378, 21, 22,378,378,378,378, 17, 91, 91, 91, 91, 91, 91, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13, 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1778,16 +1800,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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1795,10 +1817,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,379,379,379,379,379,379,379,379,379,379, +379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379, +380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, +380,380,380,380,380,380,380,380,380,380, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 70 */ @@ -1832,46 +1854,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 */ + 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 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, 91, 6, 91, 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 */ +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, -/* block 77 */ +/* block 76 */ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -1881,735 +1893,745 @@ 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, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 78 */ +382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, +382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, +382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, 91, +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,383,383,383,383,383,383, +383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, 91, + 21, 22,384,385,386,387,388, 21, 22, 21, 22, 21, 22,389,390,391, +392, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 83,393,393, /* 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, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114, +113,114,113,114,394,395,395,395,395,395,395,113,114,113,114,396, +396,396, 91, 91, 91, 91, 91, 91, 91,397,397,397,397,398,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, +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,399, +399,399,399,399,399,399, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +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, 91, 91, 91, 91, 91, 91, 91, 91, 91,401, +402, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,403, /* 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, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91, +254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91, +254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91, +254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91, +254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, /* 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, - -/* 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, 84, + 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 83 */ +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, 91,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,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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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,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, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, /* 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, +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,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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, /* 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, + 1, 2, 2, 2, 13,405,340,406, 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,406,406,406,406,406,406,406,406,406, 86, 86, 86, 86,407,407, + 7, 84, 84, 84, 84, 84, 13, 13,406,406,406,405,340, 2, 13, 13, + 91,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,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 87 */ - 1, 2, 2, 2, 13,392,329,393, 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, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408, 91, 91, 86, 86, 10, 10,409,409,408, + 7,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410, 2, 84,411,411,410, /* 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, + 91, 91, 91, 91, 91,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, 91, 91, + 91,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, /* 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, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 91, + 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +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, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, /* block 90 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89, - 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, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 91, + 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, 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, +413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 13, /* 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, 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, 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +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, 91, /* block 92 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, +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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 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, 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, /* 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, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, /* 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, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 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 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, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,417,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,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,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, /* 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, +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,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,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,416,416,416,416,416, /* 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, +416,416,416,416,416,416,416,416,416,416,416,416,416, 91, 91, 91, +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, 91, 91, 91, 91, 91, 91, 91, 91, 91, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,420,420,420,420,420,420,421,421, /* 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, +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,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,422,422, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, /* 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, +422,422,422,422,422,422,422,422,422,422,422,422,423,424,424,424, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +425,425,425,425,425,425,425,425,425,425,422,422, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,426,130, +131,131,131,427, 91, 91, 91, 91, 91, 91, 91, 91,130,130,427,342, /* 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, +127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128, +127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,429, +430,430,431,431,431,431,431,431, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, - -/* 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, 10, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84, 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, + 83, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,432, 21, 22, + +/* block 103 */ + 21, 22, 21, 22, 21, 22, 21, 22, 84, 10, 10, 21, 22,433, 14, 91, + 21, 22, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 14, 45, 45, 45, 45, 45, /* 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, +434,434,435,434,434,434,435,434,434,434,434,435,434,434,434,434, +434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434, +434,434,434,436,436,435,435,436,437,437,437,437, 91, 91, 91, 91, + 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 91, 91, 91, 91, 91, 91, +438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, +438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, +438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, +438,438,438,438,439,439,439,439, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +440,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,441,441,441,440,440,440,440,440,440,440,440,440,440,440,440, +440,440,440,440,442, 91, 91, 91, 91, 91, 91, 91, 91, 91,443,443, +444,444,444,444,444,444,444,444,444,444, 91, 91, 91, 91, 91, 91, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,174,174,174,174,174,174,445,445,445,174, 91, 91, 91, 91, /* 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, +446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447, +447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447, +447,447,447,447,447,447,448,448,448,448,448,448,448,448,449,449, +450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450, +450,450,450,450,450,450,450,451,451,451,451,451,451,451,451,451, +451,451,452,452, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,453, +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, 91, 91, 91, /* 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, +454,454,454,455,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,454,455,455,454,454,454,454,455,455,454,455,455,455, +455,457,457,457,457,457,457,457,457,457,457,457,457,457, 91,458, +459,459,459,459,459,459,459,459,459,459, 91, 91, 91, 91,457,457, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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,461,461,461,461,461,461,462, +462,461,461,462,462,461,461, 91, 91, 91, 91, 91, 91, 91, 91, 91, +460,460,460,461,460,460,460,460,460,460,460,460,461,462, 91, 91, +463,463,463,463,463,463,463,463,463,463, 91, 91,464,464,464,464, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +465,244,244,244,244,244,244,249,249,249,244,245, 91, 91, 91, 91, /* 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, +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, +467,466,467,467,467,466,466,467,467,466,466,466,466,466,467,467, +466,467,466, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,466,466,468,469,469, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91,254,254,254,254,254,254, 91, 91,254,254,254,254,254,254, 91, + 91,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91, +254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +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,471,472,471,471,472,471,471,473,471,472, 91, 91, +474,474,474,474,474,474,474,474,474,474, 91, 91, 91, 91, 91, 91, /* 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, +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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253, 91, 91, 91, 91,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, 91, 91, 91, 91, /* 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, +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,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,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,475,475,475,475, +475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, /* 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, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, /* 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, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, /* 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, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 14, 14, 14, 14, 14, 14, 14, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91,138,138,138,138,138, 91, 91, 91, 91, 91,143,140,143, +143,143,143,143,143,143,143,143,143,477,143,143,143,143,143,143, +143,143,143,143,143,143,143, 91,143,143,143,143,143, 91,143, 91, +143,143, 91,143,143, 91,143,143,143,143,143,143,143,143,143,143, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,478,478,478,478,478,478,478,478,478,478,478,478,478,478, +478,478, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150, 4, 5, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, + 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +150,150,150,150,150,150,150,150,150,150,150,150,147, 13, 91, 91, /* 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, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 91, 91, 91, 91, 91, 91, + 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, 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, + 2, 2, 2, 91, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, + 2, 2, 6, 7, 6, 6, 6, 91, 2, 3, 2, 2, 91, 91, 91, 91, +150,150,150,150,150, 91,150,150,150,150,150,150,150,150,150,150, /* 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, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150, 91, 91, 16, /* block 124 */ - 89, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, + 91, 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, + 5, 2, 4, 5, 2, 2,410,410,410,410,410,410,410,410,410,410, + 84,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, /* 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, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410, 84, 84, +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, 91, + 91, 91,253,253,253,253,253,253, 91, 91,253,253,253,253,253,253, + 91, 91,253,253,253,253,253,253, 91, 91,253,253,253, 91, 91, 91, + 3, 3, 6, 10, 13, 3, 3, 91, 13, 6, 6, 6, 6, 13, 13, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 16, 16, 16, 13, 13, 91, 91, /* 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, +479,479,479,479,479,479,479,479,479,479,479,479, 91,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, 91,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479, 91,479,479, 91,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91, +479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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,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, +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,479,479,479, 91, 91, 91, 91, 91, /* block 128 */ - 2, 2, 13, 89, 89, 89, 89, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 2, 2, 13, 91, 91, 91, 91, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,465,465,465,465,466,466,466,466,466,466,466, + 17, 17, 17, 17, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, +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,481,481,481,481,482,482,482,482,482,482,482, /* 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, +482,482,482,482,482,482,482,482,482,482,481, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 91, 91, /* 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, +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, 91, 91, 91, +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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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, 91, +486,486,486,486, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,488,487,487,487,487,487,487,487,487,488, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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, 91,490, +491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, +491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, +491,491,491,491, 91, 91, 91, 91,491,491,491,491,491,491,491,491, +492,493,493,493,493,493, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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,494,494, +494,494,494,494,494,494,494,494,495,495,495,495,495,495,495,495, +495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,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,496,496,496,496,496,496,496,496,496,496,496,496, /* 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, +497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497, +497,497,497,497,497,497,497,497,497,497,497,497,497,497, 91, 91, +498,498,498,498,498,498,498,498,498,498, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +499,499,499,499,499,499, 91, 91,499, 91,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, 91,499,499, 91, 91, 91,499, 91, 91,499, +500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500, 91,501,502,502,502,502,502,502,502,502, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,504,504,504,504,504,504, 91, 91, 91,505, +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, 91, 91, 91, 91, 91,507, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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,509,509,509, 91,509,509, 91, 91, 91, 91, 91,509,509,509,509, +508,508,508,508, 91,508,508,508, 91,508,508,508,508,508,508,508, +508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508, +508,508,508,508, 91, 91, 91, 91,509,509,509, 91, 91, 91, 91,509, +510,510,510,510,510,510,510,510, 91, 91, 91, 91, 91, 91, 91, 91, +511,511,511,511,511,511,511,511,511, 91, 91, 91, 91, 91, 91, 91, +512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, +512,512,512,512,512,512,512,512,512,512,512,512,512,513,513,514, /* 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, +515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +515,515,515,515,515,515, 91, 91, 91,516,516,516,516,516,516,516, +517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, +517,517,517,517,517,517, 91, 91,518,518,518,518,518,518,518,518, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519, 91, 91, 91, 91, 91,520,520,520,520,520,520,520,520, /* 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, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +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, 91, /* 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, +523,524,523,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, +525,525,525,525,525,525,525,525,524,524,524,524,524,524,524,524, +524,524,524,524,524,524,524,526,526,526,526,526,526,526, 91, 91, + 91, 91,527,527,527,527,527,527,527,527,527,527,527,527,527,527, +527,527,527,527,527,527,528,528,528,528,528,528,528,528,528,528, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +529,529,530,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +530,530,530,529,529,529,529,530,530,529,529,532,532,533,532,532, +532,532, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, /* 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, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535, +535,535,535, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +536,536,536,536, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, /* block 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, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, +537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, /* 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, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, +428,428,428,428,428,428,428,428,428, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +410,408, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* block 151 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -2617,209 +2639,339 @@ 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, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13,339,339, 86, 86, 86, 13, 13, 13,339,339,339, +339,339,339, 16, 16, 16, 16, 16, 16, 16, 16, 86, 86, 86, 86, 86, /* 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, + 86, 86, 86, 13, 13, 86, 86, 86, 86, 86, 86, 86, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 86, 86, 86, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,538,538,538,482, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, +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,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,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,370,370, +370,370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370, +370,370,370,370,370,370,370,370,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* 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, +369,369,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,369, 91,369,369, + 91, 91,369, 91, 91,369,369, 91, 91,369,369,369,369, 91,369,369, +369,369,369,369,369,369,370,370,370,370, 91,370, 91,370,370,370, +370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370,370, +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,370,370,370,370,370,370, +370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, /* 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, +370,370,370,370,369,369, 91,369,369,369,369, 91, 91,369,369,369, +369,369,369,369,369, 91,369,369,369,369,369,369,369, 91,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,369,369, 91,369,369,369,369, 91, +369,369,369,369,369, 91,369, 91, 91, 91,369,369,369,369,369,369, +369, 91,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,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* 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, +369,369,369,369,369,369,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, +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,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,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,370,370, +370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, /* block 160 */ - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 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, +370,370,370,370,370,370,370,370,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,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,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,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, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* 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, +369,369,369,369,369,369,369,369,369,369,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, 91, 91,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, 6,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, 6,370,370,370,370, +370,370,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, 6,370,370,370,370, /* 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, +370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, +370,370,370,370,370, 6,370,370,370,370,370,370,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, 6,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, 6, +370,370,370,370,370,370,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, 6, +370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, /* 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, +370,370,370,370,370,370,370,370,370, 6,370,370,370,370,370,370, +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, 6,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, 6,370,370,370,370,370,370,369,370, 91, 91, 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 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 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 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, + 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, + 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 168 */ - 89, 16, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 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, +539, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, /* 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, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, + 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 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 172 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 91, 91, 91, + +/* 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, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 174 */ + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13, + +/* block 175 */ + 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 91, 13, 13, 13, 91, 13, 91, 13, 91, 13, 91, 13, 13, 13, 91, + 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 91, 13, 91, 91, + 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* 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, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 177 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 178 */ +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 179 */ +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, + +/* block 180 */ +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 181 */ + 91, 16, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 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 182 */ + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + +/* block 183 */ + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + +/* block 184 */ +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476, 91, 91, }; diff --git a/harbour/src/3rd/pcre/pcrevutf.c b/harbour/src/3rd/pcre/pcrevutf.c index dcc9660fb5..c02b9922a9 100644 --- a/harbour/src/3rd/pcre/pcrevutf.c +++ b/harbour/src/3rd/pcre/pcrevutf.c @@ -54,42 +54,56 @@ 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) +_pcre_valid_utf8(USPTR string, int length, int *erroroffset) { #ifdef SUPPORT_UTF8 register USPTR p; @@ -97,84 +111,189 @@ register USPTR 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; + 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 = _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; + 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_UTF8 */ (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/harbour/src/3rd/pcre/ucp.h b/harbour/src/3rd/pcre/ucp.h index d68737e31d..34077fe07e 100644 --- a/harbour/src/3rd/pcre/ucp.h +++ b/harbour/src/3rd/pcre/ucp.h @@ -153,7 +153,11 @@ 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 }; #endif