diff -Nru pcre3-8.12/AUTHORS pcre3-8.31/AUTHORS --- pcre3-8.12/AUTHORS 2010-01-19 15:53:48.000000000 +0000 +++ pcre3-8.31/AUTHORS 2011-12-28 16:57:46.000000000 +0000 @@ -8,16 +8,38 @@ University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2010 University of Cambridge +Copyright (c) 1997-2012 University of Cambridge All rights reserved +PCRE JUST-IN-TIME COMPILATION SUPPORT +------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2012 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2012 Zoltan Herczeg +All rights reserved. + + THE C++ WRAPPER LIBRARY ----------------------- Written by: Google Inc. -Copyright (c) 2007-2010 Google Inc +Copyright (c) 2007-2012 Google Inc All rights reserved #### diff -Nru pcre3-8.12/CMakeLists.txt pcre3-8.31/CMakeLists.txt --- pcre3-8.12/CMakeLists.txt 2010-05-21 15:01:14.000000000 +0000 +++ pcre3-8.31/CMakeLists.txt 2012-02-26 17:07:08.000000000 +0000 @@ -36,11 +36,33 @@ # 2009-04-11 PH applied Christian Ehrlicher's patch to show compiler flags that # are set by specifying a release type. # 2010-01-02 PH added test for stdint.h -# 2010-03-02 PH addes test for inttypes.h +# 2010-03-02 PH added test for inttypes.h +# 2011-08-01 PH added PCREGREP_BUFSIZE +# 2011-08-22 PH added PCRE_SUPPORT_JIT +# 2011-09-06 PH modified WIN32 ADD_TEST line as suggested by Sergey Cherepanov +# 2011-09-06 PH added PCRE_SUPPORT_PCREGREP_JIT +# 2011-10-04 Sheri added support for including coff data in windows shared libraries +# compiled with MINGW if pcre.rc and/or pcreposix.rc are placed in +# the source dir by the user prior to building +# 2011-10-04 Sheri changed various add_test's to use exes' location built instead +# of DEBUG location only (likely only matters in MSVC) +# 2011-10-04 Sheri added scripts to provide needed variables to RunTest and +# RunGrepTest (used for UNIX and Msys) +# 2011-10-04 Sheri added scripts to provide needed variables and to execute +# RunTest.bat in Win32 (for effortless testing with "make test") +# 2011-10-04 Sheri Increased minimum required cmake version +# 2012-01-06 PH removed pcre_info.c and added pcre_string_utils.c +# 2012-01-10 Zoltan Herczeg added libpcre16 support +# 2012-01-13 Stephen Kelly added out of source build support +# 2012-01-17 PH applied Stephen Kelly's patch to parse the version data out +# of the configure.ac file +# 2012-02-26 PH added support for libedit PROJECT(PCRE C CXX) -CMAKE_MINIMUM_REQUIRED(VERSION 2.4.6) +# Increased minimum to 2.8.0 to support newer add_test features + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake @@ -48,6 +70,7 @@ FIND_PACKAGE( BZip2 ) FIND_PACKAGE( ZLIB ) FIND_PACKAGE( Readline ) +FIND_PACKAGE( Editline ) # Configuration checks @@ -85,6 +108,10 @@ SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries instead of static ones.") +OPTION(PCRE_BUILD_PCRE8 "Build 8 bit PCRE library" ON) + +OPTION(PCRE_BUILD_PCRE16 "Build 16 bit PCRE library" OFF) + OPTION(PCRE_BUILD_PCRECPP "Build the PCRE C++ library (pcrecpp)." ON) SET(PCRE_EBCDIC OFF CACHE BOOL @@ -99,6 +126,9 @@ SET(PCRE_MATCH_LIMIT_RECURSION "MATCH_LIMIT" CACHE STRING "Default limit on internal recursion. See MATCH_LIMIT_RECURSION in config.h.in for details.") +SET(PCREGREP_BUFSIZE "20480" CACHE STRING + "Buffer size parameter for pcregrep. See PCREGREP_BUFSIZE in config.h.in for details.") + SET(PCRE_NEWLINE "LF" CACHE STRING "What to recognize as a newline (one of CR, LF, CRLF, ANY, ANYCRLF).") @@ -108,11 +138,17 @@ SET(PCRE_POSIX_MALLOC_THRESHOLD "10" CACHE STRING "Threshold for malloc() usage. See POSIX_MALLOC_THRESHOLD in config.h.in for details.") -SET(PCRE_SUPPORT_UNICODE_PROPERTIES OFF CACHE BOOL - "Enable support for Unicode properties. (If set, UTF-8 support will be enabled as well)") +SET(PCRE_SUPPORT_JIT OFF CACHE BOOL + "Enable support for Just-in-time compiling.") + +SET(PCRE_SUPPORT_PCREGREP_JIT ON CACHE BOOL + "Enable use of Just-in-time compiling in pcregrep.") -SET(PCRE_SUPPORT_UTF8 OFF CACHE BOOL - "Enable support for the Unicode UTF-8 encoding.") +SET(PCRE_SUPPORT_UTF OFF CACHE BOOL + "Enable support for Unicode Transformation Format (UTF-8 and/or UTF-16) encoding.") + +SET(PCRE_SUPPORT_UNICODE_PROPERTIES OFF CACHE BOOL + "Enable support for Unicode properties (if set, UTF support will be enabled as well).") SET(PCRE_SUPPORT_BSR_ANYCRLF OFF CACHE BOOL "ON=Backslash-R matches only LF CR and CRLF, OFF=Backslash-R matches all Unicode Linebreaks") @@ -121,13 +157,6 @@ OPTION(PCRE_BUILD_PCREGREP "Build pcregrep" ON) OPTION(PCRE_BUILD_TESTS "Build the tests" ON) -IF (PCRE_BUILD_TESTS) - IF (NOT PCRE_BUILD_PCREGREP) - MESSAGE(STATUS "** Building tests requires pcregrep: PCRE_BUILD_PCREGREP forced ON") - SET(PCRE_BUILD_PCREGREP ON) - ENDIF(NOT PCRE_BUILD_PCREGREP) -ENDIF(PCRE_BUILD_TESTS) - IF (MINGW) OPTION(NON_STANDARD_LIB_PREFIX "ON=Shared libraries built in mingw will be named pcre.dll, etc., instead of libpcre.dll, etc." @@ -154,6 +183,14 @@ INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) ENDIF(PCRE_SUPPORT_LIBZ) +# editline lib +IF(EDITLINE_FOUND) + OPTION (PCRE_SUPPORT_LIBEDIT "Enable support for linking pcretest with libedit." OFF) +ENDIF(EDITLINE_FOUND) +IF(PCRE_SUPPORT_LIBEDIT) + INCLUDE_DIRECTORIES(${EDITLINE_INCLUDE_DIR}) +ENDIF(PCRE_SUPPORT_LIBEDIT) + # readline lib IF(READLINE_FOUND) OPTION (PCRE_SUPPORT_LIBREADLINE "Enable support for linking pcretest with libreadline." ON) @@ -190,18 +227,53 @@ SET(PCRE_STATIC 1) ENDIF(NOT BUILD_SHARED_LIBS) +IF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16) + MESSAGE(FATAL_ERROR "Either PCRE_BUILD_PCRE8 or PCRE_BUILD_PCRE16 must be enabled") +ENDIF(NOT PCRE_BUILD_PCRE8 AND NOT PCRE_BUILD_PCRE16) + +IF(PCRE_BUILD_PCRE8) + SET(SUPPORT_PCRE8 1) +ENDIF(PCRE_BUILD_PCRE8) + +IF(PCRE_BUILD_PCRE16) + SET(SUPPORT_PCRE16 1) +ENDIF(PCRE_BUILD_PCRE16) + +IF(PCRE_BUILD_PCRECPP AND NOT PCRE_BUILD_PCRE8) + MESSAGE(STATUS "** PCRE_BUILD_PCRE8 must be enabled for the C++ library support") + SET(PCRE_BUILD_PCRECPP OFF) +ENDIF(PCRE_BUILD_PCRECPP AND NOT PCRE_BUILD_PCRE8) + +IF(PCRE_BUILD_PCREGREP AND NOT PCRE_BUILD_PCRE8) + MESSAGE(STATUS "** PCRE_BUILD_PCRE8 must be enabled for the pcregrep program") + SET(PCRE_BUILD_PCREGREP OFF) +ENDIF(PCRE_BUILD_PCREGREP AND NOT PCRE_BUILD_PCRE8) + +IF(PCRE_SUPPORT_LIBREADLINE AND PCRE_SUPPORT_LIBEDIT) + MESSAGE(FATAL_ERROR "Only one of libreadline or libeditline can be specified") +ENDIF(PCRE_SUPPORT_LIBREADLINE AND PCRE_SUPPORT_LIBEDIT) + IF(PCRE_SUPPORT_BSR_ANYCRLF) SET(BSR_ANYCRLF 1) ENDIF(PCRE_SUPPORT_BSR_ANYCRLF) -IF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES) - SET(SUPPORT_UTF8 1) -ENDIF(PCRE_SUPPORT_UTF8 OR PCRE_SUPPORT_UNICODE_PROPERTIES) +IF(PCRE_SUPPORT_UTF OR PCRE_SUPPORT_UNICODE_PROPERTIES) + SET(SUPPORT_UTF 1) + SET(PCRE_SUPPORT_UTF ON) +ENDIF(PCRE_SUPPORT_UTF OR PCRE_SUPPORT_UNICODE_PROPERTIES) IF(PCRE_SUPPORT_UNICODE_PROPERTIES) SET(SUPPORT_UCP 1) ENDIF(PCRE_SUPPORT_UNICODE_PROPERTIES) +IF(PCRE_SUPPORT_JIT) + SET(SUPPORT_JIT 1) +ENDIF(PCRE_SUPPORT_JIT) + +IF(PCRE_SUPPORT_PCREGREP_JIT) + SET(SUPPORT_PCREGREP_JIT 1) +ENDIF(PCRE_SUPPORT_PCREGREP_JIT) + # This next one used to contain # SET(PCRETEST_LIBS ${READLINE_LIBRARY}) # but I was advised to add the NCURSES test as well, along with @@ -213,6 +285,13 @@ SET(PCRETEST_LIBS ${READLINE_LIBRARY} ${NCURSES_LIBRARY}) ENDIF(PCRE_SUPPORT_LIBREADLINE) +# libedit is a plug-compatible alternative to libreadline + +IF(PCRE_SUPPORT_LIBEDIT) + SET(SUPPORT_LIBEDIT 1) + SET(PCRETEST_LIBS ${EDITLINE_LIBRARY} ${NCURSES_LIBRARY}) +ENDIF(PCRE_SUPPORT_LIBEDIT) + IF(PCRE_SUPPORT_LIBZ) SET(SUPPORT_LIBZ 1) SET(PCREGREP_LIBS ${PCREGREP_LIBS} ${ZLIB_LIBRARIES}) @@ -258,9 +337,29 @@ ${PROJECT_BINARY_DIR}/config.h @ONLY) -CONFIGURE_FILE(pcre.h.generic +# Parse version numbers and date out of configure.ac + +file(STRINGS ${PROJECT_SOURCE_DIR}/configure.ac + configure_lines + LIMIT_COUNT 50 # Read only the first 50 lines of the file +) + +set(SEARCHED_VARIABLES "pcre_major" "pcre_minor" "pcre_prerelease" "pcre_date") +foreach(configure_line ${configure_lines}) + foreach(_substitution_variable ${SEARCHED_VARIABLES}) + string(TOUPPER ${_substitution_variable} _substitution_variable_upper) + if (NOT ${_substitution_variable_upper}) + string(REGEX MATCH "m4_define\\(${_substitution_variable}, \\[(.*)\\]" MACTHED_STRING ${configure_line}) + if (CMAKE_MATCH_1) + set(${_substitution_variable_upper} ${CMAKE_MATCH_1}) + endif() + endif() + endforeach() +endforeach() + +CONFIGURE_FILE(pcre.h.in ${PROJECT_BINARY_DIR}/pcre.h - COPYONLY) + @ONLY) # What about pcre-config and libpcre.pc? @@ -299,8 +398,10 @@ SET(PCRE_HEADERS ${PROJECT_BINARY_DIR}/pcre.h) +IF(PCRE_BUILD_PCRE8) SET(PCRE_SOURCES - ${PROJECT_BINARY_DIR}/pcre_chartables.c + pcre_byte_order.c + pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c @@ -308,14 +409,14 @@ pcre_fullinfo.c pcre_get.c pcre_globals.c - pcre_info.c - pcre_newline.c + pcre_jit_compile.c pcre_maketables.c + pcre_newline.c pcre_ord2utf8.c pcre_refcount.c + pcre_string_utils.c pcre_study.c pcre_tables.c - pcre_try_flipped.c pcre_ucd.c pcre_valid_utf8.c pcre_version.c @@ -326,6 +427,58 @@ SET(PCREPOSIX_SOURCES pcreposix.c) +ENDIF(PCRE_BUILD_PCRE8) + +IF(PCRE_BUILD_PCRE16) +SET(PCRE16_SOURCES + pcre16_byte_order.c + pcre16_chartables.c + pcre16_compile.c + pcre16_config.c + pcre16_dfa_exec.c + pcre16_exec.c + pcre16_fullinfo.c + pcre16_get.c + pcre16_globals.c + pcre16_jit_compile.c + pcre16_maketables.c + pcre16_newline.c + pcre16_ord2utf16.c + pcre16_refcount.c + pcre16_string_utils.c + pcre16_study.c + pcre16_tables.c + pcre16_ucd.c + pcre16_utf16_utils.c + pcre16_valid_utf16.c + pcre16_version.c + pcre16_xclass.c +) +ENDIF(PCRE_BUILD_PCRE16) + +IF(MINGW AND NOT PCRE_STATIC) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcre.o +PRE-LINK +COMMAND windres ARGS pcre.rc pcre.o +WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +COMMENT Using pcre coff info in mingw build) +SET(PCRE_SOURCES + ${PCRE_SOURCES} ${PROJECT_SOURCE_DIR}/pcre.o +) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcre.rc) +IF (EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/pcreposix.o +PRE-LINK +COMMAND windres ARGS pcreposix.rc pcreposix.o +WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +COMMENT Using pcreposix coff info in mingw build) +SET(PCREPOSIX_SOURCES + ${PCREPOSIX_SOURCES} ${PROJECT_SOURCE_DIR}/pcreposix.o +) +ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) +ENDIF(MINGW AND NOT PCRE_STATIC) + SET(PCRECPP_HEADERS pcrecpp.h pcre_scanner.h @@ -358,11 +511,13 @@ # Libraries # pcre +IF(PCRE_BUILD_PCRE8) ADD_LIBRARY(pcre ${PCRE_HEADERS} ${PCRE_SOURCES} ${PROJECT_BINARY_DIR}/config.h) SET(targets ${targets} pcre) ADD_LIBRARY(pcreposix ${PCREPOSIX_HEADERS} ${PCREPOSIX_SOURCES}) SET(targets ${targets} pcreposix) TARGET_LINK_LIBRARIES(pcreposix pcre) + IF(MINGW AND NOT PCRE_STATIC) IF(NON_STANDARD_LIB_PREFIX) SET_TARGET_PROPERTIES(pcre pcreposix @@ -377,12 +532,33 @@ ENDIF(NON_STANDARD_LIB_SUFFIX) ENDIF(MINGW AND NOT PCRE_STATIC) +ENDIF(PCRE_BUILD_PCRE8) + +IF(PCRE_BUILD_PCRE16) +ADD_LIBRARY(pcre16 ${PCRE_HEADERS} ${PCRE16_SOURCES} ${PROJECT_BINARY_DIR}/config.h) +SET(targets ${targets} pcre16) + +IF(MINGW AND NOT PCRE_STATIC) + IF(NON_STANDARD_LIB_PREFIX) + SET_TARGET_PROPERTIES(pcre16 + PROPERTIES PREFIX "" + ) + ENDIF(NON_STANDARD_LIB_PREFIX) + + IF(NON_STANDARD_LIB_SUFFIX) + SET_TARGET_PROPERTIES(pcre16 + PROPERTIES SUFFIX "-0.dll" + ) + ENDIF(NON_STANDARD_LIB_SUFFIX) +ENDIF(MINGW AND NOT PCRE_STATIC) + +ENDIF(PCRE_BUILD_PCRE16) # pcrecpp IF(PCRE_BUILD_PCRECPP) - ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES}) +ADD_LIBRARY(pcrecpp ${PCRECPP_HEADERS} ${PCRECPP_SOURCES}) SET(targets ${targets} pcrecpp) - TARGET_LINK_LIBRARIES(pcrecpp pcre) +TARGET_LINK_LIBRARIES(pcrecpp pcre) IF(MINGW AND NOT PCRE_STATIC) IF(NON_STANDARD_LIB_PREFIX) @@ -417,14 +593,40 @@ TARGET_LINK_LIBRARIES(pcregrep pcreposix ${PCREGREP_LIBS}) ENDIF(PCRE_BUILD_PCREGREP) - # Testing IF(PCRE_BUILD_TESTS) ENABLE_TESTING() - ADD_EXECUTABLE(pcretest pcretest.c) + SET(PCRETEST_SOURCES pcretest.c) + IF(PCRE_BUILD_PCRE8) + LIST(APPEND PCRETEST_SOURCES pcre_printint.c) + ENDIF(PCRE_BUILD_PCRE8) + IF(PCRE_BUILD_PCRE16) + LIST(APPEND PCRETEST_SOURCES pcre16_printint.c) + ENDIF(PCRE_BUILD_PCRE16) + + ADD_EXECUTABLE(pcretest ${PCRETEST_SOURCES}) SET(targets ${targets} pcretest) - TARGET_LINK_LIBRARIES(pcretest pcreposix ${PCRETEST_LIBS}) + IF(PCRE_BUILD_PCRE8) + LIST(APPEND PCRETEST_LIBS pcreposix pcre) + ENDIF(PCRE_BUILD_PCRE8) + IF(PCRE_BUILD_PCRE16) + LIST(APPEND PCRETEST_LIBS pcre16) + ENDIF(PCRE_BUILD_PCRE16) + TARGET_LINK_LIBRARIES(pcretest ${PCRETEST_LIBS}) + + IF(PCRE_SUPPORT_JIT) + ADD_EXECUTABLE(pcre_jit_test pcre_jit_test.c) + SET(targets ${targets} pcre_jit_test) + SET(PCRE_JIT_TEST_LIBS ) + IF(PCRE_BUILD_PCRE8) + LIST(APPEND PCRE_JIT_TEST_LIBS pcre) + ENDIF(PCRE_BUILD_PCRE8) + IF(PCRE_BUILD_PCRE16) + LIST(APPEND PCRE_JIT_TEST_LIBS pcre16) + ENDIF(PCRE_BUILD_PCRE16) + TARGET_LINK_LIBRARIES(pcre_jit_test ${PCRE_JIT_TEST_LIBS}) + ENDIF(PCRE_SUPPORT_JIT) IF(PCRE_BUILD_PCRECPP) ADD_EXECUTABLE(pcrecpp_unittest pcrecpp_unittest.cc) @@ -436,7 +638,6 @@ ) ENDIF(MINGW AND NON_STANDARD_LIB_NAMES AND NOT PCRE_STATIC) - ADD_EXECUTABLE(pcre_scanner_unittest pcre_scanner_unittest.cc) SET(targets ${targets} pcre_scanner_unittest) TARGET_LINK_LIBRARIES(pcre_scanner_unittest pcrecpp) @@ -446,42 +647,114 @@ TARGET_LINK_LIBRARIES(pcre_stringpiece_unittest pcrecpp) ENDIF(PCRE_BUILD_PCRECPP) - GET_TARGET_PROPERTY(PCREGREP_EXE pcregrep DEBUG_LOCATION) + # exes in Debug location tested by the RunTest shell script + # via "make test" + IF(PCRE_BUILD_PCREGREP) + GET_TARGET_PROPERTY(PCREGREP_EXE pcregrep DEBUG_LOCATION) + ENDIF(PCRE_BUILD_PCREGREP) + GET_TARGET_PROPERTY(PCRETEST_EXE pcretest DEBUG_LOCATION) - # Write out a CTest configuration file that sets some needed environment - # variables for the test scripts. +# ================================================= + # Write out a CTest configuration file # FILE(WRITE ${PROJECT_BINARY_DIR}/CTestCustom.ctest "# This is a generated file. - SET(ENV{srcdir} ${PROJECT_SOURCE_DIR}) - SET(ENV{pcregrep} ${PCREGREP_EXE}) - SET(ENV{pcretest} ${PCRETEST_EXE}) - ") +MESSAGE(\"When testing is complete, review test output in the +${PROJECT_BINARY_DIR}/Testing/Temporary folder.\") +MESSAGE(\"\") +") + + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_test.sh + "#! /bin/sh +# This is a generated file. +srcdir=${PROJECT_SOURCE_DIR} +pcretest=${PCRETEST_EXE} +source ${PROJECT_SOURCE_DIR}/RunTest +if test \"$?\" != \"0\"; then exit 1; fi +# End +") IF(UNIX) - ADD_TEST(pcre_test ${PROJECT_SOURCE_DIR}/RunTest) - ADD_TEST(pcre_grep_test ${PROJECT_SOURCE_DIR}/RunGrepTest) + ADD_TEST(pcre_test sh ${PROJECT_BINARY_DIR}/pcre_test.sh) ENDIF(UNIX) + + IF(PCRE_BUILD_PCREGREP) + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_grep_test.sh + "#! /bin/sh +# This is a generated file. +srcdir=${PROJECT_SOURCE_DIR} +pcregrep=${PCREGREP_EXE} +pcretest=${PCRETEST_EXE} +source ${PROJECT_SOURCE_DIR}/RunGrepTest +if test \"$?\" != \"0\"; then exit 1; fi +# End +") + + IF(UNIX) + ADD_TEST(pcre_grep_test sh ${PROJECT_BINARY_DIR}/pcre_grep_test.sh) + ENDIF(UNIX) + ENDIF(PCRE_BUILD_PCREGREP) + IF(WIN32) - ADD_TEST(pcre_test cmd /C ${PROJECT_SOURCE_DIR}/RunTest.bat) + # Provide environment for executing the bat file version of RunTest + string(REPLACE "/" "\\" winsrc "${PROJECT_SOURCE_DIR}") + + FILE(WRITE ${PROJECT_BINARY_DIR}/pcre_test.txt + "\@REM This is a generated file. +\@Echo off +setlocal +SET\ srcdir=\${srcdir} +SET\ pcretest=\${pcretest} +call \"\${srcdir}\\RunTest.Bat\" +if errorlevel 1 exit /b 1 +echo RunTest.bat tests successfully completed +") + + FILE(WRITE ${PROJECT_BINARY_DIR}/BatDriver.cmake + "# This is a generated file. +# this script is run with arguments via the cmake command in add_test(NAME pcre_test_bat) +# BatDriver feeds the actual location of pcretest.exe +FILE(TO_NATIVE_PATH \${pcretestx} pcretest) +FILE(TO_NATIVE_PATH \${srcdirx} srcdir) +configure_file(\"\${bindirx}/pcre_test.txt\" \"\${bindirx}/pcre_test.bat\") +# MESSAGE(\"cmake\ variable\ pcretest\ is\ \${pcretest}\") +# STRING(REPLACE \" \" \"\\ \" bindir \${bindirx}) +MESSAGE(\"COMMAND pcre_test.bat \") +EXECUTE_PROCESS(COMMAND pcre_test.bat +WORKING_DIRECTORY . +OUTPUT_VARIABLE batoutput) +MESSAGE(\"OUTPUT: \${batoutput}\") +") + + ADD_TEST(NAME pcre_test_bat + COMMAND ${CMAKE_COMMAND} -D bindirx=${PROJECT_BINARY_DIR} -D srcdirx=${PROJECT_SOURCE_DIR} -D pcretestx=$ -P "${PROJECT_BINARY_DIR}/BatDriver.cmake") + SET_TESTS_PROPERTIES(pcre_test_bat PROPERTIES + PASS_REGULAR_EXPRESSION "RunTest\\.bat tests successfully completed") + + IF("$ENV{OSTYPE}" STREQUAL "msys") + # Both the sh and bat file versions of RunTest are run if make test is used + # in msys + ADD_TEST(pcre_test_sh sh.exe ${PROJECT_BINARY_DIR}/pcre_test.sh) + IF(PCRE_BUILD_PCREGREP) + ADD_TEST(pcre_grep_test sh.exe ${PROJECT_BINARY_DIR}/pcre_grep_test.sh) + ENDIF(PCRE_BUILD_PCREGREP) + ENDIF("$ENV{OSTYPE}" STREQUAL "msys") + ENDIF(WIN32) - GET_TARGET_PROPERTY(PCRECPP_UNITTEST_EXE - pcrecpp_unittest - DEBUG_LOCATION) - - GET_TARGET_PROPERTY(PCRE_SCANNER_UNITTEST_EXE - pcre_scanner_unittest - DEBUG_LOCATION) - - GET_TARGET_PROPERTY(PCRE_STRINGPIECE_UNITTEST_EXE - pcre_stringpiece_unittest - DEBUG_LOCATION) - - ADD_TEST(pcrecpp_test ${PCRECPP_UNITTEST_EXE}) - ADD_TEST(pcre_scanner_test ${PCRE_SCANNER_UNITTEST_EXE}) - ADD_TEST(pcre_stringpiece_test ${PCRE_STRINGPIECE_UNITTEST_EXE}) + # Changed to accommodate testing whichever location was just built + + IF(PCRE_SUPPORT_JIT) + ADD_TEST(pcre_jit_test pcre_jit_test) + ENDIF(PCRE_SUPPORT_JIT) + + IF(PCRE_BUILD_PCRECPP) + ADD_TEST(pcrecpp_test pcrecpp_unittest) + ADD_TEST(pcre_scanner_test pcre_scanner_unittest) + ADD_TEST(pcre_stringpiece_test pcre_stringpiece_unittest) + ENDIF(PCRE_BUILD_PCRECPP) + ENDIF(PCRE_BUILD_TESTS) # Installation @@ -511,7 +784,6 @@ SET(man3 ${man3_new}) ENDIF(PCRE_BUILD_PCRECPP) - INSTALL(FILES ${man1} DESTINATION man/man1) INSTALL(FILES ${man3} DESTINATION man/man3) INSTALL(FILES ${html} DESTINATION share/doc/pcre/html) @@ -541,8 +813,11 @@ MESSAGE(STATUS " C compiler flags ................ : ${CMAKE_C_FLAGS}${cfsp}${CMAKE_C_FLAGS_${buildtype}}") MESSAGE(STATUS " C++ compiler flags .............. : ${CMAKE_CXX_FLAGS}${cxxfsp}${CMAKE_CXX_FLAGS_${buildtype}}") MESSAGE(STATUS "") + MESSAGE(STATUS " Build 8 bit PCRE library ........ : ${PCRE_BUILD_PCRE8}") + MESSAGE(STATUS " Build 16 bit PCRE library ....... : ${PCRE_BUILD_PCRE16}") MESSAGE(STATUS " Build C++ library ............... : ${PCRE_BUILD_PCRECPP}") - MESSAGE(STATUS " Enable UTF-8 support ............ : ${PCRE_SUPPORT_UNICODE_PROPERTIES}") + MESSAGE(STATUS " Enable JIT compiling support .... : ${PCRE_SUPPORT_JIT}") + MESSAGE(STATUS " Enable UTF support .............. : ${PCRE_SUPPORT_UTF}") MESSAGE(STATUS " Unicode properties .............. : ${PCRE_SUPPORT_UNICODE_PROPERTIES}") MESSAGE(STATUS " Newline char/sequence ........... : ${PCRE_NEWLINE}") MESSAGE(STATUS " \\R matches only ANYCRLF ......... : ${PCRE_SUPPORT_BSR_ANYCRLF}") @@ -556,22 +831,31 @@ MESSAGE(STATUS " Build shared libs ............... : ${BUILD_SHARED_LIBS}") MESSAGE(STATUS " Build static libs ............... : ${BUILD_STATIC_LIBS}") MESSAGE(STATUS " Build pcregrep .................. : ${PCRE_BUILD_PCREGREP}") - MESSAGE(STATUS " Build tests (implies pcretest) .. : ${PCRE_BUILD_TESTS}") + MESSAGE(STATUS " Enable JIT in pcregrep .......... : ${PCRE_SUPPORT_PCREGREP_JIT}") + MESSAGE(STATUS " Buffer size for pcregrep ........ : ${PCREGREP_BUFSIZE}") + MESSAGE(STATUS " Build tests (implies pcretest .. : ${PCRE_BUILD_TESTS}") + MESSAGE(STATUS " and pcregrep)") IF(ZLIB_FOUND) MESSAGE(STATUS " Link pcregrep with libz ......... : ${PCRE_SUPPORT_LIBZ}") ELSE(ZLIB_FOUND) - MESSAGE(STATUS " Link pcregrep with libz ......... : None" ) + MESSAGE(STATUS " Link pcregrep with libz ......... : Library not found" ) ENDIF(ZLIB_FOUND) IF(BZIP2_FOUND) MESSAGE(STATUS " Link pcregrep with libbz2 ....... : ${PCRE_SUPPORT_LIBBZ2}") ELSE(BZIP2_FOUND) - MESSAGE(STATUS " Link pcregrep with libbz2 ....... : None" ) + MESSAGE(STATUS " Link pcregrep with libbz2 ....... : Library not found" ) ENDIF(BZIP2_FOUND) - IF(NOT PCRE_SUPPORT_LIBREADLINE) - MESSAGE(STATUS " Link pcretest with libreadline .. : None" ) - ELSE(NOT PCRE_SUPPORT_LIBREADLINE) + IF(EDITLINE_FOUND) + MESSAGE(STATUS " Link pcretest with libeditline .. : ${PCRE_SUPPORT_LIBEDIT}") + ELSE(EDITLINE_FOUND) + MESSAGE(STATUS " Link pcretest with libeditline .. : Library not found" ) + ENDIF(EDITLINE_FOUND) + IF(READLINE_FOUND) MESSAGE(STATUS " Link pcretest with libreadline .. : ${PCRE_SUPPORT_LIBREADLINE}") - ENDIF(NOT PCRE_SUPPORT_LIBREADLINE) + ELSE(READLINE_FOUND) + MESSAGE(STATUS " Link pcretest with libreadline .. : Library not found" ) + ENDIF(READLINE_FOUND) + IF(MINGW AND NOT PCRE_STATIC) MESSAGE(STATUS " Non-standard dll names (prefix) . : ${NON_STANDARD_LIB_PREFIX}") MESSAGE(STATUS " Non-standard dll names (suffix) . : ${NON_STANDARD_LIB_SUFFIX}") diff -Nru pcre3-8.12/ChangeLog pcre3-8.31/ChangeLog --- pcre3-8.12/ChangeLog 2011-01-15 17:26:25.000000000 +0000 +++ pcre3-8.31/ChangeLog 2012-07-06 08:54:44.000000000 +0000 @@ -1,6 +1,699 @@ ChangeLog for PCRE ------------------ +Version 8.31 06-July-2012 +------------------------- + +1. Fixing a wrong JIT test case and some compiler warnings. + +2. Removed a bashism from the RunTest script. + +3. Add a cast to pcre_exec.c to fix the warning "unary minus operator applied + to unsigned type, result still unsigned" that was given by an MS compiler + on encountering the code "-sizeof(xxx)". + +4. Partial matching support is added to the JIT compiler. + +5. Fixed several bugs concerned with partial matching of items that consist + of more than one character: + + (a) /^(..)\1/ did not partially match "aba" because checking references was + done on an "all or nothing" basis. This also applied to repeated + references. + + (b) \R did not give a hard partial match if \r was found at the end of the + subject. + + (c) \X did not give a hard partial match after matching one or more + characters at the end of the subject. + + (d) When newline was set to CRLF, a pattern such as /a$/ did not recognize + a partial match for the string "\r". + + (e) When newline was set to CRLF, the metacharacter "." did not recognize + a partial match for a CR character at the end of the subject string. + +6. If JIT is requested using /S++ or -s++ (instead of just /S+ or -s+) when + running pcretest, the text "(JIT)" added to the output whenever JIT is + actually used to run the match. + +7. Individual JIT compile options can be set in pcretest by following -s+[+] + or /S+[+] with a digit between 1 and 7. + +8. OP_NOT now supports any UTF character not just single-byte ones. + +9. (*MARK) control verb is now supported by the JIT compiler. + +10. The command "./RunTest list" lists the available tests without actually + running any of them. (Because I keep forgetting what they all are.) + +11. Add PCRE_INFO_MAXLOOKBEHIND. + +12. Applied a (slightly modified) user-supplied patch that improves performance + when the heap is used for recursion (compiled with --disable-stack-for- + recursion). Instead of malloc and free for each heap frame each time a + logical recursion happens, frames are retained on a chain and re-used where + possible. This sometimes gives as much as 30% improvement. + +13. As documented, (*COMMIT) is now confined to within a recursive subpattern + call. + +14. As documented, (*COMMIT) is now confined to within a positive assertion. + +15. It is now possible to link pcretest with libedit as an alternative to + libreadline. + +16. (*COMMIT) control verb is now supported by the JIT compiler. + +17. The Unicode data tables have been updated to Unicode 6.1.0. + +18. Added --file-list option to pcregrep. + +19. Added binary file support to pcregrep, including the -a, --binary-files, + -I, and --text options. + +20. The madvise function is renamed for posix_madvise for QNX compatibility + reasons. Fixed by Giuseppe D'Angelo. + +21. Fixed a bug for backward assertions with REVERSE 0 in the JIT compiler. + +22. Changed the option for creating symbolic links for 16-bit man pages from + -s to -sf so that re-installing does not cause issues. + +23. Support PCRE_NO_START_OPTIMIZE in JIT as (*MARK) support requires it. + +24. Fixed a very old bug in pcretest that caused errors with restarted DFA + matches in certain environments (the workspace was not being correctly + retained). Also added to pcre_dfa_exec() a simple plausibility check on + some of the workspace data at the beginning of a restart. + +25. \s*\R was auto-possessifying the \s* when it should not, whereas \S*\R + was not doing so when it should - probably a typo introduced by SVN 528 + (change 8.10/14). + +26. When PCRE_UCP was not set, \w+\x{c4} was incorrectly auto-possessifying the + \w+ when the character tables indicated that \x{c4} was a word character. + There were several related cases, all because the tests for doing a table + lookup were testing for characters less than 127 instead of 255. + +27. If a pattern contains capturing parentheses that are not used in a match, + their slots in the ovector are set to -1. For those that are higher than + any matched groups, this happens at the end of processing. In the case when + there were back references that the ovector was too small to contain + (causing temporary malloc'd memory to be used during matching), and the + highest capturing number was not used, memory off the end of the ovector + was incorrectly being set to -1. (It was using the size of the temporary + memory instead of the true size.) + +28. To catch bugs like 27 using valgrind, when pcretest is asked to specify an + ovector size, it uses memory at the end of the block that it has got. + +29. Check for an overlong MARK name and give an error at compile time. The + limit is 255 for the 8-bit library and 65535 for the 16-bit library. + +30. JIT compiler update. + +31. JIT is now supported on jailbroken iOS devices. Thanks for Ruiger + Rill for the patch. + +32. Put spaces around SLJIT_PRINT_D in the JIT compiler. Required by CXX11. + +33. Variable renamings in the PCRE-JIT compiler. No functionality change. + +34. Fixed typos in pcregrep: in two places there was SUPPORT_LIBZ2 instead of + SUPPORT_LIBBZ2. This caused a build problem when bzip2 but not gzip (zlib) + was enabled. + +35. Improve JIT code generation for greedy plus quantifier. + +36. When /((?:a?)*)*c/ or /((?>a?)*)*c/ was matched against "aac", it set group + 1 to "aa" instead of to an empty string. The bug affected repeated groups + that could potentially match an empty string. + +37. Optimizing single character iterators in JIT. + +38. Wide characters specified with \uxxxx in JavaScript mode are now subject to + the same checks as \x{...} characters in non-JavaScript mode. Specifically, + codepoints that are too big for the mode are faulted, and in a UTF mode, + disallowed codepoints are also faulted. + +39. If PCRE was compiled with UTF support, in three places in the DFA + matcher there was code that should only have been obeyed in UTF mode, but + was being obeyed unconditionally. In 8-bit mode this could cause incorrect + processing when bytes with values greater than 127 were present. In 16-bit + mode the bug would be provoked by values in the range 0xfc00 to 0xdc00. In + both cases the values are those that cannot be the first data item in a UTF + character. The three items that might have provoked this were recursions, + possessively repeated groups, and atomic groups. + +40. Ensure that libpcre is explicitly listed in the link commands for pcretest + and pcregrep, because some OS require shared objects to be explicitly + passed to ld, causing the link step to fail if they are not. + +41. There were two incorrect #ifdefs in pcre_study.c, meaning that, in 16-bit + mode, patterns that started with \h* or \R* might be incorrectly matched. + + +Version 8.30 04-February-2012 +----------------------------- + +1. Renamed "isnumber" as "is_a_number" because in some Mac environments this + name is defined in ctype.h. + +2. Fixed a bug in fixed-length calculation for lookbehinds that would show up + only in quite long subpatterns. + +3. Removed the function pcre_info(), which has been obsolete and deprecated + since it was replaced by pcre_fullinfo() in February 2000. + +4. For a non-anchored pattern, if (*SKIP) was given with a name that did not + match a (*MARK), and the match failed at the start of the subject, a + reference to memory before the start of the subject could occur. This bug + was introduced by fix 17 of release 8.21. + +5. A reference to an unset group with zero minimum repetition was giving + totally wrong answers (in non-JavaScript-compatibility mode). For example, + /(another)?(\1?)test/ matched against "hello world test". This bug was + introduced in release 8.13. + +6. Add support for 16-bit character strings (a large amount of work involving + many changes and refactorings). + +7. RunGrepTest failed on msys because \r\n was replaced by whitespace when the + command "pattern=`printf 'xxx\r\njkl'`" was run. The pattern is now taken + from a file. + +8. Ovector size of 2 is also supported by JIT based pcre_exec (the ovector size + rounding is not applied in this particular case). + +9. The invalid Unicode surrogate codepoints U+D800 to U+DFFF are now rejected + if they appear, or are escaped, in patterns. + +10. Get rid of a number of -Wunused-but-set-variable warnings. + +11. The pattern /(?=(*:x))(q|)/ matches an empty string, and returns the mark + "x". The similar pattern /(?=(*:x))((*:y)q|)/ did not return a mark at all. + Oddly, Perl behaves the same way. PCRE has been fixed so that this pattern + also returns the mark "x". This bug applied to capturing parentheses, + non-capturing parentheses, and atomic parentheses. It also applied to some + assertions. + +12. Stephen Kelly's patch to CMakeLists.txt allows it to parse the version + information out of configure.ac instead of relying on pcre.h.generic, which + is not stored in the repository. + +13. Applied Dmitry V. Levin's patch for a more portable method for linking with + -lreadline. + +14. ZH added PCRE_CONFIG_JITTARGET; added its output to pcretest -C. + +15. Applied Graycode's patch to put the top-level frame on the stack rather + than the heap when not using the stack for recursion. This gives a + performance improvement in many cases when recursion is not deep. + +16. Experimental code added to "pcretest -C" to output the stack frame size. + + +Version 8.21 12-Dec-2011 +------------------------ + +1. Updating the JIT compiler. + +2. JIT compiler now supports OP_NCREF, OP_RREF and OP_NRREF. New test cases + are added as well. + +3. Fix cache-flush issue on PowerPC (It is still an experimental JIT port). + PCRE_EXTRA_TABLES is not suported by JIT, and should be checked before + calling _pcre_jit_exec. Some extra comments are added. + +4. (*MARK) settings inside atomic groups that do not contain any capturing + parentheses, for example, (?>a(*:m)), were not being passed out. This bug + was introduced by change 18 for 8.20. + +5. Supporting of \x, \U and \u in JavaScript compatibility mode based on the + ECMA-262 standard. + +6. Lookbehinds such as (?<=a{2}b) that contained a fixed repetition were + erroneously being rejected as "not fixed length" if PCRE_CASELESS was set. + This bug was probably introduced by change 9 of 8.13. + +7. While fixing 6 above, I noticed that a number of other items were being + incorrectly rejected as "not fixed length". This arose partly because newer + opcodes had not been added to the fixed-length checking code. I have (a) + corrected the bug and added tests for these items, and (b) arranged for an + error to occur if an unknown opcode is encountered while checking for fixed + length instead of just assuming "not fixed length". The items that were + rejected were: (*ACCEPT), (*COMMIT), (*FAIL), (*MARK), (*PRUNE), (*SKIP), + (*THEN), \h, \H, \v, \V, and single character negative classes with fixed + repetitions, e.g. [^a]{3}, with and without PCRE_CASELESS. + +8. A possessively repeated conditional subpattern such as (?(?=c)c|d)++ was + being incorrectly compiled and would have given unpredicatble results. + +9. A possessively repeated subpattern with minimum repeat count greater than + one behaved incorrectly. For example, (A){2,}+ behaved as if it was + (A)(A)++ which meant that, after a subsequent mismatch, backtracking into + the first (A) could occur when it should not. + +10. Add a cast and remove a redundant test from the code. + +11. JIT should use pcre_malloc/pcre_free for allocation. + +12. Updated pcre-config so that it no longer shows -L/usr/lib, which seems + best practice nowadays, and helps with cross-compiling. (If the exec_prefix + is anything other than /usr, -L is still shown). + +13. In non-UTF-8 mode, \C is now supported in lookbehinds and DFA matching. + +14. Perl does not support \N without a following name in a [] class; PCRE now + also gives an error. + +15. If a forward reference was repeated with an upper limit of around 2000, + it caused the error "internal error: overran compiling workspace". The + maximum number of forward references (including repeats) was limited by the + internal workspace, and dependent on the LINK_SIZE. The code has been + rewritten so that the workspace expands (via pcre_malloc) if necessary, and + the default depends on LINK_SIZE. There is a new upper limit (for safety) + of around 200,000 forward references. While doing this, I also speeded up + the filling in of repeated forward references. + +16. A repeated forward reference in a pattern such as (a)(?2){2}(.) was + incorrectly expecting the subject to contain another "a" after the start. + +17. When (*SKIP:name) is activated without a corresponding (*MARK:name) earlier + in the match, the SKIP should be ignored. This was not happening; instead + the SKIP was being treated as NOMATCH. For patterns such as + /A(*MARK:A)A+(*SKIP:B)Z|AAC/ this meant that the AAC branch was never + tested. + +18. The behaviour of (*MARK), (*PRUNE), and (*THEN) has been reworked and is + now much more compatible with Perl, in particular in cases where the result + is a non-match for a non-anchored pattern. For example, if + /b(*:m)f|a(*:n)w/ is matched against "abc", the non-match returns the name + "m", where previously it did not return a name. A side effect of this + change is that for partial matches, the last encountered mark name is + returned, as for non matches. A number of tests that were previously not + Perl-compatible have been moved into the Perl-compatible test files. The + refactoring has had the pleasing side effect of removing one argument from + the match() function, thus reducing its stack requirements. + +19. If the /S+ option was used in pcretest to study a pattern using JIT, + subsequent uses of /S (without +) incorrectly behaved like /S+. + +21. Retrieve executable code size support for the JIT compiler and fixing + some warnings. + +22. A caseless match of a UTF-8 character whose other case uses fewer bytes did + not work when the shorter character appeared right at the end of the + subject string. + +23. Added some (int) casts to non-JIT modules to reduce warnings on 64-bit + systems. + +24. Added PCRE_INFO_JITSIZE to pass on the value from (21) above, and also + output it when the /M option is used in pcretest. + +25. The CheckMan script was not being included in the distribution. Also, added + an explicit "perl" to run Perl scripts from the PrepareRelease script + because this is reportedly needed in Windows. + +26. If study data was being save in a file and studying had not found a set of + "starts with" bytes for the pattern, the data written to the file (though + never used) was taken from uninitialized memory and so caused valgrind to + complain. + +27. Updated RunTest.bat as provided by Sheri Pierce. + +28. Fixed a possible uninitialized memory bug in pcre_jit_compile.c. + +29. Computation of memory usage for the table of capturing group names was + giving an unnecessarily large value. + + +Version 8.20 21-Oct-2011 +------------------------ + +1. Change 37 of 8.13 broke patterns like [:a]...[b:] because it thought it had + a POSIX class. After further experiments with Perl, which convinced me that + Perl has bugs and confusions, a closing square bracket is no longer allowed + in a POSIX name. This bug also affected patterns with classes that started + with full stops. + +2. If a pattern such as /(a)b|ac/ is matched against "ac", there is no + captured substring, but while checking the failing first alternative, + substring 1 is temporarily captured. If the output vector supplied to + pcre_exec() was not big enough for this capture, the yield of the function + was still zero ("insufficient space for captured substrings"). This cannot + be totally fixed without adding another stack variable, which seems a lot + of expense for a edge case. However, I have improved the situation in cases + such as /(a)(b)x|abc/ matched against "abc", where the return code + indicates that fewer than the maximum number of slots in the ovector have + been set. + +3. Related to (2) above: when there are more back references in a pattern than + slots in the output vector, pcre_exec() uses temporary memory during + matching, and copies in the captures as far as possible afterwards. It was + using the entire output vector, but this conflicts with the specification + that only 2/3 is used for passing back captured substrings. Now it uses + only the first 2/3, for compatibility. This is, of course, another edge + case. + +4. Zoltan Herczeg's just-in-time compiler support has been integrated into the + main code base, and can be used by building with --enable-jit. When this is + done, pcregrep automatically uses it unless --disable-pcregrep-jit or the + runtime --no-jit option is given. + +5. When the number of matches in a pcre_dfa_exec() run exactly filled the + ovector, the return from the function was zero, implying that there were + other matches that did not fit. The correct "exactly full" value is now + returned. + +6. If a subpattern that was called recursively or as a subroutine contained + (*PRUNE) or any other control that caused it to give a non-standard return, + invalid errors such as "Error -26 (nested recursion at the same subject + position)" or even infinite loops could occur. + +7. If a pattern such as /a(*SKIP)c|b(*ACCEPT)|/ was studied, it stopped + computing the minimum length on reaching *ACCEPT, and so ended up with the + wrong value of 1 rather than 0. Further investigation indicates that + computing a minimum subject length in the presence of *ACCEPT is difficult + (think back references, subroutine calls), and so I have changed the code + so that no minimum is registered for a pattern that contains *ACCEPT. + +8. If (*THEN) was present in the first (true) branch of a conditional group, + it was not handled as intended. [But see 16 below.] + +9. Replaced RunTest.bat and CMakeLists.txt with improved versions provided by + Sheri Pierce. + +10. A pathological pattern such as /(*ACCEPT)a/ was miscompiled, thinking that + the first byte in a match must be "a". + +11. Change 17 for 8.13 increased the recursion depth for patterns like + /a(?:.)*?a/ drastically. I've improved things by remembering whether a + pattern contains any instances of (*THEN). If it does not, the old + optimizations are restored. It would be nice to do this on a per-group + basis, but at the moment that is not feasible. + +12. In some environments, the output of pcretest -C is CRLF terminated. This + broke RunTest's code that checks for the link size. A single white space + character after the value is now allowed for. + +13. RunTest now checks for the "fr" locale as well as for "fr_FR" and "french". + For "fr", it uses the Windows-specific input and output files. + +14. If (*THEN) appeared in a group that was called recursively or as a + subroutine, it did not work as intended. [But see next item.] + +15. Consider the pattern /A (B(*THEN)C) | D/ where A, B, C, and D are complex + pattern fragments (but not containing any | characters). If A and B are + matched, but there is a failure in C so that it backtracks to (*THEN), PCRE + was behaving differently to Perl. PCRE backtracked into A, but Perl goes to + D. In other words, Perl considers parentheses that do not contain any | + characters to be part of a surrounding alternative, whereas PCRE was + treading (B(*THEN)C) the same as (B(*THEN)C|(*FAIL)) -- which Perl handles + differently. PCRE now behaves in the same way as Perl, except in the case + of subroutine/recursion calls such as (?1) which have in any case always + been different (but PCRE had them first :-). + +16. Related to 15 above: Perl does not treat the | in a conditional group as + creating alternatives. Such a group is treated in the same way as an + ordinary group without any | characters when processing (*THEN). PCRE has + been changed to match Perl's behaviour. + +17. If a user had set PCREGREP_COLO(U)R to something other than 1:31, the + RunGrepTest script failed. + +18. Change 22 for version 13 caused atomic groups to use more stack. This is + inevitable for groups that contain captures, but it can lead to a lot of + stack use in large patterns. The old behaviour has been restored for atomic + groups that do not contain any capturing parentheses. + +19. If the PCRE_NO_START_OPTIMIZE option was set for pcre_compile(), it did not + suppress the check for a minimum subject length at run time. (If it was + given to pcre_exec() or pcre_dfa_exec() it did work.) + +20. Fixed an ASCII-dependent infelicity in pcretest that would have made it + fail to work when decoding hex characters in data strings in EBCDIC + environments. + +21. It appears that in at least one Mac OS environment, the isxdigit() function + is implemented as a macro that evaluates to its argument more than once, + contravening the C 90 Standard (I haven't checked a later standard). There + was an instance in pcretest which caused it to go wrong when processing + \x{...} escapes in subject strings. The has been rewritten to avoid using + things like p++ in the argument of isxdigit(). + + +Version 8.13 16-Aug-2011 +------------------------ + +1. The Unicode data tables have been updated to Unicode 6.0.0. + +2. Two minor typos in pcre_internal.h have been fixed. + +3. Added #include to pcre_scanner_unittest.cc, pcrecpp.cc, and + pcrecpp_unittest.cc. They are needed for strcmp(), memset(), and strchr() + in some environments (e.g. Solaris 10/SPARC using Sun Studio 12U2). + +4. There were a number of related bugs in the code for matching backrefences + caselessly in UTF-8 mode when codes for the characters concerned were + different numbers of bytes. For example, U+023A and U+2C65 are an upper + and lower case pair, using 2 and 3 bytes, respectively. The main bugs were: + (a) A reference to 3 copies of a 2-byte code matched only 2 of a 3-byte + code. (b) A reference to 2 copies of a 3-byte code would not match 2 of a + 2-byte code at the end of the subject (it thought there wasn't enough data + left). + +5. Comprehensive information about what went wrong is now returned by + pcre_exec() and pcre_dfa_exec() when the UTF-8 string check fails, as long + as the output vector has at least 2 elements. The offset of the start of + the failing character and a reason code are placed in the vector. + +6. When the UTF-8 string check fails for pcre_compile(), the offset that is + now returned is for the first byte of the failing character, instead of the + last byte inspected. This is an incompatible change, but I hope it is small + enough not to be a problem. It makes the returned offset consistent with + pcre_exec() and pcre_dfa_exec(). + +7. pcretest now gives a text phrase as well as the error number when + pcre_exec() or pcre_dfa_exec() fails; if the error is a UTF-8 check + failure, the offset and reason code are output. + +8. When \R was used with a maximizing quantifier it failed to skip backwards + over a \r\n pair if the subsequent match failed. Instead, it just skipped + back over a single character (\n). This seems wrong (because it treated the + two characters as a single entity when going forwards), conflicts with the + documentation that \R is equivalent to (?>\r\n|\n|...etc), and makes the + behaviour of \R* different to (\R)*, which also seems wrong. The behaviour + has been changed. + +9. Some internal refactoring has changed the processing so that the handling + of the PCRE_CASELESS and PCRE_MULTILINE options is done entirely at compile + time (the PCRE_DOTALL option was changed this way some time ago: version + 7.7 change 16). This has made it possible to abolish the OP_OPT op code, + which was always a bit of a fudge. It also means that there is one less + argument for the match() function, which reduces its stack requirements + slightly. This change also fixes an incompatibility with Perl: the pattern + (?i:([^b]))(?1) should not match "ab", but previously PCRE gave a match. + +10. More internal refactoring has drastically reduced the number of recursive + calls to match() for possessively repeated groups such as (abc)++ when + using pcre_exec(). + +11. While implementing 10, a number of bugs in the handling of groups were + discovered and fixed: + + (?<=(a)+) was not diagnosed as invalid (non-fixed-length lookbehind). + (a|)*(?1) gave a compile-time internal error. + ((a|)+)+ did not notice that the outer group could match an empty string. + (^a|^)+ was not marked as anchored. + (.*a|.*)+ was not marked as matching at start or after a newline. + +12. Yet more internal refactoring has removed another argument from the match() + function. Special calls to this function are now indicated by setting a + value in a variable in the "match data" data block. + +13. Be more explicit in pcre_study() instead of relying on "default" for + opcodes that mean there is no starting character; this means that when new + ones are added and accidentally left out of pcre_study(), testing should + pick them up. + +14. The -s option of pcretest has been documented for ages as being an old + synonym of -m (show memory usage). I have changed it to mean "force study + for every regex", that is, assume /S for every regex. This is similar to -i + and -d etc. It's slightly incompatible, but I'm hoping nobody is still + using it. It makes it easier to run collections of tests with and without + study enabled, and thereby test pcre_study() more easily. All the standard + tests are now run with and without -s (but some patterns can be marked as + "never study" - see 20 below). + +15. When (*ACCEPT) was used in a subpattern that was called recursively, the + restoration of the capturing data to the outer values was not happening + correctly. + +16. If a recursively called subpattern ended with (*ACCEPT) and matched an + empty string, and PCRE_NOTEMPTY was set, pcre_exec() thought the whole + pattern had matched an empty string, and so incorrectly returned a no + match. + +17. There was optimizing code for the last branch of non-capturing parentheses, + and also for the obeyed branch of a conditional subexpression, which used + tail recursion to cut down on stack usage. Unfortunately, now that there is + the possibility of (*THEN) occurring in these branches, tail recursion is + no longer possible because the return has to be checked for (*THEN). These + two optimizations have therefore been removed. [But see 8.20/11 above.] + +18. If a pattern containing \R was studied, it was assumed that \R always + matched two bytes, thus causing the minimum subject length to be + incorrectly computed because \R can also match just one byte. + +19. If a pattern containing (*ACCEPT) was studied, the minimum subject length + was incorrectly computed. + +20. If /S is present twice on a test pattern in pcretest input, it now + *disables* studying, thereby overriding the use of -s on the command line + (see 14 above). This is necessary for one or two tests to keep the output + identical in both cases. + +21. When (*ACCEPT) was used in an assertion that matched an empty string and + PCRE_NOTEMPTY was set, PCRE applied the non-empty test to the assertion. + +22. When an atomic group that contained a capturing parenthesis was + successfully matched, but the branch in which it appeared failed, the + capturing was not being forgotten if a higher numbered group was later + captured. For example, /(?>(a))b|(a)c/ when matching "ac" set capturing + group 1 to "a", when in fact it should be unset. This applied to multi- + branched capturing and non-capturing groups, repeated or not, and also to + positive assertions (capturing in negative assertions does not happen + in PCRE) and also to nested atomic groups. + +23. Add the ++ qualifier feature to pcretest, to show the remainder of the + subject after a captured substring, to make it easier to tell which of a + number of identical substrings has been captured. + +24. The way atomic groups are processed by pcre_exec() has been changed so that + if they are repeated, backtracking one repetition now resets captured + values correctly. For example, if ((?>(a+)b)+aabab) is matched against + "aaaabaaabaabab" the value of captured group 2 is now correctly recorded as + "aaa". Previously, it would have been "a". As part of this code + refactoring, the way recursive calls are handled has also been changed. + +25. If an assertion condition captured any substrings, they were not passed + back unless some other capturing happened later. For example, if + (?(?=(a))a) was matched against "a", no capturing was returned. + +26. When studying a pattern that contained subroutine calls or assertions, + the code for finding the minimum length of a possible match was handling + direct recursions such as (xxx(?1)|yyy) but not mutual recursions (where + group 1 called group 2 while simultaneously a separate group 2 called group + 1). A stack overflow occurred in this case. I have fixed this by limiting + the recursion depth to 10. + +27. Updated RunTest.bat in the distribution to the version supplied by Tom + Fortmann. This supports explicit test numbers on the command line, and has + argument validation and error reporting. + +28. An instance of \X with an unlimited repeat could fail if at any point the + first character it looked at was a mark character. + +29. Some minor code refactoring concerning Unicode properties and scripts + should reduce the stack requirement of match() slightly. + +30. Added the '=' option to pcretest to check the setting of unused capturing + slots at the end of the pattern, which are documented as being -1, but are + not included in the return count. + +31. If \k was not followed by a braced, angle-bracketed, or quoted name, PCRE + compiled something random. Now it gives a compile-time error (as does + Perl). + +32. A *MARK encountered during the processing of a positive assertion is now + recorded and passed back (compatible with Perl). + +33. If --only-matching or --colour was set on a pcregrep call whose pattern + had alternative anchored branches, the search for a second match in a line + was done as if at the line start. Thus, for example, /^01|^02/ incorrectly + matched the line "0102" twice. The same bug affected patterns that started + with a backwards assertion. For example /\b01|\b02/ also matched "0102" + twice. + +34. Previously, PCRE did not allow quantification of assertions. However, Perl + does, and because of capturing effects, quantifying parenthesized + assertions may at times be useful. Quantifiers are now allowed for + parenthesized assertions. + +35. A minor code tidy in pcre_compile() when checking options for \R usage. + +36. \g was being checked for fancy things in a character class, when it should + just be a literal "g". + +37. PCRE was rejecting [:a[:digit:]] whereas Perl was not. It seems that the + appearance of a nested POSIX class supersedes an apparent external class. + For example, [:a[:digit:]b:] matches "a", "b", ":", or a digit. Also, + unescaped square brackets may also appear as part of class names. For + example, [:a[:abc]b:] gives unknown class "[:abc]b:]". PCRE now behaves + more like Perl. (But see 8.20/1 above.) + +38. PCRE was giving an error for \N with a braced quantifier such as {1,} (this + was because it thought it was \N{name}, which is not supported). + +39. Add minix to OS list not supporting the -S option in pcretest. + +40. PCRE tries to detect cases of infinite recursion at compile time, but it + cannot analyze patterns in sufficient detail to catch mutual recursions + such as ((?1))((?2)). There is now a runtime test that gives an error if a + subgroup is called recursively as a subpattern for a second time at the + same position in the subject string. In previous releases this might have + been caught by the recursion limit, or it might have run out of stack. + +41. A pattern such as /(?(R)a+|(?R)b)/ is quite safe, as the recursion can + happen only once. PCRE was, however incorrectly giving a compile time error + "recursive call could loop indefinitely" because it cannot analyze the + pattern in sufficient detail. The compile time test no longer happens when + PCRE is compiling a conditional subpattern, but actual runaway loops are + now caught at runtime (see 40 above). + +42. It seems that Perl allows any characters other than a closing parenthesis + to be part of the NAME in (*MARK:NAME) and other backtracking verbs. PCRE + has been changed to be the same. + +43. Updated configure.ac to put in more quoting round AC_LANG_PROGRAM etc. so + as not to get warnings when autogen.sh is called. Also changed + AC_PROG_LIBTOOL (deprecated) to LT_INIT (the current macro). + +44. To help people who use pcregrep to scan files containing exceedingly long + lines, the following changes have been made: + + (a) The default value of the buffer size parameter has been increased from + 8K to 20K. (The actual buffer used is three times this size.) + + (b) The default can be changed by ./configure --with-pcregrep-bufsize when + PCRE is built. + + (c) A --buffer-size=n option has been added to pcregrep, to allow the size + to be set at run time. + + (d) Numerical values in pcregrep options can be followed by K or M, for + example --buffer-size=50K. + + (e) If a line being scanned overflows pcregrep's buffer, an error is now + given and the return code is set to 2. + +45. Add a pointer to the latest mark to the callout data block. + +46. The pattern /.(*F)/, when applied to "abc" with PCRE_PARTIAL_HARD, gave a + partial match of an empty string instead of no match. This was specific to + the use of ".". + +47. The pattern /f.*/8s, when applied to "for" with PCRE_PARTIAL_HARD, gave a + complete match instead of a partial match. This bug was dependent on both + the PCRE_UTF8 and PCRE_DOTALL options being set. + +48. For a pattern such as /\babc|\bdef/ pcre_study() was failing to set up the + starting byte set, because \b was not being ignored. + + Version 8.12 15-Jan-2011 ------------------------ diff -Nru pcre3-8.12/CheckMan pcre3-8.31/CheckMan --- pcre3-8.12/CheckMan 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/CheckMan 2011-01-11 16:26:13.000000000 +0000 @@ -0,0 +1,67 @@ +#! /usr/bin/perl + +# A script to scan PCRE's man pages to check for typos in the control +# sequences. I use only a small set of the available repertoire, so it is +# straightforward to check that nothing else has slipped in by mistake. This +# script should be called in the doc directory. + +$yield = 0; + +while (scalar(@ARGV) > 0) + { + $line = 0; + $file = shift @ARGV; + + open (IN, $file) || die "Failed to open $file\n"; + + while () + { + $line++; + if (/^\s*$/) + { + printf "Empty line $line of $file\n"; + $yield = 1; + } + elsif (/^\./) + { + if (!/^\.\s*$| + ^\.B\s+\S| + ^\.TH\s\S| + ^\.SH\s\S| + ^\.SS\s\S| + ^\.TP(?:\s\d+)?\s*$| + ^\.ti\s\S| + ^\.SM\s*$| + ^\.rs\s*$| + ^\.sp\s*$| + ^\.nf\s*$| + ^\.fi\s*$| + ^\.P\s*$| + ^\.PP\s*$| + ^\.\\"(?:\ HREF)?\s*$| + ^\.\\"\sHTML\s\s*$| + ^\.\\"\sHTML\s<\/a>\s*$| + ^\.\\"\s<\/a>\s*$| + ^\.\\"\sJOINSH\s*$| + ^\.\\"\sJOIN\s*$/x + ) + { + printf "Bad control line $line of $file\n"; + $yield = 1; + } + } + else + { + if (/\\[^ef]|\\f[^IBP]/) + { + printf "Bad backslash in line $line of $file\n"; + $yield = 1; + } + } + } + + close(IN); + } + +exit $yield; +# End diff -Nru pcre3-8.12/HACKING pcre3-8.31/HACKING --- pcre3-8.12/HACKING 2010-10-10 16:22:37.000000000 +0000 +++ pcre3-8.31/HACKING 2012-02-22 15:14:37.000000000 +0000 @@ -2,7 +2,8 @@ -------------------------- These are very rough technical notes that record potentially useful information -about PCRE internals. +about PCRE internals. For information about testing PCRE, see the pcretest +documentation and the comment at the head of the RunTest file. Historical note 1 @@ -48,6 +49,18 @@ first pass through the pattern is helpful for other reasons. +Support for 16-bit data strings +------------------------------- + +From release 8.30, PCRE supports 16-bit as well as 8-bit data strings, by being +compilable in either 8-bit or 16-bit modes, or both. Thus, two different +libraries can be created. In the description that follows, the word "short" is +used for a 16-bit data quantity, and the word "unit" is used for a quantity +that is a byte in 8-bit mode and a short in 16-bit mode. However, so as not to +over-complicate the text, the names of PCRE functions are given in 8-bit form +only. + + Computing the memory requirement: how it was -------------------------------------------- @@ -68,7 +81,7 @@ I had a flash of inspiration as to how I could run the real compile function in a "fake" mode that enables it to compute how much memory it would need, while actually only ever using a few hundred bytes of working memory, and without too -many tests of the mode that might slow it down. So I re-factored the compiling +many tests of the mode that might slow it down. So I refactored the compiling functions to work this way. This got rid of about 600 lines of source. It should make future maintenance and development easier. As this was such a major change, I never released 6.8, instead upping the number to 7.0 (other quite @@ -88,7 +101,10 @@ it implements an NFA algorithm, similar to the original Henry Spencer algorithm and the way that Perl works. This is not surprising, since it is intended to be as compatible with Perl as possible. This is the function most users of PCRE -will use most of the time. +will use most of the time. From release 8.20, if PCRE is compiled with +just-in-time (JIT) support, and studying a compiled pattern with JIT is +successful, the JIT code is run instead of the normal pcre_exec() code, but the +result is the same. Supplementary matching function @@ -108,28 +124,38 @@ ever active at once. I believe some other regex matchers work this way. +Changeable options +------------------ + +The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL) may +change in the middle of patterns. From PCRE 8.13, their processing is handled +entirely at compile time by generating different opcodes for the different +settings. The runtime functions do not need to keep track of an options state +any more. + + Format of compiled patterns --------------------------- -The compiled form of a pattern is a vector of bytes, containing items of -variable length. The first byte in an item is an opcode, and the length of the -item is either implicit in the opcode or contained in the data bytes that -follow it. - -In many cases below LINK_SIZE data values are specified for offsets within the -compiled pattern. The default value for LINK_SIZE is 2, but PCRE can be -compiled to use 3-byte or 4-byte values for these offsets (impairing the -performance). This is necessary only when patterns whose compiled length is -greater than 64K are going to be processed. In this description, we assume the -"normal" compilation options. Data values that are counts (e.g. for -quantifiers) are always just two bytes long. - -A list of the opcodes follows: +The compiled form of a pattern is a vector of units (bytes in 8-bit mode, or +shorts in 16-bit mode), containing items of variable length. The first unit in +an item contains an opcode, and the length of the item is either implicit in +the opcode or contained in the data that follows it. + +In many cases listed below, LINK_SIZE data values are specified for offsets +within the compiled pattern. LINK_SIZE always specifies a number of bytes. The +default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or +4-byte values for these offsets, although this impairs the performance. (3-byte +LINK_SIZE values are available only in 8-bit mode.) Specifing a LINK_SIZE +larger than 2 is necessary only when patterns whose compiled length is greater +than 64K are going to be processed. In this description, we assume the "normal" +compilation options. Data values that are counts (e.g. for quantifiers) are +always just two bytes long (one short in 16-bit mode). Opcodes with no following data ------------------------------ -These items are all just one byte long +These items are all just one unit long OP_END end of pattern OP_ANY match any one character other than newline @@ -138,7 +164,8 @@ OP_SOD match start of data: \A OP_SOM, start of match (subject + offset): \G OP_SET_SOM, set start of match (\K) - OP_CIRC ^ (start of data, or after \n in multiline) + OP_CIRC ^ (start of data) + OP_CIRCM ^ multiline mode (start of data or after newline) OP_NOT_WORD_BOUNDARY \W OP_WORD_BOUNDARY \w OP_NOT_DIGIT \D @@ -153,7 +180,8 @@ OP_WORDCHAR \w OP_EODN match end of data or \n at end: \Z OP_EOD match end of data: \z - OP_DOLL $ (end of data, or before \n in multiline) + OP_DOLL $ (end of data, or before final newline) + OP_DOLLM $ multiline mode (end of data or before newline) OP_EXTUNI match an extended Unicode character OP_ANYNL match any Unicode newline sequence @@ -164,49 +192,57 @@ OP_SKIP ) indicating which parentheses must be closed. -Backtracking control verbs with data ------------------------------------- - -OP_THEN is followed by a LINK_SIZE offset, which is the distance back to the -start of the current branch. - -OP_MARK is followed by the mark name, preceded by a one-byte length, and -followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with arguments, -the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used. For the first -two, the name follows immediately; for OP_THEN_ARG, it follows the LINK_SIZE -offset value. +Backtracking control verbs with (optional) data +----------------------------------------------- + +(*THEN) without an argument generates the opcode OP_THEN and no following data. +OP_MARK is followed by the mark name, preceded by a one-unit length, and +followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with arguments, +the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, with the name +following in the same format. +Matching literal characters +--------------------------- + +The OP_CHAR opcode is followed by a single character that is to be matched +casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes, +the character may be more than one unit long. + + Repeating single characters --------------------------- -The common repeats (*, +, ?) when applied to a single character use the -following opcodes: +The common repeats (*, +, ?), when applied to a single character, use the +following opcodes, which come in caseful and caseless versions: - OP_STAR - OP_MINSTAR - OP_POSSTAR - OP_PLUS - OP_MINPLUS - OP_POSPLUS - OP_QUERY - OP_MINQUERY - OP_POSQUERY - -In ASCII mode, these are two-byte items; in UTF-8 mode, the length is variable. -Those with "MIN" in their name are the minimizing versions. Those with "POS" in -their names are possessive versions. Each is followed by the character that is -to be repeated. Other repeats make use of - - OP_UPTO - OP_MINUPTO - OP_POSUPTO - OP_EXACT - -which are followed by a two-byte count (most significant first) and the -repeated character. OP_UPTO matches from 0 to the given number. A repeat with a -non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an -OP_UPTO (or OP_MINUPTO or OPT_POSUPTO). + Caseful Caseless + OP_STAR OP_STARI + OP_MINSTAR OP_MINSTARI + OP_POSSTAR OP_POSSTARI + OP_PLUS OP_PLUSI + OP_MINPLUS OP_MINPLUSI + OP_POSPLUS OP_POSPLUSI + OP_QUERY OP_QUERYI + OP_MINQUERY OP_MINQUERYI + OP_POSQUERY OP_POSQUERYI + +Each opcode is followed by the character that is to be repeated. In ASCII mode, +these are two-unit items; in UTF-8 or UTF-16 modes, the length is variable. +Those with "MIN" in their names are the minimizing versions. Those with "POS" +in their names are possessive versions. Other repeats make use of these +opcodes: + + Caseful Caseless + OP_UPTO OP_UPTOI + OP_MINUPTO OP_MINUPTOI + OP_POSUPTO OP_POSUPTOI + OP_EXACT OP_EXACTI + +Each of these is followed by a two-byte (one short) count (most significant +byte first in 8-bit mode) and then the repeated character. OP_UPTO matches from +0 to the given number. A repeat with a non-zero minimum and a fixed maximum is +coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or OPT_POSUPTO). Repeating character types @@ -214,7 +250,7 @@ Repeats of things like \d are done exactly as for single characters, except that instead of a character, the opcode for the type is stored in the data -byte. The opcodes are: +unit. The opcodes are: OP_TYPESTAR OP_TYPEMINSTAR @@ -236,65 +272,58 @@ OP_PROP and OP_NOTPROP are used for positive and negative matches of a character by testing its Unicode property (the \p and \P escape sequences). -Each is followed by two bytes that encode the desired property as a type and a +Each is followed by two units that encode the desired property as a type and a value. -Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by -three bytes: OP_PROP or OP_NOTPROP and then the desired property type and +Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by +three units: OP_PROP or OP_NOTPROP, and then the desired property type and value. -Matching literal characters ---------------------------- - -The OP_CHAR opcode is followed by a single character that is to be matched -casefully. For caseless matching, OP_CHARNC is used. In UTF-8 mode, the -character may be more than one byte long. (Earlier versions of PCRE used -multi-character strings, but this was changed to allow some new features to be -added.) - - Character classes ----------------- -If there is only one character, OP_CHAR or OP_CHARNC is used for a positive -class, and OP_NOT for a negative one (that is, for something like [^a]). -However, in UTF-8 mode, the use of OP_NOT applies only to characters with -values < 128, because OP_NOT is confined to single bytes. - -Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a repeated, -negated, single-character class. The normal ones (OP_STAR etc.) are used for a -repeated positive single-character class. - -When there's more than one character in a class and all the characters are less -than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a negative -one. In either case, the opcode is followed by a 32-byte bit map containing a 1 -bit for every character that is acceptable. The bits are counted from the least -significant end of each byte. - -The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8 mode, -subject characters with values greater than 256 can be handled correctly. For -OP_CLASS they don't match, whereas for OP_NCLASS they do. - -For classes containing characters with values > 255, OP_XCLASS is used. It -optionally uses a bit map (if any characters lie within it), followed by a list -of pairs and single characters. There is a flag character than indicates -whether it's a positive or a negative class. +If there is only one character in the class, OP_CHAR or OP_CHARI is used for a +positive class, and OP_NOT or OP_NOTI for a negative one (that is, for +something like [^a]). + +Another set of 13 repeating opcodes (called OP_NOTSTAR etc.) are used for +repeated, negated, single-character classes. The normal single-character +opcodes (OP_STAR, etc.) are used for repeated positive single-character +classes. + +When there is more than one character in a class and all the characters are +less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a +negative one. In either case, the opcode is followed by a 32-byte (16-short) +bit map containing a 1 bit for every character that is acceptable. The bits are +counted from the least significant end of each unit. In caseless mode, bits for +both cases are set. + +The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16 mode, +subject characters with values greater than 255 can be handled correctly. For +OP_CLASS they do not match, whereas for OP_NCLASS they do. + +For classes containing characters with values greater than 255, OP_XCLASS is +used. It optionally uses a bit map (if any characters lie within it), followed +by a list of pairs (for a range) and single characters. In caseless mode, both +cases are explicitly listed. There is a flag character than indicates whether +it is a positive or a negative class. Back references --------------- -OP_REF is followed by two bytes containing the reference number. +OP_REF (caseful) or OP_REFI (caseless) is followed by two bytes (one short) +containing the reference number. Repeating character classes and back references ----------------------------------------------- Single-character classes are handled specially (see above). This section -applies to OP_CLASS and OP_REF. In both cases, the repeat information follows -the base item. The matching code looks at the following opcode to see if it is -one of +applies to OP_CLASS and OP_REF[I]. In both cases, the repeat information +follows the base item. The matching code looks at the following opcode to see +if it is one of OP_CRSTAR OP_CRMINSTAR @@ -305,10 +334,10 @@ OP_CRRANGE OP_CRMINRANGE -All but the last two are just single-byte items. The others are followed by -four bytes of data, comprising the minimum and maximum repeat counts. There are -no special possessive opcodes for these repeats; a possessive repeat is -compiled into an atomic group. +All but the last two are just single-unit items. The others are followed by +four bytes (two shorts) of data, comprising the minimum and maximum repeat +counts. There are no special possessive opcodes for these repeats; a possessive +repeat is compiled into an atomic group. Brackets and alternation @@ -318,7 +347,8 @@ compile time, so alternation always happens in the context of brackets. [Note for North Americans: "bracket" to some English speakers, including -myself, can be round, square, curly, or pointy. Hence this usage.] +myself, can be round, square, curly, or pointy. Hence this usage rather than +"parentheses".] Non-capturing brackets use the opcode OP_BRA. Originally PCRE was limited to 99 capturing brackets and it used a different opcode for each one. From release @@ -330,16 +360,17 @@ next alternative OP_ALT or, if there aren't any branches, to the matching OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to the next one, or to the OP_KET opcode. For capturing brackets, the bracket -number immediately follows the offset, always as a 2-byte item. +number immediately follows the offset, always as a 2-byte (one short) item. -OP_KET is used for subpatterns that do not repeat indefinitely, while +OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or -maximally respectively. All three are followed by LINK_SIZE bytes giving (as a -positive number) the offset back to the matching bracket opcode. +maximally respectively (see below for possessive repetitions). All three are +followed by LINK_SIZE bytes giving (as a positive number) the offset back to +the matching bracket opcode. If a subpattern is quantified such that it is permitted to match zero times, it is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are -single-byte opcodes that tell the matcher that skipping the following +single-unit opcodes that tell the matcher that skipping the following subpattern entirely is a valid branch. In the case of the first two, not skipping the pattern is also valid (greedy and non-greedy). The third is used when a pattern has the quantifier {0,0}. It cannot be entirely discarded, @@ -362,6 +393,15 @@ that it needs to check for matching an empty string when it hits OP_KETRMIN or OP_KETRMAX, and if so, to break the loop. +Possessive brackets +------------------- + +When a repeated group (capturing or non-capturing) is marked as possessive by +the "+" notation, e.g. (abc)++, different opcodes are used. Their names all +have POS on the end, e.g. OP_BRAPOS instead of OP_BRA and OP_SCPBRPOS instead +of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum +repetition is zero, the group is preceded by OP_BRAPOSZERO. + Assertions ---------- @@ -369,11 +409,11 @@ Forward assertions are just like other subpatterns, but starting with one of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion -is OP_REVERSE, followed by a two byte count of the number of characters to move -back the pointer in the subject string. When operating in UTF-8 mode, the count -is a character count rather than a byte count. A separate count is present in -each alternative of a lookbehind assertion, allowing them to have different -fixed lengths. +is OP_REVERSE, followed by a two byte (one short) count of the number of +characters to move back the pointer in the subject string. In ASCII mode, the +count is a number of units, but in UTF-8/16 mode each character may occupy more +than one unit. A separate count is present in each alternative of a lookbehind +assertion, allowing them to have different fixed lengths. Once-only (atomic) subpatterns @@ -390,14 +430,15 @@ These are like other subpatterns, but they start with the opcode OP_COND, or OP_SCOND for one that might match an empty string in an unbounded repeat. If the condition is a back reference, this is stored at the start of the -subpattern using the opcode OP_CREF followed by two bytes containing the -reference number. OP_NCREF is used instead if the reference was generated by -name (so that the runtime code knows to check for duplicate names). +subpattern using the opcode OP_CREF followed by two bytes (one short) +containing the reference number. OP_NCREF is used instead if the reference was +generated by name (so that the runtime code knows to check for duplicate +names). If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of group x" (coded as "(?(Rx)"), the group number is stored at the start of the subpattern using the opcode OP_RREF or OP_NRREF (cf OP_NCREF), and a value of -zero for "the whole pattern". For a DEFINE condition, just the single byte +zero for "the whole pattern". For a DEFINE condition, just the single unit OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern always starts with one of the assertions. @@ -416,25 +457,12 @@ Callout ------- -OP_CALLOUT is followed by one byte of data that holds a callout number in the +OP_CALLOUT is followed by one unit of data that holds a callout number in the range 0 to 254 for manual callouts, or 255 for an automatic callout. In both -cases there follows a two-byte value giving the offset in the pattern to the -start of the following item, and another two-byte item giving the length of the -next item. - - -Changing options ----------------- - -If any of the /i, /m, or /s options are changed within a pattern, an OP_OPT -opcode is compiled, followed by one byte containing the new settings of these -flags. If there are several alternatives, there is an occurrence of OP_OPT at -the start of all those following the first options change, to set appropriate -options for the start of the alternative. Immediately after the end of the -group there is another such item to reset the flags to their previous values. A -change of flag right at the very start of the pattern can be handled entirely -at compile time, and so does not cause anything to be put into the compiled -data. +cases there follows a two-byte (one short) value giving the offset in the +pattern to the start of the following item, and another two-byte (one short) +item giving the length of the next item. + Philip Hazel -October 2010 +February 2012 diff -Nru pcre3-8.12/LICENCE pcre3-8.31/LICENCE --- pcre3-8.12/LICENCE 2010-01-19 16:01:21.000000000 +0000 +++ pcre3-8.31/LICENCE 2011-12-28 16:57:58.000000000 +0000 @@ -9,7 +9,9 @@ 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 @@ University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2010 University of Cambridge +Copyright (c) 1997-2012 University of Cambridge +All rights reserved. + + +PCRE JUST-IN-TIME COMPILATION SUPPORT +------------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2010-2012 Zoltan Herczeg +All rights reserved. + + +STACK-LESS JUST-IN-TIME COMPILER +-------------------------------- + +Written by: Zoltan Herczeg +Email local part: hzmester +Emain domain: freemail.hu + +Copyright(c) 2009-2012 Zoltan Herczeg All rights reserved. @@ -31,7 +55,7 @@ Contributed by: Google Inc. -Copyright (c) 2007-2010, Google Inc. +Copyright (c) 2007-2012, Google Inc. All rights reserved. diff -Nru pcre3-8.12/Makefile.am pcre3-8.31/Makefile.am --- pcre3-8.12/Makefile.am 2011-01-15 11:27:45.000000000 +0000 +++ pcre3-8.31/Makefile.am 2012-06-20 15:08:49.000000000 +0000 @@ -17,7 +17,9 @@ dist_html_DATA = \ doc/html/index.html \ doc/html/pcre.html \ + doc/html/pcre16.html \ doc/html/pcre-config.html \ + doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ doc/html/pcre_config.html \ @@ -25,6 +27,7 @@ doc/html/pcre_copy_substring.html \ doc/html/pcre_dfa_exec.html \ doc/html/pcre_exec.html \ + doc/html/pcre_free_study.html \ doc/html/pcre_free_substring.html \ doc/html/pcre_free_substring_list.html \ doc/html/pcre_fullinfo.html \ @@ -33,10 +36,13 @@ doc/html/pcre_get_stringtable_entries.html \ doc/html/pcre_get_substring.html \ doc/html/pcre_get_substring_list.html \ - doc/html/pcre_info.html \ + doc/html/pcre_jit_stack_alloc.html \ + doc/html/pcre_jit_stack_free.html \ doc/html/pcre_maketables.html \ + doc/html/pcre_pattern_to_host_byte_order.html \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ + doc/html/pcre_utf16_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ @@ -44,6 +50,8 @@ doc/html/pcrecompat.html \ doc/html/pcredemo.html \ doc/html/pcregrep.html \ + doc/html/pcrejit.html \ + doc/html/pcrelimits.html \ doc/html/pcrematching.html \ doc/html/pcrepartial.html \ doc/html/pcrepattern.html \ @@ -53,7 +61,8 @@ doc/html/pcresample.html \ doc/html/pcrestack.html \ doc/html/pcresyntax.html \ - doc/html/pcretest.html + doc/html/pcretest.html \ + doc/html/pcreunicode.html pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) @@ -72,7 +81,7 @@ dist_noinst_SCRIPTS = # Some of the binaries we make are to be installed, and others are -# (non-user-visible) helper programs needed to build libpcre. +# (non-user-visible) helper programs needed to build libpcre or libpcre16. bin_PROGRAMS = noinst_PROGRAMS = @@ -88,11 +97,13 @@ EXTRA_DIST += \ doc/perltest.txt \ NON-UNIX-USE \ + NON-AUTOTOOLS-BUILD \ HACKING # These files are used in the preparation of a release EXTRA_DIST += \ PrepareRelease \ + CheckMan \ CleanTxt \ Detrail \ 132html \ @@ -161,10 +172,15 @@ endif # WITH_REBUILD_CHARTABLES +BUILT_SOURCES = pcre_chartables.c ## The main pcre library + +# Build the 8 bit library if it is enabled. +if WITH_PCRE8 lib_LTLIBRARIES += libpcre.la libpcre_la_SOURCES = \ + pcre_byte_order.c \ pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ @@ -172,15 +188,15 @@ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ - pcre_info.c \ pcre_internal.h \ + pcre_jit_compile.c \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ pcre_refcount.c \ + pcre_string_utils.c \ pcre_study.c \ pcre_tables.c \ - pcre_try_flipped.c \ pcre_ucd.c \ pcre_valid_utf8.c \ pcre_version.c \ @@ -191,21 +207,96 @@ nodist_libpcre_la_SOURCES = \ pcre_chartables.c -# The pcre_printint.src file is #included by some source files, so it must be -# distributed. The pcre_chartables.c.dist file is the default version of -# pcre_chartables.c, used unless --enable-rebuild-chartables is specified. -EXTRA_DIST += pcre_printint.src pcre_chartables.c.dist +endif # WITH_PCRE8 + +# Build the 16 bit library if it is enabled. +if WITH_PCRE16 +lib_LTLIBRARIES += libpcre16.la +libpcre16_la_SOURCES = \ + pcre16_byte_order.c \ + pcre16_chartables.c \ + pcre16_compile.c \ + pcre16_config.c \ + pcre16_dfa_exec.c \ + pcre16_exec.c \ + pcre16_fullinfo.c \ + pcre16_get.c \ + pcre16_globals.c \ + pcre16_jit_compile.c \ + pcre16_maketables.c \ + pcre16_newline.c \ + pcre16_ord2utf16.c \ + pcre16_refcount.c \ + pcre16_string_utils.c \ + pcre16_study.c \ + pcre16_tables.c \ + pcre16_ucd.c \ + pcre16_utf16_utils.c \ + pcre16_valid_utf16.c \ + pcre16_version.c \ + pcre16_xclass.c + +## This file is generated as part of the building process, so don't distribute. +nodist_libpcre16_la_SOURCES = \ + pcre_chartables.c + +endif # WITH_PCRE16 +# The pcre_chartables.c.dist file is the default version of pcre_chartables.c, +# used unless --enable-rebuild-chartables is specified. +EXTRA_DIST += pcre_chartables.c.dist + +# The JIT compiler lives in a separate directory, but its files are #included +# when pcre_jit_compile.c is processed, so they must be distributed. +EXTRA_DIST += \ + sljit/sljitConfig.h \ + sljit/sljitConfigInternal.h \ + sljit/sljitExecAllocator.c \ + sljit/sljitLir.c \ + sljit/sljitLir.h \ + sljit/sljitNativeARM_Thumb2.c \ + sljit/sljitNativeARM_v5.c \ + sljit/sljitNativeMIPS_32.c \ + sljit/sljitNativeMIPS_common.c \ + sljit/sljitNativePPC_32.c \ + sljit/sljitNativePPC_64.c \ + sljit/sljitNativePPC_common.c \ + sljit/sljitNativeX86_32.c \ + sljit/sljitNativeX86_64.c \ + sljit/sljitNativeX86_common.c \ + sljit/sljitUtils.c + +if WITH_PCRE8 libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) +endif # WITH_PCRE8 +if WITH_PCRE16 +libpcre16_la_LDFLAGS = $(EXTRA_LIBPCRE16_LDFLAGS) +endif # WITH_PCRE16 CLEANFILES += pcre_chartables.c +## If JIT support is enabled, arrange for the JIT test program to run. +if WITH_JIT +TESTS += pcre_jit_test +noinst_PROGRAMS += pcre_jit_test +pcre_jit_test_SOURCES = pcre_jit_test.c +pcre_jit_test_LDADD = +if WITH_PCRE8 +pcre_jit_test_LDADD += libpcre.la +endif # WITH_PCRE8 +if WITH_PCRE16 +pcre_jit_test_LDADD += libpcre16.la +endif # WITH_PCRE16 +endif # WITH_JIT + ## A version of the main pcre library that has a posix re API. +if WITH_PCRE8 lib_LTLIBRARIES += libpcreposix.la libpcreposix_la_SOURCES = \ pcreposix.c libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) libpcreposix_la_LIBADD = libpcre.la +endif # WITH_PCRE8 ## There's a C++ library as well. if WITH_PCRE_CPP @@ -246,15 +337,28 @@ EXTRA_DIST += RunTest.bat bin_PROGRAMS += pcretest pcretest_SOURCES = pcretest.c -pcretest_LDADD = libpcreposix.la $(LIBREADLINE) +pcretest_LDADD = $(LIBREADLINE) +if WITH_PCRE8 +pcretest_SOURCES += pcre_printint.c +pcretest_LDADD += libpcre.la libpcreposix.la +endif # WITH_PCRE8 +if WITH_PCRE16 +pcretest_SOURCES += pcre16_printint.c +pcretest_LDADD += libpcre16.la +endif # WITH_PCRE16 +if WITH_PCRE8 TESTS += RunGrepTest dist_noinst_SCRIPTS += RunGrepTest bin_PROGRAMS += pcregrep pcregrep_SOURCES = pcregrep.c -pcregrep_LDADD = libpcreposix.la $(LIBZ) $(LIBBZ2) +pcregrep_LDADD = $(LIBZ) $(LIBBZ2) +pcregrep_LDADD += libpcre.la libpcreposix.la +endif # WITH_PCRE8 EXTRA_DIST += \ + testdata/grepbinary \ + testdata/grepfilelist \ testdata/grepinput \ testdata/grepinput3 \ testdata/grepinput8 \ @@ -264,6 +368,13 @@ testdata/grepoutput \ testdata/grepoutput8 \ testdata/grepoutputN \ + testdata/greppatN4 \ + testdata/saved16 \ + testdata/saved16BE-1 \ + testdata/saved16BE-2 \ + testdata/saved16LE-1 \ + testdata/saved16LE-2 \ + testdata/saved8 \ testdata/testinput1 \ testdata/testinput2 \ testdata/testinput3 \ @@ -276,6 +387,16 @@ testdata/testinput10 \ testdata/testinput11 \ testdata/testinput12 \ + testdata/testinput13 \ + testdata/testinput14 \ + testdata/testinput15 \ + testdata/testinput16 \ + testdata/testinput17 \ + testdata/testinput18 \ + testdata/testinput19 \ + testdata/testinput20 \ + testdata/testinput21 \ + testdata/testinput22 \ testdata/testoutput1 \ testdata/testoutput2 \ testdata/testoutput3 \ @@ -286,8 +407,19 @@ testdata/testoutput8 \ testdata/testoutput9 \ testdata/testoutput10 \ - testdata/testoutput11 \ + testdata/testoutput11-16 \ + testdata/testoutput11-8 \ testdata/testoutput12 \ + testdata/testoutput13 \ + testdata/testoutput14 \ + testdata/testoutput15 \ + testdata/testoutput16 \ + testdata/testoutput17 \ + testdata/testoutput18 \ + testdata/testoutput19 \ + testdata/testoutput20 \ + testdata/testoutput21 \ + testdata/testoutput22 \ testdata/wintestinput3 \ testdata/wintestoutput3 \ perltest.pl @@ -317,13 +449,12 @@ # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". (It is used by the pcre.dll target.) -DLL_OBJS= pcre_compile.o pcre_config.o \ +DLL_OBJS= pcre_byte_order.o pcre_compile.o pcre_config.o \ pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ - pcre_globals.o pcre_info.o pcre_maketables.o \ + pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ - pcre_study.o pcre_tables.o pcre_try_flipped.o \ - pcre_ucd.o pcre_valid_utf8.o pcre_version.o \ - pcre_chartables.o \ + pcre_study.o pcre_tables.o pcre_ucd.o \ + pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ pcre_xclass.o # A PCRE user submitted the following addition, saying that it "will allow @@ -336,13 +467,18 @@ # We have .pc files for pkg-config users. pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libpcre.pc libpcreposix.pc +if WITH_PCRE16 +pkgconfig_DATA += libpcre16.pc +endif if WITH_PCRE_CPP pkgconfig_DATA += libpcrecpp.pc endif dist_man_MANS = \ doc/pcre.3 \ + doc/pcre16.3 \ doc/pcre-config.1 \ + doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ doc/pcre_config.3 \ @@ -350,6 +486,7 @@ doc/pcre_copy_substring.3 \ doc/pcre_dfa_exec.3 \ doc/pcre_exec.3 \ + doc/pcre_free_study.3 \ doc/pcre_free_substring.3 \ doc/pcre_free_substring_list.3 \ doc/pcre_fullinfo.3 \ @@ -358,16 +495,21 @@ doc/pcre_get_stringtable_entries.3 \ doc/pcre_get_substring.3 \ doc/pcre_get_substring_list.3 \ - doc/pcre_info.3 \ + doc/pcre_jit_stack_alloc.3 \ + doc/pcre_jit_stack_free.3 \ doc/pcre_maketables.3 \ + doc/pcre_pattern_to_host_byte_order.3 \ doc/pcre_refcount.3 \ doc/pcre_study.3 \ + doc/pcre_utf16_to_host_byte_order.3 \ doc/pcre_version.3 \ doc/pcreapi.3 \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ doc/pcregrep.1 \ + doc/pcrejit.3 \ + doc/pcrelimits.3 \ doc/pcrematching.3 \ doc/pcrepartial.3 \ doc/pcrepattern.3 \ @@ -377,7 +519,36 @@ doc/pcresample.3 \ doc/pcrestack.3 \ doc/pcresyntax.3 \ - doc/pcretest.1 + doc/pcretest.1 \ + doc/pcreunicode.3 + +# Arrange for the per-function man pages to have 16-bit names as well. +install-data-hook: + ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre16_assign_jit_stack.3 + ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre16_compile.3 + ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre16_compile2.3 + ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre16_config.3 + ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_named_substring.3 + ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_substring.3 + ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre16_dfa_exec.3 + ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre16_exec.3 + ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre16_free_study.3 + ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre16_free_substring.3 + ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_free_substring_list.3 + ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre16_fullinfo.3 + ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_named_substring.3 + ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre16_get_stringnumber.3 + ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre16_get_stringtable_entries.3 + ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_substring.3 + ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_get_substring_list.3 + ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_alloc.3 + ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_free.3 + ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre16_maketables.3 + ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_pattern_to_host_byte_order.3 + ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre16_refcount.3 + ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre16_study.3 + ln -sf pcre_utf16_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_utf16_to_host_byte_order.3 + ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre16_version.3 pcrecpp_man = doc/pcrecpp.3 EXTRA_DIST += $(pcrecpp_man) @@ -392,6 +563,7 @@ cmake/COPYING-CMAKE-SCRIPTS \ cmake/FindPackageHandleStandardArgs.cmake \ cmake/FindReadline.cmake \ + cmake/FindEditline.cmake \ CMakeLists.txt \ config-cmake.h.in diff -Nru pcre3-8.12/Makefile.in pcre3-8.31/Makefile.in --- pcre3-8.12/Makefile.in 2011-01-15 11:28:19.000000000 +0000 +++ pcre3-8.31/Makefile.in 2012-07-06 09:55:28.000000000 +0000 @@ -38,9 +38,9 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -TESTS = $(am__EXEEXT_2) RunTest RunGrepTest -bin_PROGRAMS = pcretest$(EXEEXT) pcregrep$(EXEEXT) -noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +TESTS = $(am__EXEEXT_3) $(am__EXEEXT_4) RunTest $(am__append_18) +bin_PROGRAMS = pcretest$(EXEEXT) $(am__EXEEXT_1) +noinst_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) # These additional headers will be be installed if C++ support is enabled. We # do not distribute pcrecpparg.h or pcre_stringpiece.h, as these are generated @@ -54,20 +54,40 @@ @WITH_PCRE_CPP_TRUE@ pcre_scanner.h @WITH_REBUILD_CHARTABLES_TRUE@am__append_3 = dftables -@WITH_PCRE_CPP_TRUE@am__append_4 = libpcrecpp.la -@WITH_PCRE_CPP_TRUE@am__append_5 = pcrecpp_unittest \ + +# Build the 8 bit library if it is enabled. +@WITH_PCRE8_TRUE@am__append_4 = libpcre.la + +# Build the 16 bit library if it is enabled. +@WITH_PCRE16_TRUE@am__append_5 = libpcre16.la +@WITH_JIT_TRUE@am__append_6 = pcre_jit_test +@WITH_JIT_TRUE@am__append_7 = pcre_jit_test +@WITH_JIT_TRUE@@WITH_PCRE8_TRUE@am__append_8 = libpcre.la +@WITH_JIT_TRUE@@WITH_PCRE16_TRUE@am__append_9 = libpcre16.la +@WITH_PCRE8_TRUE@am__append_10 = libpcreposix.la +@WITH_PCRE_CPP_TRUE@am__append_11 = libpcrecpp.la +@WITH_PCRE_CPP_TRUE@am__append_12 = pcrecpp_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest -@WITH_PCRE_CPP_TRUE@am__append_6 = pcrecpp_unittest \ +@WITH_PCRE_CPP_TRUE@am__append_13 = pcrecpp_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest -@WITH_PCRE_CPP_TRUE@am__append_7 = libpcrecpp.pc +@WITH_PCRE8_TRUE@am__append_14 = pcre_printint.c +@WITH_PCRE8_TRUE@am__append_15 = libpcre.la libpcreposix.la +@WITH_PCRE16_TRUE@am__append_16 = pcre16_printint.c +@WITH_PCRE16_TRUE@am__append_17 = libpcre16.la +@WITH_PCRE8_TRUE@am__append_18 = RunGrepTest +@WITH_PCRE8_TRUE@am__append_19 = RunGrepTest +@WITH_PCRE8_TRUE@am__append_20 = pcregrep +@WITH_PCRE16_TRUE@am__append_21 = libpcre16.pc +@WITH_PCRE_CPP_TRUE@am__append_22 = libpcrecpp.pc subdir = . -DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ +DIST_COMMON = README $(am__configure_deps) \ + $(am__dist_noinst_SCRIPTS_DIST) $(am__include_HEADERS_DIST) \ $(dist_doc_DATA) $(dist_html_DATA) $(dist_man_MANS) \ - $(dist_noinst_DATA) $(dist_noinst_SCRIPTS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(srcdir)/libpcre.pc.in \ + $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/libpcre.pc.in $(srcdir)/libpcre16.pc.in \ $(srcdir)/libpcrecpp.pc.in $(srcdir)/libpcreposix.pc.in \ $(srcdir)/pcre-config.in $(srcdir)/pcre.h.in \ $(srcdir)/pcre_stringpiece.h.in $(srcdir)/pcrecpparg.h.in \ @@ -81,8 +101,9 @@ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = libpcre.pc libpcreposix.pc libpcrecpp.pc \ - pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h +CONFIG_CLEAN_FILES = libpcre.pc libpcre16.pc libpcreposix.pc \ + libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h \ + pcrecpparg.h CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -113,36 +134,85 @@ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libpcre_la_LIBADD = -am_libpcre_la_OBJECTS = pcre_compile.lo pcre_config.lo \ - pcre_dfa_exec.lo pcre_exec.lo pcre_fullinfo.lo pcre_get.lo \ - pcre_globals.lo pcre_info.lo pcre_maketables.lo \ - pcre_newline.lo pcre_ord2utf8.lo pcre_refcount.lo \ - pcre_study.lo pcre_tables.lo pcre_try_flipped.lo pcre_ucd.lo \ - pcre_valid_utf8.lo pcre_version.lo pcre_xclass.lo -nodist_libpcre_la_OBJECTS = pcre_chartables.lo +am__libpcre_la_SOURCES_DIST = pcre_byte_order.c pcre_compile.c \ + pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c \ + pcre_get.c pcre_globals.c pcre_internal.h pcre_jit_compile.c \ + pcre_maketables.c pcre_newline.c pcre_ord2utf8.c \ + pcre_refcount.c pcre_string_utils.c pcre_study.c pcre_tables.c \ + pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c \ + ucp.h +@WITH_PCRE8_TRUE@am_libpcre_la_OBJECTS = pcre_byte_order.lo \ +@WITH_PCRE8_TRUE@ pcre_compile.lo pcre_config.lo \ +@WITH_PCRE8_TRUE@ pcre_dfa_exec.lo pcre_exec.lo \ +@WITH_PCRE8_TRUE@ pcre_fullinfo.lo pcre_get.lo pcre_globals.lo \ +@WITH_PCRE8_TRUE@ pcre_jit_compile.lo pcre_maketables.lo \ +@WITH_PCRE8_TRUE@ pcre_newline.lo pcre_ord2utf8.lo \ +@WITH_PCRE8_TRUE@ pcre_refcount.lo pcre_string_utils.lo \ +@WITH_PCRE8_TRUE@ pcre_study.lo pcre_tables.lo pcre_ucd.lo \ +@WITH_PCRE8_TRUE@ pcre_valid_utf8.lo pcre_version.lo \ +@WITH_PCRE8_TRUE@ pcre_xclass.lo +@WITH_PCRE8_TRUE@nodist_libpcre_la_OBJECTS = pcre_chartables.lo libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \ $(nodist_libpcre_la_OBJECTS) -libpcre_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libpcre_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE8_TRUE@am_libpcre_la_rpath = -rpath $(libdir) +libpcre16_la_LIBADD = +am__libpcre16_la_SOURCES_DIST = pcre16_byte_order.c \ + pcre16_chartables.c pcre16_compile.c pcre16_config.c \ + pcre16_dfa_exec.c pcre16_exec.c pcre16_fullinfo.c pcre16_get.c \ + pcre16_globals.c pcre16_jit_compile.c pcre16_maketables.c \ + pcre16_newline.c pcre16_ord2utf16.c pcre16_refcount.c \ + pcre16_string_utils.c pcre16_study.c pcre16_tables.c \ + pcre16_ucd.c pcre16_utf16_utils.c pcre16_valid_utf16.c \ + pcre16_version.c pcre16_xclass.c +@WITH_PCRE16_TRUE@am_libpcre16_la_OBJECTS = pcre16_byte_order.lo \ +@WITH_PCRE16_TRUE@ pcre16_chartables.lo pcre16_compile.lo \ +@WITH_PCRE16_TRUE@ pcre16_config.lo pcre16_dfa_exec.lo \ +@WITH_PCRE16_TRUE@ pcre16_exec.lo pcre16_fullinfo.lo \ +@WITH_PCRE16_TRUE@ pcre16_get.lo pcre16_globals.lo \ +@WITH_PCRE16_TRUE@ pcre16_jit_compile.lo pcre16_maketables.lo \ +@WITH_PCRE16_TRUE@ pcre16_newline.lo pcre16_ord2utf16.lo \ +@WITH_PCRE16_TRUE@ pcre16_refcount.lo pcre16_string_utils.lo \ +@WITH_PCRE16_TRUE@ pcre16_study.lo pcre16_tables.lo \ +@WITH_PCRE16_TRUE@ pcre16_ucd.lo pcre16_utf16_utils.lo \ +@WITH_PCRE16_TRUE@ pcre16_valid_utf16.lo pcre16_version.lo \ +@WITH_PCRE16_TRUE@ pcre16_xclass.lo +@WITH_PCRE16_TRUE@nodist_libpcre16_la_OBJECTS = pcre_chartables.lo +libpcre16_la_OBJECTS = $(am_libpcre16_la_OBJECTS) \ + $(nodist_libpcre16_la_OBJECTS) +libpcre16_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libpcre16_la_LDFLAGS) $(LDFLAGS) -o $@ +@WITH_PCRE16_TRUE@am_libpcre16_la_rpath = -rpath $(libdir) @WITH_PCRE_CPP_TRUE@libpcrecpp_la_DEPENDENCIES = libpcre.la am__libpcrecpp_la_SOURCES_DIST = pcrecpp_internal.h pcrecpp.cc \ pcre_scanner.cc pcre_stringpiece.cc @WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_OBJECTS = pcrecpp.lo \ @WITH_PCRE_CPP_TRUE@ pcre_scanner.lo pcre_stringpiece.lo libpcrecpp_la_OBJECTS = $(am_libpcrecpp_la_OBJECTS) -libpcrecpp_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libpcrecpp_la_LDFLAGS) $(LDFLAGS) -o $@ +libpcrecpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(libpcrecpp_la_LDFLAGS) $(LDFLAGS) \ + -o $@ @WITH_PCRE_CPP_TRUE@am_libpcrecpp_la_rpath = -rpath $(libdir) -libpcreposix_la_DEPENDENCIES = libpcre.la -am_libpcreposix_la_OBJECTS = pcreposix.lo +@WITH_PCRE8_TRUE@libpcreposix_la_DEPENDENCIES = libpcre.la +am__libpcreposix_la_SOURCES_DIST = pcreposix.c +@WITH_PCRE8_TRUE@am_libpcreposix_la_OBJECTS = pcreposix.lo libpcreposix_la_OBJECTS = $(am_libpcreposix_la_OBJECTS) -libpcreposix_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libpcreposix_la_LDFLAGS) $(LDFLAGS) -o $@ -@WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_1 = dftables$(EXEEXT) -@WITH_PCRE_CPP_TRUE@am__EXEEXT_2 = pcrecpp_unittest$(EXEEXT) \ +libpcreposix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libpcreposix_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +@WITH_PCRE8_TRUE@am_libpcreposix_la_rpath = -rpath $(libdir) +@WITH_PCRE8_TRUE@am__EXEEXT_1 = pcregrep$(EXEEXT) +@WITH_REBUILD_CHARTABLES_TRUE@am__EXEEXT_2 = dftables$(EXEEXT) +@WITH_JIT_TRUE@am__EXEEXT_3 = pcre_jit_test$(EXEEXT) +@WITH_PCRE_CPP_TRUE@am__EXEEXT_4 = pcrecpp_unittest$(EXEEXT) \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest$(EXEEXT) \ @WITH_PCRE_CPP_TRUE@ pcre_stringpiece_unittest$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) @@ -151,6 +221,11 @@ @WITH_REBUILD_CHARTABLES_TRUE@ dftables.$(OBJEXT) dftables_OBJECTS = $(am_dftables_OBJECTS) dftables_LDADD = $(LDADD) +am__pcre_jit_test_SOURCES_DIST = pcre_jit_test.c +@WITH_JIT_TRUE@am_pcre_jit_test_OBJECTS = pcre_jit_test.$(OBJEXT) +pcre_jit_test_OBJECTS = $(am_pcre_jit_test_OBJECTS) +@WITH_JIT_TRUE@pcre_jit_test_DEPENDENCIES = $(am__append_8) \ +@WITH_JIT_TRUE@ $(am__append_9) am__pcre_scanner_unittest_SOURCES_DIST = pcre_scanner_unittest.cc @WITH_PCRE_CPP_TRUE@am_pcre_scanner_unittest_OBJECTS = \ @WITH_PCRE_CPP_TRUE@ pcre_scanner_unittest.$(OBJEXT) @@ -170,14 +245,23 @@ @WITH_PCRE_CPP_TRUE@ pcrecpp_unittest.$(OBJEXT) pcrecpp_unittest_OBJECTS = $(am_pcrecpp_unittest_OBJECTS) @WITH_PCRE_CPP_TRUE@pcrecpp_unittest_DEPENDENCIES = libpcrecpp.la -am_pcregrep_OBJECTS = pcregrep.$(OBJEXT) +am__pcregrep_SOURCES_DIST = pcregrep.c +@WITH_PCRE8_TRUE@am_pcregrep_OBJECTS = pcregrep.$(OBJEXT) pcregrep_OBJECTS = $(am_pcregrep_OBJECTS) am__DEPENDENCIES_1 = -pcregrep_DEPENDENCIES = libpcreposix.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am_pcretest_OBJECTS = pcretest.$(OBJEXT) +@WITH_PCRE8_TRUE@pcregrep_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@WITH_PCRE8_TRUE@ $(am__DEPENDENCIES_1) libpcre.la \ +@WITH_PCRE8_TRUE@ libpcreposix.la +am__pcretest_SOURCES_DIST = pcretest.c pcre_printint.c \ + pcre16_printint.c +@WITH_PCRE8_TRUE@am__objects_1 = pcre_printint.$(OBJEXT) +@WITH_PCRE16_TRUE@am__objects_2 = pcre16_printint.$(OBJEXT) +am_pcretest_OBJECTS = pcretest.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) pcretest_OBJECTS = $(am_pcretest_OBJECTS) -pcretest_DEPENDENCIES = libpcreposix.la $(am__DEPENDENCIES_1) +pcretest_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_15) \ + $(am__append_17) +am__dist_noinst_SCRIPTS_DIST = RunTest RunGrepTest SCRIPTS = $(bin_SCRIPTS) $(dist_noinst_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -185,34 +269,59 @@ am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_$(V)) +am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) +am__v_CXX_0 = @echo " CXX " $@; CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_$(V)) +am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CXXLD_0 = @echo " CXXLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \ + $(libpcre16_la_SOURCES) $(nodist_libpcre16_la_SOURCES) \ $(libpcrecpp_la_SOURCES) $(libpcreposix_la_SOURCES) \ - $(dftables_SOURCES) $(pcre_scanner_unittest_SOURCES) \ + $(dftables_SOURCES) $(pcre_jit_test_SOURCES) \ + $(pcre_scanner_unittest_SOURCES) \ $(pcre_stringpiece_unittest_SOURCES) \ $(pcrecpp_unittest_SOURCES) $(pcregrep_SOURCES) \ $(pcretest_SOURCES) -DIST_SOURCES = $(libpcre_la_SOURCES) $(am__libpcrecpp_la_SOURCES_DIST) \ - $(libpcreposix_la_SOURCES) $(am__dftables_SOURCES_DIST) \ +DIST_SOURCES = $(am__libpcre_la_SOURCES_DIST) \ + $(am__libpcre16_la_SOURCES_DIST) \ + $(am__libpcrecpp_la_SOURCES_DIST) \ + $(am__libpcreposix_la_SOURCES_DIST) \ + $(am__dftables_SOURCES_DIST) $(am__pcre_jit_test_SOURCES_DIST) \ $(am__pcre_scanner_unittest_SOURCES_DIST) \ $(am__pcre_stringpiece_unittest_SOURCES_DIST) \ - $(am__pcrecpp_unittest_SOURCES_DIST) $(pcregrep_SOURCES) \ - $(pcretest_SOURCES) + $(am__pcrecpp_unittest_SOURCES_DIST) \ + $(am__pcregrep_SOURCES_DIST) $(am__pcretest_SOURCES_DIST) man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 NROFF = nroff @@ -238,6 +347,7 @@ distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ @@ -265,6 +375,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +EXTRA_LIBPCRE16_LDFLAGS = @EXTRA_LIBPCRE16_LDFLAGS@ EXTRA_LIBPCRECPP_LDFLAGS = @EXTRA_LIBPCRECPP_LDFLAGS@ EXTRA_LIBPCREPOSIX_LDFLAGS = @EXTRA_LIBPCREPOSIX_LDFLAGS@ EXTRA_LIBPCRE_LDFLAGS = @EXTRA_LIBPCRE_LDFLAGS@ @@ -287,6 +398,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -317,6 +429,7 @@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -337,6 +450,8 @@ docdir = @docdir@ dvidir = @dvidir@ enable_cpp = @enable_cpp@ +enable_pcre16 = @enable_pcre16@ +enable_pcre8 = @enable_pcre8@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ @@ -386,7 +501,9 @@ dist_html_DATA = \ doc/html/index.html \ doc/html/pcre.html \ + doc/html/pcre16.html \ doc/html/pcre-config.html \ + doc/html/pcre_assign_jit_stack.html \ doc/html/pcre_compile.html \ doc/html/pcre_compile2.html \ doc/html/pcre_config.html \ @@ -394,6 +511,7 @@ doc/html/pcre_copy_substring.html \ doc/html/pcre_dfa_exec.html \ doc/html/pcre_exec.html \ + doc/html/pcre_free_study.html \ doc/html/pcre_free_substring.html \ doc/html/pcre_free_substring_list.html \ doc/html/pcre_fullinfo.html \ @@ -402,10 +520,13 @@ doc/html/pcre_get_stringtable_entries.html \ doc/html/pcre_get_substring.html \ doc/html/pcre_get_substring_list.html \ - doc/html/pcre_info.html \ + doc/html/pcre_jit_stack_alloc.html \ + doc/html/pcre_jit_stack_free.html \ doc/html/pcre_maketables.html \ + doc/html/pcre_pattern_to_host_byte_order.html \ doc/html/pcre_refcount.html \ doc/html/pcre_study.html \ + doc/html/pcre_utf16_to_host_byte_order.html \ doc/html/pcre_version.html \ doc/html/pcreapi.html \ doc/html/pcrebuild.html \ @@ -413,6 +534,8 @@ doc/html/pcrecompat.html \ doc/html/pcredemo.html \ doc/html/pcregrep.html \ + doc/html/pcrejit.html \ + doc/html/pcrelimits.html \ doc/html/pcrematching.html \ doc/html/pcrepartial.html \ doc/html/pcrepattern.html \ @@ -422,16 +545,18 @@ doc/html/pcresample.html \ doc/html/pcrestack.html \ doc/html/pcresyntax.html \ - doc/html/pcretest.html + doc/html/pcretest.html \ + doc/html/pcreunicode.html pcrecpp_html = doc/html/pcrecpp.html dist_noinst_DATA = $(pcrecpp_html) @WITH_PCRE_CPP_TRUE@html_DATA = $(pcrecpp_html) # The Libtool libraries to install. We'll add to this later. -lib_LTLIBRARIES = libpcre.la libpcreposix.la $(am__append_4) +lib_LTLIBRARIES = $(am__append_4) $(am__append_5) $(am__append_10) \ + $(am__append_11) check_SCRIPTS = -dist_noinst_SCRIPTS = RunTest RunGrepTest +dist_noinst_SCRIPTS = RunTest $(am__append_19) # Additional files to delete on 'make clean' and 'make maintainer-clean'. CLEANFILES = pcre_chartables.c testsavedregex teststderr testtry \ @@ -451,35 +576,58 @@ # for the benefit of people who are building PCRE manually, without the # Autotools support. -# The pcre_printint.src file is #included by some source files, so it must be -# distributed. The pcre_chartables.c.dist file is the default version of -# pcre_chartables.c, used unless --enable-rebuild-chartables is specified. +# The pcre_chartables.c.dist file is the default version of pcre_chartables.c, +# used unless --enable-rebuild-chartables is specified. + +# The JIT compiler lives in a separate directory, but its files are #included +# when pcre_jit_compile.c is processed, so they must be distributed. # PCRE demonstration program. No longer built automatcally. The point is that # the users should build it themselves. So just distribute the source. # noinst_PROGRAMS += pcredemo # pcredemo_SOURCES = pcredemo.c # pcredemo_LDADD = libpcre.la -EXTRA_DIST = doc/perltest.txt NON-UNIX-USE HACKING PrepareRelease \ - CleanTxt Detrail 132html doc/index.html.src makevp.bat \ - makevp_c.txt makevp_l.txt pcregexp.pas pcre.h.generic \ - config.h.generic pcre_printint.src pcre_chartables.c.dist \ - RunTest.bat testdata/grepinput testdata/grepinput3 \ +EXTRA_DIST = doc/perltest.txt NON-UNIX-USE NON-AUTOTOOLS-BUILD HACKING \ + PrepareRelease CheckMan CleanTxt Detrail 132html \ + doc/index.html.src makevp.bat makevp_c.txt makevp_l.txt \ + pcregexp.pas pcre.h.generic config.h.generic \ + pcre_chartables.c.dist sljit/sljitConfig.h \ + sljit/sljitConfigInternal.h sljit/sljitExecAllocator.c \ + sljit/sljitLir.c sljit/sljitLir.h \ + sljit/sljitNativeARM_Thumb2.c sljit/sljitNativeARM_v5.c \ + sljit/sljitNativeMIPS_32.c sljit/sljitNativeMIPS_common.c \ + sljit/sljitNativePPC_32.c sljit/sljitNativePPC_64.c \ + sljit/sljitNativePPC_common.c sljit/sljitNativeX86_32.c \ + sljit/sljitNativeX86_64.c sljit/sljitNativeX86_common.c \ + sljit/sljitUtils.c RunTest.bat testdata/grepbinary \ + testdata/grepfilelist testdata/grepinput testdata/grepinput3 \ testdata/grepinput8 testdata/grepinputv testdata/grepinputx \ testdata/greplist testdata/grepoutput testdata/grepoutput8 \ - testdata/grepoutputN testdata/testinput1 testdata/testinput2 \ - testdata/testinput3 testdata/testinput4 testdata/testinput5 \ - testdata/testinput6 testdata/testinput7 testdata/testinput8 \ - testdata/testinput9 testdata/testinput10 testdata/testinput11 \ - testdata/testinput12 testdata/testoutput1 testdata/testoutput2 \ - testdata/testoutput3 testdata/testoutput4 testdata/testoutput5 \ - testdata/testoutput6 testdata/testoutput7 testdata/testoutput8 \ - testdata/testoutput9 testdata/testoutput10 \ - testdata/testoutput11 testdata/testoutput12 \ + testdata/grepoutputN testdata/greppatN4 testdata/saved16 \ + testdata/saved16BE-1 testdata/saved16BE-2 testdata/saved16LE-1 \ + testdata/saved16LE-2 testdata/saved8 testdata/testinput1 \ + testdata/testinput2 testdata/testinput3 testdata/testinput4 \ + testdata/testinput5 testdata/testinput6 testdata/testinput7 \ + testdata/testinput8 testdata/testinput9 testdata/testinput10 \ + testdata/testinput11 testdata/testinput12 testdata/testinput13 \ + testdata/testinput14 testdata/testinput15 testdata/testinput16 \ + testdata/testinput17 testdata/testinput18 testdata/testinput19 \ + testdata/testinput20 testdata/testinput21 testdata/testinput22 \ + testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \ + testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \ + testdata/testoutput7 testdata/testoutput8 testdata/testoutput9 \ + testdata/testoutput10 testdata/testoutput11-16 \ + testdata/testoutput11-8 testdata/testoutput12 \ + testdata/testoutput13 testdata/testoutput14 \ + testdata/testoutput15 testdata/testoutput16 \ + testdata/testoutput17 testdata/testoutput18 \ + testdata/testoutput19 testdata/testoutput20 \ + testdata/testoutput21 testdata/testoutput22 \ testdata/wintestinput3 testdata/wintestoutput3 perltest.pl \ pcredemo.c $(pcrecpp_man) cmake/COPYING-CMAKE-SCRIPTS \ cmake/FindPackageHandleStandardArgs.cmake \ - cmake/FindReadline.cmake CMakeLists.txt config-cmake.h.in + cmake/FindReadline.cmake cmake/FindEditline.cmake \ + CMakeLists.txt config-cmake.h.in # These are the header files we'll install. We do not distribute pcre.h because # it is generated from pcre.h.in. @@ -487,38 +635,70 @@ include_HEADERS = pcreposix.h $(am__append_2) bin_SCRIPTS = pcre-config @WITH_REBUILD_CHARTABLES_TRUE@dftables_SOURCES = dftables.c -libpcre_la_SOURCES = \ - pcre_compile.c \ - pcre_config.c \ - pcre_dfa_exec.c \ - pcre_exec.c \ - pcre_fullinfo.c \ - pcre_get.c \ - pcre_globals.c \ - pcre_info.c \ - pcre_internal.h \ - pcre_maketables.c \ - pcre_newline.c \ - pcre_ord2utf8.c \ - pcre_refcount.c \ - pcre_study.c \ - pcre_tables.c \ - pcre_try_flipped.c \ - pcre_ucd.c \ - pcre_valid_utf8.c \ - pcre_version.c \ - pcre_xclass.c \ - ucp.h - -nodist_libpcre_la_SOURCES = \ - pcre_chartables.c - -libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) -libpcreposix_la_SOURCES = \ - pcreposix.c +BUILT_SOURCES = pcre_chartables.c +@WITH_PCRE8_TRUE@libpcre_la_SOURCES = \ +@WITH_PCRE8_TRUE@ pcre_byte_order.c \ +@WITH_PCRE8_TRUE@ pcre_compile.c \ +@WITH_PCRE8_TRUE@ pcre_config.c \ +@WITH_PCRE8_TRUE@ pcre_dfa_exec.c \ +@WITH_PCRE8_TRUE@ pcre_exec.c \ +@WITH_PCRE8_TRUE@ pcre_fullinfo.c \ +@WITH_PCRE8_TRUE@ pcre_get.c \ +@WITH_PCRE8_TRUE@ pcre_globals.c \ +@WITH_PCRE8_TRUE@ pcre_internal.h \ +@WITH_PCRE8_TRUE@ pcre_jit_compile.c \ +@WITH_PCRE8_TRUE@ pcre_maketables.c \ +@WITH_PCRE8_TRUE@ pcre_newline.c \ +@WITH_PCRE8_TRUE@ pcre_ord2utf8.c \ +@WITH_PCRE8_TRUE@ pcre_refcount.c \ +@WITH_PCRE8_TRUE@ pcre_string_utils.c \ +@WITH_PCRE8_TRUE@ pcre_study.c \ +@WITH_PCRE8_TRUE@ pcre_tables.c \ +@WITH_PCRE8_TRUE@ pcre_ucd.c \ +@WITH_PCRE8_TRUE@ pcre_valid_utf8.c \ +@WITH_PCRE8_TRUE@ pcre_version.c \ +@WITH_PCRE8_TRUE@ pcre_xclass.c \ +@WITH_PCRE8_TRUE@ ucp.h + +@WITH_PCRE8_TRUE@nodist_libpcre_la_SOURCES = \ +@WITH_PCRE8_TRUE@ pcre_chartables.c + +@WITH_PCRE16_TRUE@libpcre16_la_SOURCES = \ +@WITH_PCRE16_TRUE@ pcre16_byte_order.c \ +@WITH_PCRE16_TRUE@ pcre16_chartables.c \ +@WITH_PCRE16_TRUE@ pcre16_compile.c \ +@WITH_PCRE16_TRUE@ pcre16_config.c \ +@WITH_PCRE16_TRUE@ pcre16_dfa_exec.c \ +@WITH_PCRE16_TRUE@ pcre16_exec.c \ +@WITH_PCRE16_TRUE@ pcre16_fullinfo.c \ +@WITH_PCRE16_TRUE@ pcre16_get.c \ +@WITH_PCRE16_TRUE@ pcre16_globals.c \ +@WITH_PCRE16_TRUE@ pcre16_jit_compile.c \ +@WITH_PCRE16_TRUE@ pcre16_maketables.c \ +@WITH_PCRE16_TRUE@ pcre16_newline.c \ +@WITH_PCRE16_TRUE@ pcre16_ord2utf16.c \ +@WITH_PCRE16_TRUE@ pcre16_refcount.c \ +@WITH_PCRE16_TRUE@ pcre16_string_utils.c \ +@WITH_PCRE16_TRUE@ pcre16_study.c \ +@WITH_PCRE16_TRUE@ pcre16_tables.c \ +@WITH_PCRE16_TRUE@ pcre16_ucd.c \ +@WITH_PCRE16_TRUE@ pcre16_utf16_utils.c \ +@WITH_PCRE16_TRUE@ pcre16_valid_utf16.c \ +@WITH_PCRE16_TRUE@ pcre16_version.c \ +@WITH_PCRE16_TRUE@ pcre16_xclass.c + +@WITH_PCRE16_TRUE@nodist_libpcre16_la_SOURCES = \ +@WITH_PCRE16_TRUE@ pcre_chartables.c + +@WITH_PCRE8_TRUE@libpcre_la_LDFLAGS = $(EXTRA_LIBPCRE_LDFLAGS) +@WITH_PCRE16_TRUE@libpcre16_la_LDFLAGS = $(EXTRA_LIBPCRE16_LDFLAGS) +@WITH_JIT_TRUE@pcre_jit_test_SOURCES = pcre_jit_test.c +@WITH_JIT_TRUE@pcre_jit_test_LDADD = $(am__append_8) $(am__append_9) +@WITH_PCRE8_TRUE@libpcreposix_la_SOURCES = \ +@WITH_PCRE8_TRUE@ pcreposix.c -libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) -libpcreposix_la_LIBADD = libpcre.la +@WITH_PCRE8_TRUE@libpcreposix_la_LDFLAGS = $(EXTRA_LIBPCREPOSIX_LDFLAGS) +@WITH_PCRE8_TRUE@libpcreposix_la_LIBADD = libpcre.la @WITH_PCRE_CPP_TRUE@libpcrecpp_la_SOURCES = \ @WITH_PCRE_CPP_TRUE@ pcrecpp_internal.h \ @WITH_PCRE_CPP_TRUE@ pcrecpp.cc \ @@ -533,30 +713,33 @@ @WITH_PCRE_CPP_TRUE@pcre_scanner_unittest_LDADD = libpcrecpp.la @WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_SOURCES = pcre_stringpiece_unittest.cc @WITH_PCRE_CPP_TRUE@pcre_stringpiece_unittest_LDADD = libpcrecpp.la -pcretest_SOURCES = pcretest.c -pcretest_LDADD = libpcreposix.la $(LIBREADLINE) -pcregrep_SOURCES = pcregrep.c -pcregrep_LDADD = libpcreposix.la $(LIBZ) $(LIBBZ2) +pcretest_SOURCES = pcretest.c $(am__append_14) $(am__append_16) +pcretest_LDADD = $(LIBREADLINE) $(am__append_15) $(am__append_17) +@WITH_PCRE8_TRUE@pcregrep_SOURCES = pcregrep.c +@WITH_PCRE8_TRUE@pcregrep_LDADD = $(LIBZ) $(LIBBZ2) libpcre.la \ +@WITH_PCRE8_TRUE@ libpcreposix.la # A PCRE user submitted the following addition, saying that it "will allow # anyone using the 'mingw32' compiler to simply type 'make pcre.dll' and get a # nice DLL for Windows use". (It is used by the pcre.dll target.) -DLL_OBJS = pcre_compile.o pcre_config.o \ +DLL_OBJS = pcre_byte_order.o pcre_compile.o pcre_config.o \ pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ - pcre_globals.o pcre_info.o pcre_maketables.o \ + pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ - pcre_study.o pcre_tables.o pcre_try_flipped.o \ - pcre_ucd.o pcre_valid_utf8.o pcre_version.o \ - pcre_chartables.o \ + pcre_study.o pcre_tables.o pcre_ucd.o \ + pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ pcre_xclass.o # We have .pc files for pkg-config users. pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libpcre.pc libpcreposix.pc $(am__append_7) +pkgconfig_DATA = libpcre.pc libpcreposix.pc $(am__append_21) \ + $(am__append_22) dist_man_MANS = \ doc/pcre.3 \ + doc/pcre16.3 \ doc/pcre-config.1 \ + doc/pcre_assign_jit_stack.3 \ doc/pcre_compile.3 \ doc/pcre_compile2.3 \ doc/pcre_config.3 \ @@ -564,6 +747,7 @@ doc/pcre_copy_substring.3 \ doc/pcre_dfa_exec.3 \ doc/pcre_exec.3 \ + doc/pcre_free_study.3 \ doc/pcre_free_substring.3 \ doc/pcre_free_substring_list.3 \ doc/pcre_fullinfo.3 \ @@ -572,16 +756,21 @@ doc/pcre_get_stringtable_entries.3 \ doc/pcre_get_substring.3 \ doc/pcre_get_substring_list.3 \ - doc/pcre_info.3 \ + doc/pcre_jit_stack_alloc.3 \ + doc/pcre_jit_stack_free.3 \ doc/pcre_maketables.3 \ + doc/pcre_pattern_to_host_byte_order.3 \ doc/pcre_refcount.3 \ doc/pcre_study.3 \ + doc/pcre_utf16_to_host_byte_order.3 \ doc/pcre_version.3 \ doc/pcreapi.3 \ doc/pcrebuild.3 \ doc/pcrecallout.3 \ doc/pcrecompat.3 \ doc/pcregrep.1 \ + doc/pcrejit.3 \ + doc/pcrelimits.3 \ doc/pcrematching.3 \ doc/pcrepartial.3 \ doc/pcrepattern.3 \ @@ -591,11 +780,12 @@ doc/pcresample.3 \ doc/pcrestack.3 \ doc/pcresyntax.3 \ - doc/pcretest.1 + doc/pcretest.1 \ + doc/pcreunicode.3 pcrecpp_man = doc/pcrecpp.3 @WITH_PCRE_CPP_TRUE@man_MANS = $(pcrecpp_man) -all: config.h +all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: @@ -653,6 +843,8 @@ -rm -f config.h stamp-h1 libpcre.pc: $(top_builddir)/config.status $(srcdir)/libpcre.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ +libpcre16.pc: $(top_builddir)/config.status $(srcdir)/libpcre16.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ libpcreposix.pc: $(top_builddir)/config.status $(srcdir)/libpcreposix.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libpcrecpp.pc: $(top_builddir)/config.status $(srcdir)/libpcrecpp.pc.in @@ -697,11 +889,13 @@ rm -f "$${dir}/so_locations"; \ done libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) - $(libpcre_la_LINK) -rpath $(libdir) $(libpcre_la_OBJECTS) $(libpcre_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(libpcre_la_LINK) $(am_libpcre_la_rpath) $(libpcre_la_OBJECTS) $(libpcre_la_LIBADD) $(LIBS) +libpcre16.la: $(libpcre16_la_OBJECTS) $(libpcre16_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpcre16_la_LINK) $(am_libpcre16_la_rpath) $(libpcre16_la_OBJECTS) $(libpcre16_la_LIBADD) $(LIBS) libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) - $(libpcrecpp_la_LINK) $(am_libpcrecpp_la_rpath) $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_LIBADD) $(LIBS) + $(AM_V_CXXLD)$(libpcrecpp_la_LINK) $(am_libpcrecpp_la_rpath) $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_LIBADD) $(LIBS) libpcreposix.la: $(libpcreposix_la_OBJECTS) $(libpcreposix_la_DEPENDENCIES) - $(libpcreposix_la_LINK) -rpath $(libdir) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(libpcreposix_la_LINK) $(am_libpcreposix_la_rpath) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -756,22 +950,25 @@ rm -f $$list dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) @rm -f dftables$(EXEEXT) - $(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS) +pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) + @rm -f pcre_jit_test$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pcre_jit_test_OBJECTS) $(pcre_jit_test_LDADD) $(LIBS) pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) @rm -f pcre_scanner_unittest$(EXEEXT) - $(CXXLINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS) pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) @rm -f pcre_stringpiece_unittest$(EXEEXT) - $(CXXLINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS) pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) @rm -f pcrecpp_unittest$(EXEEXT) - $(CXXLINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS) + $(AM_V_CXXLD)$(CXXLINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS) pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) @rm -f pcregrep$(EXEEXT) - $(LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS) pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) @rm -f pcretest$(EXEEXT) - $(LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -814,6 +1011,30 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dftables.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_byte_order.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_chartables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_dfa_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_exec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_fullinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_get.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_globals.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_maketables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_newline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_ord2utf16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_printint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_refcount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_string_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_study.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_tables.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_ucd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_utf16_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_valid_utf16.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre16_xclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_byte_order.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_chartables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_compile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_config.Plo@am__quote@ @@ -822,18 +1043,20 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_fullinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_get.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_globals.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_compile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_maketables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_newline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ord2utf8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_printint.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_refcount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_scanner_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_string_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_stringpiece_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_study.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_tables.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_try_flipped.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_ucd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_valid_utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_version.Plo@am__quote@ @@ -845,43 +1068,49 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcretest.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< .cc.o: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cc.obj: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< @@ -1399,7 +1628,8 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ $(HEADERS) config.h install-binPROGRAMS: install-libLTLIBRARIES @@ -1408,7 +1638,8 @@ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -1434,6 +1665,7 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am @@ -1462,7 +1694,8 @@ install-data-am: install-dist_docDATA install-dist_htmlDATA \ install-htmlDATA install-includeHEADERS install-man \ install-nodist_includeHEADERS install-pkgconfigDATA - + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: @@ -1518,7 +1751,8 @@ uninstall-man: uninstall-man1 uninstall-man3 -.MAKE: all check-am install-am install-strip +.MAKE: all check check-am install install-am install-data-am \ + install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \ clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ @@ -1529,9 +1763,9 @@ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-binSCRIPTS install-data \ - install-data-am install-dist_docDATA install-dist_htmlDATA \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-htmlDATA \ + install-data-am install-data-hook install-dist_docDATA \ + install-dist_htmlDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-htmlDATA \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-man install-man1 install-man3 \ install-nodist_includeHEADERS install-pdf install-pdf-am \ @@ -1567,6 +1801,34 @@ pcre.dll: $(DLL_OBJS) $(CC) -shared -o pcre.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS) +# Arrange for the per-function man pages to have 16-bit names as well. +install-data-hook: + ln -sf pcre_assign_jit_stack.3 $(DESTDIR)$(man3dir)/pcre16_assign_jit_stack.3 + ln -sf pcre_compile.3 $(DESTDIR)$(man3dir)/pcre16_compile.3 + ln -sf pcre_compile2.3 $(DESTDIR)$(man3dir)/pcre16_compile2.3 + ln -sf pcre_config.3 $(DESTDIR)$(man3dir)/pcre16_config.3 + ln -sf pcre_copy_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_named_substring.3 + ln -sf pcre_copy_substring.3 $(DESTDIR)$(man3dir)/pcre16_copy_substring.3 + ln -sf pcre_dfa_exec.3 $(DESTDIR)$(man3dir)/pcre16_dfa_exec.3 + ln -sf pcre_exec.3 $(DESTDIR)$(man3dir)/pcre16_exec.3 + ln -sf pcre_free_study.3 $(DESTDIR)$(man3dir)/pcre16_free_study.3 + ln -sf pcre_free_substring.3 $(DESTDIR)$(man3dir)/pcre16_free_substring.3 + ln -sf pcre_free_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_free_substring_list.3 + ln -sf pcre_fullinfo.3 $(DESTDIR)$(man3dir)/pcre16_fullinfo.3 + ln -sf pcre_get_named_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_named_substring.3 + ln -sf pcre_get_stringnumber.3 $(DESTDIR)$(man3dir)/pcre16_get_stringnumber.3 + ln -sf pcre_get_stringtable_entries.3 $(DESTDIR)$(man3dir)/pcre16_get_stringtable_entries.3 + ln -sf pcre_get_substring.3 $(DESTDIR)$(man3dir)/pcre16_get_substring.3 + ln -sf pcre_get_substring_list.3 $(DESTDIR)$(man3dir)/pcre16_get_substring_list.3 + ln -sf pcre_jit_stack_alloc.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_alloc.3 + ln -sf pcre_jit_stack_free.3 $(DESTDIR)$(man3dir)/pcre16_jit_stack_free.3 + ln -sf pcre_maketables.3 $(DESTDIR)$(man3dir)/pcre16_maketables.3 + ln -sf pcre_pattern_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_pattern_to_host_byte_order.3 + ln -sf pcre_refcount.3 $(DESTDIR)$(man3dir)/pcre16_refcount.3 + ln -sf pcre_study.3 $(DESTDIR)$(man3dir)/pcre16_study.3 + ln -sf pcre_utf16_to_host_byte_order.3 $(DESTDIR)$(man3dir)/pcre16_utf16_to_host_byte_order.3 + ln -sf pcre_version.3 $(DESTDIR)$(man3dir)/pcre16_version.3 + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru pcre3-8.12/NEWS pcre3-8.31/NEWS --- pcre3-8.12/NEWS 2011-01-15 11:25:12.000000000 +0000 +++ pcre3-8.31/NEWS 2012-07-06 09:06:23.000000000 +0000 @@ -1,6 +1,82 @@ News about PCRE releases ------------------------ +Release 8.31 06-July-2012 +------------------------- + +This is mainly a bug-fixing release, with a small number of developments: + +. The JIT compiler now supports partial matching and the (*MARK) and + (*COMMIT) verbs. + +. PCRE_INFO_MAXLOOKBEHIND can be used to find the longest lookbehing in a + pattern. + +. There should be a performance improvement when using the heap instead of the + stack for recursion. + +. pcregrep can now be linked with libedit as an alternative to libreadline. + +. pcregrep now has a --file-list option where the list of files to scan is + given as a file. + +. pcregrep now recognizes binary files and there are related options. + +. The Unicode tables have been updated to 6.1.0. + +As always, the full list of changes is in the ChangeLog file. + + +Release 8.30 04-February-2012 +----------------------------- + +Release 8.30 introduces a major new feature: support for 16-bit character +strings, compiled as a separate library. There are a few changes to the +8-bit library, in addition to some bug fixes. + +. The pcre_info() function, which has been obsolete for over 10 years, has + been removed. + +. When a compiled pattern was saved to a file and later reloaded on a host + with different endianness, PCRE used automatically to swap the bytes in some + of the data fields. With the advent of the 16-bit library, where more of this + swapping is needed, it is no longer done automatically. Instead, the bad + endianness is detected and a specific error is given. The user can then call + a new function called pcre_pattern_to_host_byte_order() (or an equivalent + 16-bit function) to do the swap. + +. In UTF-8 mode, the values 0xd800 to 0xdfff are not legal Unicode + code points and are now faulted. (They are the so-called "surrogates" + that are reserved for coding high values in UTF-16.) + + +Release 8.21 12-Dec-2011 +------------------------ + +This is almost entirely a bug-fix release. The only new feature is the ability +to obtain the size of the memory used by the JIT compiler. + + +Release 8.20 21-Oct-2011 +------------------------ + +The main change in this release is the inclusion of Zoltan Herczeg's +just-in-time compiler support, which can be accessed by building PCRE with +--enable-jit. Large performance benefits can be had in many situations. 8.20 +also fixes an unfortunate bug that was introduced in 8.13 as well as tidying up +a number of infelicities and differences from Perl. + + +Release 8.13 16-Aug-2011 +------------------------ + +This is mainly a bug-fix release. There has been a lot of internal refactoring. +The Unicode tables have been updated. The only new feature in the library is +the passing of *MARK information to callouts. Some additions have been made to +pcretest to make testing easier and more comprehensive. There is a new option +for pcregrep to adjust its internal buffer size. + + Release 8.12 15-Jan-2011 ------------------------ diff -Nru pcre3-8.12/NON-AUTOTOOLS-BUILD pcre3-8.31/NON-AUTOTOOLS-BUILD --- pcre3-8.12/NON-AUTOTOOLS-BUILD 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/NON-AUTOTOOLS-BUILD 2012-06-20 15:08:49.000000000 +0000 @@ -0,0 +1,585 @@ +Building PCRE without using autotools +------------------------------------- + +This document contains the following sections: + + General + Generic instructions for the PCRE C library + The C++ wrapper functions + Building for virtual Pascal + Stack size in Windows environments + Linking programs in Windows environments + Comments about Win32 builds + Building PCRE on Windows with CMake + Use of relative paths with CMake on Windows + Testing with RunTest.bat + Building under Windows with BCC5.5 + Building PCRE on OpenVMS + Building PCRE on Stratus OpenVOS + + +GENERAL + +I (Philip Hazel) have no experience of Windows or VMS sytems and how their +libraries work. The items in the PCRE distribution and Makefile that relate to +anything other than Linux systems are untested by me. + +There are some other comments and files (including some documentation in CHM +format) in the Contrib directory on the FTP site: + + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib + +The basic PCRE library consists entirely of code written in Standard C, and so +should compile successfully on any system that has a Standard C compiler and +library. The C++ wrapper functions are a separate issue (see below). + +The PCRE distribution includes a "configure" file for use by the configure/make +(autotools) build system, as found in many Unix-like environments. The README +file contains information about the options for "configure". + +There is also support for CMake, which some users prefer, especially in Windows +environments, though it can also be run in Unix-like environments. See the +section entitled "Building PCRE on Windows with CMake" below. + +Versions of config.h and pcre.h are distributed in the PCRE tarballs under the +names config.h.generic and pcre.h.generic. These are provided for those who +build PCRE without using "configure" or CMake. If you use "configure" or CMake, +the .generic versions are not used. + + +GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY + +The following are generic instructions for building the PCRE C library "by +hand": + + (1) Copy or rename the file config.h.generic as config.h, and edit the macro + settings that it contains to whatever is appropriate for your environment. + In particular, if you want to force a specific value for newline, you can + define the NEWLINE macro. When you compile any of the PCRE modules, you + must specify -DHAVE_CONFIG_H to your compiler so that config.h is included + in the sources. + + An alternative approach is not to edit config.h, but to use -D on the + compiler command line to make any changes that you need to the + configuration options. In this case -DHAVE_CONFIG_H must not be set. + + NOTE: There have been occasions when the way in which certain parameters + in config.h are used has changed between releases. (In the configure/make + world, this is handled automatically.) When upgrading to a new release, + you are strongly advised to review config.h.generic before re-using what + you had previously. + + (2) Copy or rename the file pcre.h.generic as pcre.h. + + (3) EITHER: + Copy or rename file pcre_chartables.c.dist as pcre_chartables.c. + + OR: + Compile dftables.c as a stand-alone program (using -DHAVE_CONFIG_H if + you have set up config.h), and then run it with the single argument + "pcre_chartables.c". This generates a set of standard character tables + and writes them to that file. The tables are generated using the default + C locale for your system. If you want to use a locale that is specified + by LC_xxx environment variables, add the -L option to the dftables + command. You must use this method if you are building on a system that + uses EBCDIC code. + + The tables in pcre_chartables.c are defaults. The caller of PCRE can + specify alternative tables at run time. + + (4) Ensure that you have the following header files: + + pcre_internal.h + ucp.h + + (5) For an 8-bit library, compile the following source files, setting + -DHAVE_CONFIG_H as a compiler option if you have set up config.h with your + configuration, or else use other -D settings to change the configuration + as required. + + pcre_byte_order.c + pcre_chartables.c + pcre_compile.c + pcre_config.c + pcre_dfa_exec.c + pcre_exec.c + pcre_fullinfo.c + pcre_get.c + pcre_globals.c + pcre_maketables.c + pcre_newline.c + pcre_ord2utf8.c + pcre_refcount.c + pcre_string_utils.c + pcre_study.c + pcre_tables.c + pcre_ucd.c + pcre_valid_utf8.c + pcre_version.c + pcre_xclass.c + + Make sure that you include -I. in the compiler command (or equivalent for + an unusual compiler) so that all included PCRE header files are first + sought in the current directory. Otherwise you run the risk of picking up + a previously-installed file from somewhere else. + + (6) If you have defined SUPPORT_JIT in config.h, you must also compile + + pcre_jit_compile.c + + This file #includes sources from the sljit subdirectory, where there + should be 16 files, all of whose names begin with "sljit". + + (7) Now link all the compiled code into an object library in whichever form + your system keeps such libraries. This is the basic PCRE C 8-bit library. + If your system has static and shared libraries, you may have to do this + once for each type. + + (8) If you want to build a 16-bit library (as well as, or instead of the 8-bit + library) repeat steps 5-7 with the following files: + + pcre16_byte_order.c + pcre16_chartables.c + pcre16_compile.c + pcre16_config.c + pcre16_dfa_exec.c + pcre16_exec.c + pcre16_fullinfo.c + pcre16_get.c + pcre16_globals.c + pcre16_jit_compile.c (if SUPPORT_JIT is defined) + pcre16_maketables.c + pcre16_newline.c + pcre16_ord2utf16.c + pcre16_refcount.c + pcre16_string_utils.c + pcre16_study.c + pcre16_tables.c + pcre16_ucd.c + pcre16_utf16_utils.c + pcre16_valid_utf16.c + pcre16_version.c + pcre16_xclass.c + + (9) If you want to build the POSIX wrapper functions (which apply only to the + 8-bit library), ensure that you have the pcreposix.h file and then compile + pcreposix.c (remembering -DHAVE_CONFIG_H if necessary). Link the result + (on its own) as the pcreposix library. + +(10) The pcretest program can be linked with either or both of the 8-bit and + 16-bit libraries (depending on what you selected in config.h). Compile + pcretest.c and pcre_printint.c (again, don't forget -DHAVE_CONFIG_H) and + link them together with the appropriate library/ies. If you compiled an + 8-bit library, pcretest also needs the pcreposix wrapper library unless + you compiled it with -DNOPOSIX. + +(11) Run pcretest on the testinput files in the testdata directory, and check + that the output matches the corresponding testoutput files. There are + comments about what each test does in the section entitled "Testing PCRE" + in the README file. If you compiled both an 8-bit and a 16-bit library, + you need to run pcretest with the -16 option to do 16-bit tests. + + Some tests are relevant only when certain build-time options are selected. + For example, test 4 is for UTF-8 or UTF-16 support, and will not run if + you have built PCRE without it. See the comments at the start of each + testinput file. If you have a suitable Unix-like shell, the RunTest script + will run the appropriate tests for you. + + Note that the supplied files are in Unix format, with just LF characters + as line terminators. You may need to edit them to change this if your + system uses a different convention. If you are using Windows, you probably + should use the wintestinput3 file instead of testinput3 (and the + corresponding output file). This is a locale test; wintestinput3 sets the + locale to "french" rather than "fr_FR", and there some minor output + differences. + +(12) If you have built PCRE with SUPPORT_JIT, the JIT features will be tested + by the testdata files. However, you might also like to build and run + the JIT test program, pcre_jit_test.c. + +(13) If you want to use the pcregrep command, compile and link pcregrep.c; it + uses only the basic 8-bit PCRE library (it does not need the pcreposix + library). + + +THE C++ WRAPPER FUNCTIONS + +The PCRE distribution also contains some C++ wrapper functions and tests, +applicable to the 8-bit library, which were contributed by Google Inc. On a +system that can use "configure" and "make", the functions are automatically +built into a library called pcrecpp. It should be straightforward to compile +the .cc files manually on other systems. The files called xxx_unittest.cc are +test programs for each of the corresponding xxx.cc files. + + +BUILDING FOR VIRTUAL PASCAL + +A script for building PCRE using Borland's C++ compiler for use with VPASCAL +was contributed by Alexander Tokarev. Stefan Weber updated the script and added +additional files. The following files in the distribution are for building PCRE +for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas. + + +STACK SIZE IN WINDOWS ENVIRONMENTS + +The default processor stack size of 1Mb in some Windows environments is too +small for matching patterns that need much recursion. In particular, test 2 may +fail because of this. Normally, running out of stack causes a crash, but there +have been cases where the test program has just died silently. See your linker +documentation for how to increase stack size if you experience problems. The +Linux default of 8Mb is a reasonable choice for the stack, though even that can +be too small for some pattern/subject combinations. + +PCRE has a compile configuration option to disable the use of stack for +recursion so that heap is used instead. However, pattern matching is +significantly slower when this is done. There is more about stack usage in the +"pcrestack" documentation. + + +LINKING PROGRAMS IN WINDOWS ENVIRONMENTS + +If you want to statically link a program against a PCRE library in the form of +a non-dll .a file, you must define PCRE_STATIC before including pcre.h or +pcrecpp.h, otherwise the pcre_malloc() and pcre_free() exported functions will +be declared __declspec(dllimport), with unwanted results. + + +CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS + +It is possible to compile programs to use different calling conventions using +MSVC. Search the web for "calling conventions" for more information. To make it +easier to change the calling convention for the exported functions in the +PCRE library, the macro PCRE_CALL_CONVENTION is present in all the external +definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is +not set, it defaults to empty; the default calling convention is then used +(which is what is wanted most of the time). + + +COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE ON WINDOWS WITH CMAKE") + +There are two ways of building PCRE using the "configure, make, make install" +paradigm on Windows systems: using MinGW or using Cygwin. These are not at all +the same thing; they are completely different from each other. There is also +support for building using CMake, which some users find a more straightforward +way of building PCRE under Windows. + +The MinGW home page (http://www.mingw.org/) says this: + + MinGW: A collection of freely available and freely distributable Windows + specific header files and import libraries combined with GNU toolsets that + allow one to produce native Windows programs that do not rely on any + 3rd-party C runtime DLLs. + +The Cygwin home page (http://www.cygwin.com/) says this: + + Cygwin is a Linux-like environment for Windows. It consists of two parts: + + . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing + substantial Linux API functionality + + . A collection of tools which provide Linux look and feel. + + The Cygwin DLL currently works with all recent, commercially released x86 32 + bit and 64 bit versions of Windows, with the exception of Windows CE. + +On both MinGW and Cygwin, PCRE should build correctly using: + + ./configure && make && make install + +This should create two libraries called libpcre and libpcreposix, and, if you +have enabled building the C++ wrapper, a third one called libpcrecpp. These are +independent libraries: when you link with libpcreposix or libpcrecpp you must +also link with libpcre, which contains the basic functions. (Some earlier +releases of PCRE included the basic libpcre functions in libpcreposix. This no +longer happens.) + +A user submitted a special-purpose patch that makes it easy to create +"pcre.dll" under mingw32 using the "msys" environment. It provides "pcre.dll" +as a special target. If you use this target, no other files are built, and in +particular, the pcretest and pcregrep programs are not built. An example of how +this might be used is: + + ./configure --enable-utf --disable-cpp CFLAGS="-03 -s"; make pcre.dll + +Using Cygwin's compiler generates libraries and executables that depend on +cygwin1.dll. If a library that is generated this way is distributed, +cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL +licence, this forces not only PCRE to be under the GPL, but also the entire +application. A distributor who wants to keep their own code proprietary must +purchase an appropriate Cygwin licence. + +MinGW has no such restrictions. The MinGW compiler generates a library or +executable that can run standalone on Windows without any third party dll or +licensing issues. + +But there is more complication: + +If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is +to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a +front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's +gcc and MinGW's gcc). So, a user can: + +. Build native binaries by using MinGW or by getting Cygwin and using + -mno-cygwin. + +. Build binaries that depend on cygwin1.dll by using Cygwin with the normal + compiler flags. + +The test files that are supplied with PCRE are in UNIX format, with LF +characters as line terminators. Unless your PCRE library uses a default newline +option that includes LF as a valid newline, it may be necessary to change the +line terminators in the test files to get some of the tests to work. + + +BUILDING PCRE ON WINDOWS WITH CMAKE + +CMake is an alternative configuration facility that can be used instead of +"configure". CMake creates project files (make files, solution files, etc.) +tailored to numerous development environments, including Visual Studio, +Borland, Msys, MinGW, NMake, and Unix. If possible, use short paths with no +spaces in the names for your CMake installation and your PCRE source and build +directories. + +The following instructions were contributed by a PCRE user. + +1. Install the latest CMake version available from http://www.cmake.org/, and + ensure that cmake\bin is on your path. + +2. Unzip (retaining folder structure) the PCRE source tree into a source + directory such as C:\pcre. You should ensure your local date and time + is not earlier than the file dates in your source dir if the release is + very new. + +3. Create a new, empty build directory, preferably a subdirectory of the + source dir. For example, C:\pcre\pcre-xx\build. + +4. Run cmake-gui from the Shell envirornment of your build tool, for example, + Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. + +5. Enter C:\pcre\pcre-xx and C:\pcre\pcre-xx\build for the source and build + directories, respectively. + +6. Hit the "Configure" button. + +7. Select the particular IDE / build tool that you are using (Visual + Studio, MSYS makefiles, MinGW makefiles, etc.) + +8. The GUI will then list several configuration options. This is where + you can enable UTF-8 support or other PCRE optional features. + +9. Hit "Configure" again. The adjacent "Generate" button should now be + active. + +10. Hit "Generate". + +11. The build directory should now contain a usable build system, be it a + solution file for Visual Studio, makefiles for MinGW, etc. Exit from + cmake-gui and use the generated build system with your compiler or IDE. + E.g., for MinGW you can run "make", or for Visual Studio, open the PCRE + solution, select the desired configuration (Debug, or Release, etc.) and + build the ALL_BUILD project. + +12. If during configuration with cmake-gui you've elected to build the test + programs, you can execute them by building the test project. E.g., for + MinGW: "make test"; for Visual Studio build the RUN_TESTS project. The + most recent build configuration is targeted by the tests. A summary of + test results is presented. Complete test output is subsequently + available for review in Testing\Temporary under your build dir. + + +USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS + +A PCRE user comments as follows: + +I thought that others may want to know the current state of +CMAKE_USE_RELATIVE_PATHS support on Windows. + +Here it is: +-- AdditionalIncludeDirectories is only partially modified (only the +first path - see below) +-- Only some of the contained file paths are modified - shown below for +pcre.vcproj +-- It properly modifies + +I am sure CMake people can fix that if they want to. Until then one will +need to replace existing absolute paths in project files with relative +paths manually (e.g. from VS) - relative to project file location. I did +just that before being told to try CMAKE_USE_RELATIVE_PATHS. Not a big +deal. + +AdditionalIncludeDirectories="E:\builds\pcre\build;E:\builds\pcre\pcre-7.5;" +AdditionalIncludeDirectories=".;E:\builds\pcre\pcre-7.5;" + +RelativePath="pcre.h"> +RelativePath="pcre_chartables.c"> +RelativePath="pcre_chartables.c.rule"> + + +TESTING WITH RUNTEST.BAT + +If configured with CMake, building the test project ("make test" or building +ALL_TESTS in Visual Studio) creates (and runs) pcre_test.bat (and depending +on your configuration options, possibly other test programs) in the build +directory. Pcre_test.bat runs RunTest.Bat with correct source and exe paths. + +For manual testing with RunTest.bat, provided the build dir is a subdirectory +of the source directory: Open command shell window. Chdir to the location +of your pcretest.exe and pcregrep.exe programs. Call RunTest.bat with +"..\RunTest.Bat" or "..\..\RunTest.bat" as appropriate. + +To run only a particular test with RunTest.Bat provide a test number argument. + +Otherwise: + +1. Copy RunTest.bat into the directory where pcretest.exe and pcregrep.exe + have been created. + +2. Edit RunTest.bat to indentify the full or relative location of + the pcre source (wherein which the testdata folder resides), e.g.: + + set srcdir=C:\pcre\pcre-8.20 + +3. In a Windows command environment, chdir to the location of your bat and + exe programs. + +4. Run RunTest.bat. Test outputs will automatically be compared to expected + results, and discrepancies will be identified in the console output. + +To independently test the just-in-time compiler, run pcre_jit_test.exe. +To test pcrecpp, run pcrecpp_unittest.exe, pcre_stringpiece_unittest.exe and +pcre_scanner_unittest.exe. + + +BUILDING UNDER WINDOWS WITH BCC5.5 + +Michael Roy sent these comments about building PCRE under Windows with BCC5.5: + + Some of the core BCC libraries have a version of PCRE from 1998 built in, + which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a + version mismatch. I'm including an easy workaround below, if you'd like to + include it in the non-unix instructions: + + When linking a project with BCC5.5, pcre.lib must be included before any of + the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command + line. + + +BUILDING UNDER WINDOWS CE WITH VISUAL STUDIO 200x + +Vincent Richomme sent a zip archive of files to help with this process. They +can be found in the file "pcre-vsbuild.zip" in the Contrib directory of the FTP +site. + + +BUILDING PCRE ON OPENVMS + +Dan Mooney sent the following comments about building PCRE on OpenVMS. They +relate to an older version of PCRE that used fewer source files, so the exact +commands will need changing. See the current list of source files above. + +"It was quite easy to compile and link the library. I don't have a formal +make file but the attached file [reproduced below] contains the OpenVMS DCL +commands I used to build the library. I had to add #define +POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. + +The library was built on: +O/S: HP OpenVMS v7.3-1 +Compiler: Compaq C v6.5-001-48BCD +Linker: vA13-01 + +The test results did not match 100% due to the issues you mention in your +documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I +modified some of the character tables temporarily and was able to get the +results to match. Tests using the fr locale did not match since I don't have +that locale loaded. The study size was always reported to be 3 less than the +value in the standard test output files." + +========================= +$! This DCL procedure builds PCRE on OpenVMS +$! +$! I followed the instructions in the non-unix-use file in the distribution. +$! +$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES +$ COMPILE DFTABLES.C +$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ +$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C +$ COMPILE MAKETABLES.C +$ COMPILE GET.C +$ COMPILE STUDY.C +$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol +$! did not seem to be defined anywhere. +$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. +$ COMPILE PCRE.C +$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ +$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol +$! did not seem to be defined anywhere. +$ COMPILE PCREPOSIX.C +$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ +$ COMPILE PCRETEST.C +$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB +$! C programs that want access to command line arguments must be +$! defined as a symbol +$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" +$! Arguments must be enclosed in quotes. +$ PCRETEST "-C" +$! Test results: +$! +$! The test results did not match 100%. The functions isprint(), iscntrl(), +$! isgraph() and ispunct() on OpenVMS must not produce the same results +$! as the system that built the test output files provided with the +$! distribution. +$! +$! The study size did not match and was always 3 less on OpenVMS. +$! +$! Locale could not be set to fr +$! +========================= + + +BUILDING PCRE ON STRATUS OPENVOS + +These notes on the port of PCRE to VOS (lightly edited) were supplied by +Ashutosh Warikoo, whose email address has the local part awarikoo and the +domain nse.co.in. The port was for version 7.9 in August 2009. + +1. Building PCRE + +I built pcre on OpenVOS Release 17.0.1at using GNU Tools 3.4a without any +problems. I used the following packages to build PCRE: + + ftp://ftp.stratus.com/pub/vos/posix/ga/posix.save.evf.gz + +Please read and follow the instructions that come with these packages. To start +the build of pcre, from the root of the package type: + + ./build.sh + +2. Installing PCRE + +Once you have successfully built PCRE, login to the SysAdmin group, switch to +the root user, and type + + [ !create_dir (master_disk)>usr --if needed ] + [ !create_dir (master_disk)>usr>local --if needed ] + !gmake install + +This installs PCRE and its man pages into /usr/local. You can add +(master_disk)>usr>local>bin to your command search paths, or if you are in +BASH, add /usr/local/bin to the PATH environment variable. + +4. Restrictions + +This port requires readline library optionally. However during the build I +faced some yet unexplored errors while linking with readline. As it was an +optional component I chose to disable it. + +5. Known Problems + +I ran the test suite, but you will have to be your own judge of whether this +command, and this port, suits your purposes. If you find any problems that +appear to be related to the port itself, please let me know. Please see the +build.log file in the root of the package also. + + +========================== +Last Updated: 18 June 2012 diff -Nru pcre3-8.12/NON-UNIX-USE pcre3-8.31/NON-UNIX-USE --- pcre3-8.12/NON-UNIX-USE 2010-06-03 19:15:23.000000000 +0000 +++ pcre3-8.31/NON-UNIX-USE 2012-06-18 18:01:00.000000000 +0000 @@ -1,501 +1,7 @@ Compiling PCRE on non-Unix systems ---------------------------------- -This document contains the following sections: +This has been renamed to better reflect its contents. Please see the file +NON-AUTOTOOLS-BUILD for details of how to build PCRE without using autotools. - General - Generic instructions for the PCRE C library - The C++ wrapper functions - Building for virtual Pascal - Stack size in Windows environments - Linking programs in Windows environments - Comments about Win32 builds - Building PCRE on Windows with CMake - Use of relative paths with CMake on Windows - Testing with RunTest.bat - Building under Windows with BCC5.5 - Building PCRE on OpenVMS - Building PCRE on Stratus OpenVOS - - -GENERAL - -I (Philip Hazel) have no experience of Windows or VMS sytems and how their -libraries work. The items in the PCRE distribution and Makefile that relate to -anything other than Unix-like systems are untested by me. - -There are some other comments and files (including some documentation in CHM -format) in the Contrib directory on the FTP site: - - ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib - -If you want to compile PCRE for a non-Unix system (especially for a system that -does not support "configure" and "make" files), note that the basic PCRE -library consists entirely of code written in Standard C, and so should compile -successfully on any system that has a Standard C compiler and library. The C++ -wrapper functions are a separate issue (see below). - -The PCRE distribution includes a "configure" file for use by the Configure/Make -build system, as found in many Unix-like environments. There is also support -support for CMake, which some users prefer, especially in Windows environments. -There are some instructions for CMake under Windows in the section entitled -"Building PCRE with CMake" below. CMake can also be used to build PCRE in -Unix-like systems. - - -GENERIC INSTRUCTIONS FOR THE PCRE C LIBRARY - -The following are generic comments about building the PCRE C library "by hand". - - (1) Copy or rename the file config.h.generic as config.h, and edit the macro - settings that it contains to whatever is appropriate for your environment. - In particular, if you want to force a specific value for newline, you can - define the NEWLINE macro. When you compile any of the PCRE modules, you - must specify -DHAVE_CONFIG_H to your compiler so that config.h is included - in the sources. - - An alternative approach is not to edit config.h, but to use -D on the - compiler command line to make any changes that you need to the - configuration options. In this case -DHAVE_CONFIG_H must not be set. - - NOTE: There have been occasions when the way in which certain parameters - in config.h are used has changed between releases. (In the configure/make - world, this is handled automatically.) When upgrading to a new release, - you are strongly advised to review config.h.generic before re-using what - you had previously. - - (2) Copy or rename the file pcre.h.generic as pcre.h. - - (3) EITHER: - Copy or rename file pcre_chartables.c.dist as pcre_chartables.c. - - OR: - Compile dftables.c as a stand-alone program (using -DHAVE_CONFIG_H if - you have set up config.h), and then run it with the single argument - "pcre_chartables.c". This generates a set of standard character tables - and writes them to that file. The tables are generated using the default - C locale for your system. If you want to use a locale that is specified - by LC_xxx environment variables, add the -L option to the dftables - command. You must use this method if you are building on a system that - uses EBCDIC code. - - The tables in pcre_chartables.c are defaults. The caller of PCRE can - specify alternative tables at run time. - - (4) Ensure that you have the following header files: - - pcre_internal.h - ucp.h - - (5) Also ensure that you have the following file, which is #included as source - when building a debugging version of PCRE, and is also used by pcretest. - - pcre_printint.src - - (6) Compile the following source files, setting -DHAVE_CONFIG_H as a compiler - option if you have set up config.h with your configuration, or else use - other -D settings to change the configuration as required. - - pcre_chartables.c - pcre_compile.c - pcre_config.c - pcre_dfa_exec.c - pcre_exec.c - pcre_fullinfo.c - pcre_get.c - pcre_globals.c - pcre_info.c - pcre_maketables.c - pcre_newline.c - pcre_ord2utf8.c - pcre_refcount.c - pcre_study.c - pcre_tables.c - pcre_try_flipped.c - pcre_ucd.c - pcre_valid_utf8.c - pcre_version.c - pcre_xclass.c - - Make sure that you include -I. in the compiler command (or equivalent for - an unusual compiler) so that all included PCRE header files are first - sought in the current directory. Otherwise you run the risk of picking up - a previously-installed file from somewhere else. - - (7) Now link all the compiled code into an object library in whichever form - your system keeps such libraries. This is the basic PCRE C library. If - your system has static and shared libraries, you may have to do this once - for each type. - - (8) Similarly, if you want to build the POSIX wrapper functions, ensure that - you have the pcreposix.h file and then compile pcreposix.c (remembering - -DHAVE_CONFIG_H if necessary). Link the result (on its own) as the - pcreposix library. - - (9) Compile the test program pcretest.c (again, don't forget -DHAVE_CONFIG_H). - This needs the functions in the PCRE library when linking. It also needs - the pcreposix wrapper functions unless you compile it with -DNOPOSIX. The - pcretest.c program also needs the pcre_printint.src source file, which it - #includes. - -(10) Run pcretest on the testinput files in the testdata directory, and check - that the output matches the corresponding testoutput files. Note that the - supplied files are in Unix format, with just LF characters as line - terminators. You may need to edit them to change this if your system uses - a different convention. If you are using Windows, you probably should use - the wintestinput3 file instead of testinput3 (and the corresponding output - file). This is a locale test; wintestinput3 sets the locale to "french" - rather than "fr_FR", and there some minor output differences. - -(11) If you want to use the pcregrep command, compile and link pcregrep.c; it - uses only the basic PCRE library (it does not need the pcreposix library). - - -THE C++ WRAPPER FUNCTIONS - -The PCRE distribution also contains some C++ wrapper functions and tests, -contributed by Google Inc. On a system that can use "configure" and "make", -the functions are automatically built into a library called pcrecpp. It should -be straightforward to compile the .cc files manually on other systems. The -files called xxx_unittest.cc are test programs for each of the corresponding -xxx.cc files. - - -BUILDING FOR VIRTUAL PASCAL - -A script for building PCRE using Borland's C++ compiler for use with VPASCAL -was contributed by Alexander Tokarev. Stefan Weber updated the script and added -additional files. The following files in the distribution are for building PCRE -for use with VP/Borland: makevp_c.txt, makevp_l.txt, makevp.bat, pcregexp.pas. - - -STACK SIZE IN WINDOWS ENVIRONMENTS - -The default processor stack size of 1Mb in some Windows environments is too -small for matching patterns that need much recursion. In particular, test 2 may -fail because of this. Normally, running out of stack causes a crash, but there -have been cases where the test program has just died silently. See your linker -documentation for how to increase stack size if you experience problems. The -Linux default of 8Mb is a reasonable choice for the stack, though even that can -be too small for some pattern/subject combinations. - -PCRE has a compile configuration option to disable the use of stack for -recursion so that heap is used instead. However, pattern matching is -significantly slower when this is done. There is more about stack usage in the -"pcrestack" documentation. - - -LINKING PROGRAMS IN WINDOWS ENVIRONMENTS - -If you want to statically link a program against a PCRE library in the form of -a non-dll .a file, you must define PCRE_STATIC before including pcre.h or -pcrecpp.h, otherwise the pcre_malloc() and pcre_free() exported functions will -be declared __declspec(dllimport), with unwanted results. - - -CALLING CONVENTIONS IN WINDOWS ENVIRONMENTS - -It is possible to compile programs to use different calling conventions using -MSVC. Search the web for "calling conventions" for more information. To make it -easier to change the calling convention for the exported functions in the -PCRE library, the macro PCRE_CALL_CONVENTION is present in all the external -definitions. It can be set externally when compiling (e.g. in CFLAGS). If it is -not set, it defaults to empty; the default calling convention is then used -(which is what is wanted most of the time). - - -COMMENTS ABOUT WIN32 BUILDS (see also "BUILDING PCRE WITH CMAKE" below) - -There are two ways of building PCRE using the "configure, make, make install" -paradigm on Windows systems: using MinGW or using Cygwin. These are not at all -the same thing; they are completely different from each other. There is also -support for building using CMake, which some users find a more straightforward -way of building PCRE under Windows. However, the tests are not run -automatically when CMake is used. - -The MinGW home page (http://www.mingw.org/) says this: - - MinGW: A collection of freely available and freely distributable Windows - specific header files and import libraries combined with GNU toolsets that - allow one to produce native Windows programs that do not rely on any - 3rd-party C runtime DLLs. - -The Cygwin home page (http://www.cygwin.com/) says this: - - Cygwin is a Linux-like environment for Windows. It consists of two parts: - - . A DLL (cygwin1.dll) which acts as a Linux API emulation layer providing - substantial Linux API functionality - - . A collection of tools which provide Linux look and feel. - - The Cygwin DLL currently works with all recent, commercially released x86 32 - bit and 64 bit versions of Windows, with the exception of Windows CE. - -On both MinGW and Cygwin, PCRE should build correctly using: - - ./configure && make && make install - -This should create two libraries called libpcre and libpcreposix, and, if you -have enabled building the C++ wrapper, a third one called libpcrecpp. These are -independent libraries: when you like with libpcreposix or libpcrecpp you must -also link with libpcre, which contains the basic functions. (Some earlier -releases of PCRE included the basic libpcre functions in libpcreposix. This no -longer happens.) - -A user submitted a special-purpose patch that makes it easy to create -"pcre.dll" under mingw32 using the "msys" environment. It provides "pcre.dll" -as a special target. If you use this target, no other files are built, and in -particular, the pcretest and pcregrep programs are not built. An example of how -this might be used is: - - ./configure --enable-utf --disable-cpp CFLAGS="-03 -s"; make pcre.dll - -Using Cygwin's compiler generates libraries and executables that depend on -cygwin1.dll. If a library that is generated this way is distributed, -cygwin1.dll has to be distributed as well. Since cygwin1.dll is under the GPL -licence, this forces not only PCRE to be under the GPL, but also the entire -application. A distributor who wants to keep their own code proprietary must -purchase an appropriate Cygwin licence. - -MinGW has no such restrictions. The MinGW compiler generates a library or -executable that can run standalone on Windows without any third party dll or -licensing issues. - -But there is more complication: - -If a Cygwin user uses the -mno-cygwin Cygwin gcc flag, what that really does is -to tell Cygwin's gcc to use the MinGW gcc. Cygwin's gcc is only acting as a -front end to MinGW's gcc (if you install Cygwin's gcc, you get both Cygwin's -gcc and MinGW's gcc). So, a user can: - -. Build native binaries by using MinGW or by getting Cygwin and using - -mno-cygwin. - -. Build binaries that depend on cygwin1.dll by using Cygwin with the normal - compiler flags. - -The test files that are supplied with PCRE are in Unix format, with LF -characters as line terminators. It may be necessary to change the line -terminators in order to get some of the tests to work. - - -BUILDING PCRE ON WINDOWS WITH CMAKE - -CMake is an alternative configuration facility that can be used instead of the -traditional Unix "configure". CMake creates project files (make files, solution -files, etc.) tailored to numerous development environments, including Visual -Studio, Borland, Msys, MinGW, NMake, and Unix. The following instructions -were contributed by a PCRE user. - -1. Install the latest CMake version available from http://www.cmake.org/, and - ensure that cmake\bin is on your path. - -2. Unzip (retaining folder structure) the PCRE source tree into a source - directory such as C:\pcre. - -3. Create a new, empty build directory, for example C:\pcre\build\ - -4. Run cmake-gui from the Shell envirornment of your build tool, for example, - Msys for Msys/MinGW or Visual Studio Command Prompt for VC/VC++. - -5. Enter C:\pcre\pcre-xx and C:\pcre\build for the source and build - directories, respectively. - -6. Hit the "Configure" button. - -7. Select the particular IDE / build tool that you are using (Visual - Studio, MSYS makefiles, MinGW makefiles, etc.) - -8. The GUI will then list several configuration options. This is where - you can enable UTF-8 support or other PCRE optional features. - -9. Hit "Configure" again. The adjacent "Generate" button should now be - active. - -10. Hit "Generate". - -11. The build directory should now contain a usable build system, be it a - solution file for Visual Studio, makefiles for MinGW, etc. Exit from - cmake-gui and use the generated build system with your compiler or IDE. - - -USE OF RELATIVE PATHS WITH CMAKE ON WINDOWS - -A PCRE user comments as follows: - -I thought that others may want to know the current state of -CMAKE_USE_RELATIVE_PATHS support on Windows. - -Here it is: --- AdditionalIncludeDirectories is only partially modified (only the -first path - see below) --- Only some of the contained file paths are modified - shown below for -pcre.vcproj --- It properly modifies - -I am sure CMake people can fix that if they want to. Until then one will -need to replace existing absolute paths in project files with relative -paths manually (e.g. from VS) - relative to project file location. I did -just that before being told to try CMAKE_USE_RELATIVE_PATHS. Not a big -deal. - -AdditionalIncludeDirectories="E:\builds\pcre\build;E:\builds\pcre\pcre-7.5;" -AdditionalIncludeDirectories=".;E:\builds\pcre\pcre-7.5;" - -RelativePath="pcre.h"> -RelativePath="pcre_chartables.c"> -RelativePath="pcre_chartables.c.rule"> - - -TESTING WITH RUNTEST.BAT - -1. Copy RunTest.bat into the directory where pcretest.exe has been created. - -2. Edit RunTest.bat and insert a line that indentifies the relative location of - the pcre source, e.g.: - - set srcdir=..\pcre-7.4-RC3 - -3. Run RunTest.bat from a command shell environment. Test outputs will - automatically be compared to expected results, and discrepancies will - identified in the console output. - -4. To test pcrecpp, run pcrecpp_unittest.exe, pcre_stringpiece_unittest.exe and - pcre_scanner_unittest.exe. - - -BUILDING UNDER WINDOWS WITH BCC5.5 - -Michael Roy sent these comments about building PCRE under Windows with BCC5.5: - - Some of the core BCC libraries have a version of PCRE from 1998 built in, - which can lead to pcre_exec() giving an erroneous PCRE_ERROR_NULL from a - version mismatch. I'm including an easy workaround below, if you'd like to - include it in the non-unix instructions: - - When linking a project with BCC5.5, pcre.lib must be included before any of - the libraries cw32.lib, cw32i.lib, cw32mt.lib, and cw32mti.lib on the command - line. - - -BUILDING UNDER WINDOWS CE WITH VISUAL STUDIO 200x - -Vincent Richomme sent a zip archive of files to help with this process. They -can be found in the file "pcre-vsbuild.zip" in the Contrib directory of the FTP -site. - - -BUILDING PCRE ON OPENVMS - -Dan Mooney sent the following comments about building PCRE on OpenVMS. They -relate to an older version of PCRE that used fewer source files, so the exact -commands will need changing. See the current list of source files above. - -"It was quite easy to compile and link the library. I don't have a formal -make file but the attached file [reproduced below] contains the OpenVMS DCL -commands I used to build the library. I had to add #define -POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. - -The library was built on: -O/S: HP OpenVMS v7.3-1 -Compiler: Compaq C v6.5-001-48BCD -Linker: vA13-01 - -The test results did not match 100% due to the issues you mention in your -documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I -modified some of the character tables temporarily and was able to get the -results to match. Tests using the fr locale did not match since I don't have -that locale loaded. The study size was always reported to be 3 less than the -value in the standard test output files." - -========================= -$! This DCL procedure builds PCRE on OpenVMS -$! -$! I followed the instructions in the non-unix-use file in the distribution. -$! -$ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES -$ COMPILE DFTABLES.C -$ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ -$ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C -$ COMPILE MAKETABLES.C -$ COMPILE GET.C -$ COMPILE STUDY.C -$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol -$! did not seem to be defined anywhere. -$! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. -$ COMPILE PCRE.C -$ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ -$! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol -$! did not seem to be defined anywhere. -$ COMPILE PCREPOSIX.C -$ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ -$ COMPILE PCRETEST.C -$ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB -$! C programs that want access to command line arguments must be -$! defined as a symbol -$ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" -$! Arguments must be enclosed in quotes. -$ PCRETEST "-C" -$! Test results: -$! -$! The test results did not match 100%. The functions isprint(), iscntrl(), -$! isgraph() and ispunct() on OpenVMS must not produce the same results -$! as the system that built the test output files provided with the -$! distribution. -$! -$! The study size did not match and was always 3 less on OpenVMS. -$! -$! Locale could not be set to fr -$! -========================= - - -BUILDING PCRE ON STRATUS OPENVOS - -These notes on the port of PCRE to VOS (lightly edited) were supplied by -Ashutosh Warikoo, whose email address has the local part awarikoo and the -domain nse.co.in. The port was for version 7.9 in August 2009. - -1. Building PCRE - -I built pcre on OpenVOS Release 17.0.1at using GNU Tools 3.4a without any -problems. I used the following packages to build PCRE: - - ftp://ftp.stratus.com/pub/vos/posix/ga/posix.save.evf.gz - -Please read and follow the instructions that come with these packages. To start -the build of pcre, from the root of the package type: - - ./build.sh - -2. Installing PCRE - -Once you have successfully built PCRE, login to the SysAdmin group, switch to -the root user, and type - - [ !create_dir (master_disk)>usr --if needed ] - [ !create_dir (master_disk)>usr>local --if needed ] - !gmake install - -This installs PCRE and its man pages into /usr/local. You can add -(master_disk)>usr>local>bin to your command search paths, or if you are in -BASH, add /usr/local/bin to the PATH environment variable. - -4. Restrictions - -This port requires readline library optionally. However during the build I -faced some yet unexplored errors while linking with readline. As it was an -optional component I chose to disable it. - -5. Known Problems - -I ran a the test suite, but you will have to be your own judge of whether this -command, and this port, suits your purposes. If you find any problems that -appear to be related to the port itself, please let me know. Please see the -build.log file in the root of the package also. - - -========================= -Last Updated: 26 May 2010 -**** +#### diff -Nru pcre3-8.12/PrepareRelease pcre3-8.31/PrepareRelease --- pcre3-8.12/PrepareRelease 2011-01-11 16:32:42.000000000 +0000 +++ pcre3-8.31/PrepareRelease 2012-06-18 17:19:19.000000000 +0000 @@ -37,7 +37,7 @@ # Check the remaining man pages -../CheckMan *.1 *.3 +perl ../CheckMan *.1 *.3 if [ $? != 0 ] ; then exit 1; fi # Make Text form of the documentation. It needs some mangling to make it @@ -49,7 +49,7 @@ This file contains a concatenation of the PCRE man pages, converted to plain text format for ease of searching with a text editor, or for use on systems that do not have a man page processor. The small individual files that give -synopses of each function in the library have not been included. Neither has +synopses of each function in the library have not been included. Neither has the pcredemo program. There are separate text files for the pcregrep and pcretest commands. ----------------------------------------------------------------------------- @@ -58,12 +58,13 @@ End echo "Making pcre.txt" -for file in pcre pcrebuild pcrematching pcreapi pcrecallout pcrecompat \ - pcrepattern pcresyntax pcrepartial pcreprecompile \ - pcreperform pcreposix pcrecpp pcresample pcrestack ; do +for file in pcre pcre16 pcrebuild pcrematching pcreapi pcrecallout pcrecompat \ + pcrepattern pcresyntax pcreunicode pcrejit pcrepartial \ + pcreprecompile pcreperform pcreposix pcrecpp pcresample \ + pcrelimits pcrestack ; do echo " Processing $file.3" nroff -c -man $file.3 >$file.rawtxt - ../CleanTxt <$file.rawtxt >>pcre.txt + perl ../CleanTxt <$file.rawtxt >>pcre.txt /bin/rm $file.rawtxt echo "------------------------------------------------------------------------------" >>pcre.txt if [ "$file" != "pcresample" ] ; then @@ -76,7 +77,7 @@ for file in pcretest pcregrep pcre-config ; do echo Making $file.txt nroff -c -man $file.1 >$file.rawtxt - ../CleanTxt <$file.rawtxt >$file.txt + perl ../CleanTxt <$file.rawtxt >$file.txt /bin/rm $file.rawtxt done @@ -103,7 +104,7 @@ ". hy \\\\n(HY\n" . "..\n" . ".\n" . - ".EX\n" ; + ".EX\n" ; while () { s/\\/\\e/g; @@ -111,7 +112,7 @@ } print OUT ".EE\n"; close(IN); - close(OUT); + close(OUT); END if [ $? != 0 ] ; then exit 1; fi @@ -125,7 +126,7 @@ for file in *.1 ; do base=`basename $file .1` echo " Making $base.html" - ../132html -toc $base <$file >html/$base.html + perl ../132html -toc $base <$file >html/$base.html done # Exclude table of contents for function summaries. It seems that expr @@ -136,14 +137,16 @@ base=`basename $file .3` toc=-toc if [ `expr $base : '.*_'` -ne 0 ] ; then toc="" ; fi - if [ "$base" = "pcresample" ] || \ - [ "$base" = "pcrestack" ] || \ - [ "$base" = "pcrecompat" ] || \ - [ "$base" = "pcreperform" ] ; then + if [ "$base" = "pcresample" ] || \ + [ "$base" = "pcrestack" ] || \ + [ "$base" = "pcrecompat" ] || \ + [ "$base" = "pcrelimits" ] || \ + [ "$base" = "pcreperform" ] || \ + [ "$base" = "pcreunicode" ] ; then toc="" fi echo " Making $base.html" - ../132html $toc $base <$file >html/$base.html + perl ../132html $toc $base <$file >html/$base.html if [ $? != 0 ] ; then exit 1; fi done @@ -154,8 +157,11 @@ if [ "$1" = "doc" ] ; then exit; fi # These files are detrailed; do not detrail the test data because there may be -# significant trailing spaces. The configure files are also omitted from the -# detrailing. +# significant trailing spaces. Do not detrail RunTest.bat, because it has CRLF +# line endings and the detrail script removes all trailing white space. The +# configure files are also omitted from the detrailing. We don't bother with +# those pcre16_xx files that just define COMPILE_PCRE16 and then #include the +# common file, because they aren't going to change. files="\ Makefile.am \ @@ -167,6 +173,7 @@ AUTHORS \ NEWS \ NON-UNIX-USE \ + NON-AUTOTOOLS-BUILD \ INSTALL \ 132html \ CleanTxt \ @@ -175,13 +182,12 @@ CMakeLists.txt \ RunGrepTest \ RunTest \ - RunTest.bat \ pcre-config.in \ libpcre.pc.in \ + libpcre16.pc.in \ libpcreposix.pc.in \ libpcrecpp.pc.in \ config.h.in \ - pcre_printint.src \ pcre_chartables.c.dist \ pcredemo.c \ pcregrep.c \ @@ -191,6 +197,7 @@ pcreposix.h \ pcre.h.in \ pcre_internal.h + pcre_byte_order.c \ pcre_compile.c \ pcre_config.c \ pcre_dfa_exec.c \ @@ -198,18 +205,23 @@ pcre_fullinfo.c \ pcre_get.c \ pcre_globals.c \ - pcre_info.c \ + pcre_jit_compile.c \ + pcre_jit_test.c \ pcre_maketables.c \ pcre_newline.c \ pcre_ord2utf8.c \ + pcre16_ord2utf16.c \ + pcre_printint.c \ pcre_refcount.c \ + pcre_string_utils.c \ pcre_study.c \ pcre_tables.c \ - pcre_try_flipped.c \ pcre_ucp_searchfuncs.c \ pcre_valid_utf8.c \ pcre_version.c \ pcre_xclass.c \ + pcre16_utf16_utils.c \ + pcre16_valid_utf16.c \ pcre_scanner.cc \ pcre_scanner.h \ pcre_scanner_unittest.cc \ @@ -230,7 +242,7 @@ libpcreposix.def" echo Detrailing -./Detrail $files doc/p* doc/html/* +perl ./Detrail $files doc/p* doc/html/* echo Doing basic configure to get default pcre.h and config.h # This is in case the caller has set aliases (as I do - PH) diff -Nru pcre3-8.12/README pcre3-8.31/README --- pcre3-8.12/README 2010-01-19 16:39:47.000000000 +0000 +++ pcre3-8.31/README 2012-06-20 15:08:49.000000000 +0000 @@ -18,11 +18,12 @@ The PCRE APIs Documentation for PCRE Contributions by users of PCRE - Building PCRE on non-Unix systems - Building PCRE on Unix-like systems - Retrieving configuration information on Unix-like systems - Shared libraries on Unix-like systems - Cross-compiling on Unix-like systems + Building PCRE on non-Unix-like systems + Building PCRE without using autotools + Building PCRE using autotools + Retrieving configuration information + Shared libraries + Cross-compiling using autotools Using HP's ANSI C++ compiler (aCC) Using PCRE from MySQL Making new tarballs @@ -34,16 +35,19 @@ The PCRE APIs ------------- -PCRE is written in C, and it has its own API. The distribution also includes a -set of C++ wrapper functions (see the pcrecpp man page for details), courtesy -of Google Inc. - -In addition, there is a set of C wrapper functions that are based on the POSIX -regular expression API (see the pcreposix man page). These end up in the -library called libpcreposix. Note that this just provides a POSIX calling -interface to PCRE; the regular expressions themselves still follow Perl syntax -and semantics. The POSIX API is restricted, and does not give full access to -all of PCRE's facilities. +PCRE is written in C, and it has its own API. There are two sets of functions, +one for the 8-bit library, which processes strings of bytes, and one for the +16-bit library, which processes strings of 16-bit values. The distribution also +includes a set of C++ wrapper functions (see the pcrecpp man page for details), +courtesy of Google Inc., which can be used to call the 8-bit PCRE library from +C++. + +In addition, there is a set of C wrapper functions (again, just for the 8-bit +library) that are based on the POSIX regular expression API (see the pcreposix +man page). These end up in the library called libpcreposix. Note that this just +provides a POSIX calling interface to PCRE; the regular expressions themselves +still follow Perl syntax and semantics. The POSIX API is restricted, and does +not give full access to all of PCRE's facilities. The header file for the POSIX-style functions is called pcreposix.h. The official POSIX name is regex.h, but I did not want to risk possible problems @@ -106,36 +110,45 @@ in the standard distribution, so these contibutions have been archived. -Building PCRE on non-Unix systems ---------------------------------- +Building PCRE on non-Unix-like systems +-------------------------------------- -For a non-Unix system, please read the comments in the file NON-UNIX-USE, -though if your system supports the use of "configure" and "make" you may be -able to build PCRE in the same way as for Unix-like systems. PCRE can also be -configured in many platform environments using the GUI facility provided by -CMake's cmake-gui command. This creates Makefiles, solution files, etc. +For a non-Unix-like system, please read the comments in the file +NON-AUTOTOOLS-BUILD, though if your system supports the use of "configure" and +"make" you may be able to build PCRE using autotools in the same way as for +many Unix-like systems. + +PCRE can also be configured using the GUI facility provided by CMake's +cmake-gui command. This creates Makefiles, solution files, etc. The file +NON-AUTOTOOLS-BUILD has information about CMake. PCRE has been compiled on many different operating systems. It should be straightforward to build PCRE on any system that has a Standard C compiler and library, because it uses only Standard C functions. -Building PCRE on Unix-like systems ----------------------------------- +Building PCRE without using autotools +------------------------------------- + +The use of autotools (in particular, libtool) is problematic in some +environments, even some that are Unix or Unix-like. See the NON-AUTOTOOLS-BUILD +file for ways of building PCRE without using autotools. + + +Building PCRE using autotools +----------------------------- If you are using HP's ANSI C++ compiler (aCC), please see the special note in the section entitled "Using HP's ANSI C++ compiler (aCC)" below. -The following instructions assume the use of the widely used "configure, make, -make install" process. There is also support for CMake in the PCRE -distribution; there are some comments about using CMake in the NON-UNIX-USE -file, though it can also be used in Unix-like systems. - -To build PCRE on a Unix-like system, first run the "configure" command from the -PCRE distribution directory, with your current directory set to the directory -where you want the files to be created. This command is a standard GNU -"autoconf" configuration script, for which generic instructions are supplied in -the file INSTALL. +The following instructions assume the use of the widely used "configure; make; +make install" (autotools) process. + +To build PCRE on system that supports autotools, first run the "configure" +command from the PCRE distribution directory, with your current directory set +to the directory where you want the files to be created. This command is a +standard GNU "autoconf" configuration script, for which generic instructions +are supplied in the file INSTALL. Most commonly, people build PCRE within its own distribution directory, and in this case, on many systems, just running "./configure" is sufficient. However, @@ -143,9 +156,9 @@ CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local -specifies that the C compiler should be run with the flags '-O2 -Wall' instead -of the default, and that "make install" should install PCRE under /opt/local -instead of the default /usr/local. +This command specifies that the C compiler should be run with the flags '-O2 +-Wall' instead of the default, and that "make install" should install PCRE +under /opt/local instead of the default /usr/local. If you want to build in a different directory, just run "configure" with that directory as current. For example, suppose you have unpacked the PCRE source @@ -159,27 +172,59 @@ does not have any features to support this. There are some optional features that can be included or omitted from the PCRE -library. You can read more about them in the pcrebuild man page. +library. They are also documented in the pcrebuild man page. + +. By default, both shared and static libraries are built. You can change this + by adding one of these options to the "configure" command: + + --disable-shared + --disable-static -. If you want to suppress the building of the C++ wrapper library, you can add - --disable-cpp to the "configure" command. Otherwise, when "configure" is run, - it will try to find a C++ compiler and C++ header files, and if it succeeds, - it will try to build the C++ wrapper. + (See also "Shared libraries on Unix-like systems" below.) + +. By default, only the 8-bit library is built. If you add --enable-pcre16 to + the "configure" command, the 16-bit library is also built. If you want only + the 16-bit library, use "./configure --enable-pcre16 --disable-pcre8". + +. If you are building the 8-bit library and want to suppress the building of + the C++ wrapper library, you can add --disable-cpp to the "configure" + command. Otherwise, when "configure" is run without --disable-pcre8, it will + try to find a C++ compiler and C++ header files, and if it succeeds, it will + try to build the C++ wrapper. + +. If you want to include support for just-in-time compiling, which can give + large performance improvements on certain platforms, add --enable-jit to the + "configure" command. This support is available only for certain hardware + architectures. If you try to enable it on an unsupported architecture, there + will be a compile time error. + +. When JIT support is enabled, pcregrep automatically makes use of it, unless + you add --disable-pcregrep-jit to the "configure" command. . If you want to make use of the support for UTF-8 Unicode character strings in - PCRE, you must add --enable-utf8 to the "configure" command. Without it, the - code for handling UTF-8 is not included in the library. Even when included, - it still has to be enabled by an option at run time. When PCRE is compiled - with this option, its input can only either be ASCII or UTF-8, even when - running on EBCDIC platforms. It is not possible to use both --enable-utf8 and - --enable-ebcdic at the same time. - -. If, in addition to support for UTF-8 character strings, you want to include - support for the \P, \p, and \X sequences that recognize Unicode character - properties, you must add --enable-unicode-properties to the "configure" - command. This adds about 30K to the size of the library (in the form of a - property table); only the basic two-letter properties such as Lu are - supported. + the 8-bit library, or UTF-16 Unicode character strings in the 16-bit library, + you must add --enable-utf to the "configure" command. Without it, the code + for handling UTF-8 and UTF-16 is not included in the relevant library. Even + when --enable-utf is included, the use of a UTF encoding still has to be + enabled by an option at run time. When PCRE is compiled with this option, its + input can only either be ASCII or UTF-8/16, even when running on EBCDIC + platforms. It is not possible to use both --enable-utf and --enable-ebcdic at + the same time. + +. There are no separate options for enabling UTF-8 and UTF-16 independently + because that would allow ridiculous settings such as requesting UTF-16 + support while building only the 8-bit library. However, the option + --enable-utf8 is retained for backwards compatibility with earlier releases + that did not support 16-bit character strings. It is synonymous with + --enable-utf. It is not possible to configure one library with UTF support + and the other without in the same configuration. + +. If, in addition to support for UTF-8/16 character strings, you want to + include support for the \P, \p, and \X sequences that recognize Unicode + character properties, you must add --enable-unicode-properties to the + "configure" command. This adds about 30K to the size of the library (in the + form of a property table); only the basic two-letter properties such as Lu + are supported. . You can build PCRE to recognize either CR or LF or the sequence CRLF or any of the preceding, or any of the Unicode newline sequences as indicating the @@ -232,10 +277,11 @@ sizes in the pcrestack man page. . The default maximum compiled pattern size is around 64K. You can increase - this by adding --with-link-size=3 to the "configure" command. You can - increase it even more by setting --with-link-size=4, but this is unlikely - ever to be necessary. Increasing the internal link size will reduce - performance. + this by adding --with-link-size=3 to the "configure" command. In the 8-bit + library, PCRE then uses three bytes instead of two for offsets to different + parts of the compiled pattern. In the 16-bit library, --with-link-size=3 is + the same as --with-link-size=4, which (in both libraries) uses four-byte + offsets. Increasing the internal link size reduces performance. . You can build PCRE so that its internal match() function that is called from pcre_exec() does not call itself recursively. Instead, it uses memory blocks @@ -247,9 +293,10 @@ on the "configure" command. PCRE runs more slowly in this mode, but it may be necessary in environments with limited stack sizes. This applies only to the - pcre_exec() function; it does not apply to pcre_dfa_exec(), which does not - use deeply nested recursion. There is a discussion about stack sizes in the - pcrestack man page. + normal execution of the pcre_exec() function; if JIT support is being + successfully used, it is not relevant. Equally, it does not apply to + pcre_dfa_exec(), which does not use deeply nested recursion. There is a + discussion about stack sizes in the pcrestack man page. . For speed, PCRE uses four tables for manipulating and identifying characters whose code point values are less than 256. By default, it uses a set of @@ -269,27 +316,37 @@ This automatically implies --enable-rebuild-chartables (see above). However, when PCRE is built this way, it always operates in EBCDIC. It cannot support - both EBCDIC and UTF-8. + both EBCDIC and UTF-8/16. -. It is possible to compile pcregrep to use libz and/or libbz2, in order to - read .gz and .bz2 files (respectively), by specifying one or both of +. The pcregrep program currently supports only 8-bit data files, and so + requires the 8-bit PCRE library. It is possible to compile pcregrep to use + libz and/or libbz2, in order to read .gz and .bz2 files (respectively), by + specifying one or both of --enable-pcregrep-libz --enable-pcregrep-libbz2 Of course, the relevant libraries must be installed on your system. +. The default size of internal buffer used by pcregrep can be set by, for + example: + + --with-pcregrep-bufsize=50K + + The default value is 20K. + . It is possible to compile pcretest so that it links with the libreadline - library, by specifying + or libedit libraries, by specifying, respectively, - --enable-pcretest-libreadline + --enable-pcretest-libreadline or --enable-pcretest-libedit If this is done, when pcretest's input is from a terminal, it reads it using the readline() function. This provides line-editing and history facilities. Note that libreadline is GPL-licenced, so if you distribute a binary of - pcretest linked in this way, there may be licensing issues. + pcretest linked in this way, there may be licensing issues. These can be + avoided by linking with libedit (which has a BSD licence) instead. - Setting this option causes the -lreadline option to be added to the pcretest + Enabling libreadline causes the -lreadline option to be added to the pcretest build. In many operating environments with a sytem-installed readline library this is sufficient. However, in some environments (e.g. if an unmodified distribution version of readline is in use), it may be necessary @@ -302,37 +359,42 @@ The "configure" script builds the following files for the basic C library: -. Makefile is the makefile that builds the library -. config.h contains build-time configuration options for the library -. pcre.h is the public PCRE header file -. pcre-config is a script that shows the settings of "configure" options -. libpcre.pc is data for the pkg-config command -. libtool is a script that builds shared and/or static libraries -. RunTest is a script for running tests on the basic C library -. RunGrepTest is a script for running tests on the pcregrep command +. Makefile the makefile that builds the library +. config.h build-time configuration options for the library +. pcre.h the public PCRE header file +. pcre-config script that shows the building settings such as CFLAGS + that were set for "configure" +. libpcre.pc ) data for the pkg-config command +. libpcre16.pc ) +. libpcreposix.pc ) +. libtool script that builds shared and/or static libraries Versions of config.h and pcre.h are distributed in the PCRE tarballs under the names config.h.generic and pcre.h.generic. These are provided for those who have to built PCRE without using "configure" or CMake. If you use "configure" or CMake, the .generic versions are not used. -If a C++ compiler is found, the following files are also built: +When building the 8-bit library, if a C++ compiler is found, the following +files are also built: -. libpcrecpp.pc is data for the pkg-config command -. pcrecpparg.h is a header file for programs that call PCRE via the C++ wrapper -. pcre_stringpiece.h is the header for the C++ "stringpiece" functions +. libpcrecpp.pc data for the pkg-config command +. pcrecpparg.h header file for calling PCRE via the C++ wrapper +. pcre_stringpiece.h header for the C++ "stringpiece" functions The "configure" script also creates config.status, which is an executable script that can be run to recreate the configuration, and config.log, which contains compiler output from tests that "configure" runs. -Once "configure" has run, you can run "make". It builds two libraries, called -libpcre and libpcreposix, a test program called pcretest, and the pcregrep -command. If a C++ compiler was found on your system, "make" also builds the C++ -wrapper library, which is called libpcrecpp, and some test programs called -pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest. -Building the C++ wrapper can be disabled by adding --disable-cpp to the -"configure" command. +Once "configure" has run, you can run "make". This builds either or both of the +libraries libpcre and libpcre16, and a test program called pcretest. If you +enabled JIT support with --enable-jit, a test program called pcre_jit_test is +built as well. + +If the 8-bit library is built, libpcreposix and the pcregrep command are also +built, and if a C++ compiler was found on your system, and you did not disable +it with --disable-cpp, "make" builds the C++ wrapper library, which is called +libpcrecpp, as well as some test programs called pcrecpp_unittest, +pcre_scanner_unittest, and pcre_stringpiece_unittest. The command "make check" runs all the appropriate tests. Details of the PCRE tests are given below in a separate section of this document. @@ -343,16 +405,19 @@ Commands (bin): pcretest - pcregrep + pcregrep (if 8-bit support is enabled) pcre-config Libraries (lib): - libpcre - libpcreposix - libpcrecpp (if C++ support is enabled) + libpcre16 (if 16-bit support is enabled) + libpcre (if 8-bit support is enabled) + libpcreposix (if 8-bit support is enabled) + libpcrecpp (if 8-bit and C++ support is enabled) Configuration information (lib/pkgconfig): + libpcre16.pc libpcre.pc + libpcreposix.pc libpcrecpp.pc (if C++ support is enabled) Header files (include): @@ -366,6 +431,7 @@ Man pages (share/man/man{1,3}): pcregrep.1 pcretest.1 + pcre-config.1 pcre.3 pcre*.3 (lots more pages, all starting "pcre") @@ -380,17 +446,18 @@ LICENCE NEWS README - pcre.txt (a concatenation of the man(3) pages) - pcretest.txt the pcretest man page - pcregrep.txt the pcregrep man page + pcre.txt (a concatenation of the man(3) pages) + pcretest.txt the pcretest man page + pcregrep.txt the pcregrep man page + pcre-config.txt the pcre-config man page If you want to remove PCRE from your system, you can run "make uninstall". This removes all the files that "make install" installed. However, it does not remove any directories, because these are often shared with other programs. -Retrieving configuration information on Unix-like systems ---------------------------------------------------------- +Retrieving configuration information +------------------------------------ Running "make install" installs the command pcre-config, which can be used to recall information about the PCRE configuration and installation. For example: @@ -415,8 +482,8 @@ /lib/pkgconfig. -Shared libraries on Unix-like systems -------------------------------------- +Shared libraries +---------------- The default distribution builds PCRE as shared libraries and static libraries, as long as the operating system supports shared libraries. Shared library @@ -441,8 +508,8 @@ build only shared libraries. -Cross-compiling on Unix-like systems ------------------------------------- +Cross-compiling using autotools +------------------------------- You can specify CC and CFLAGS in the normal way to the "configure" command, in order to cross-compile PCRE for some other host. However, you should NOT @@ -514,30 +581,49 @@ Testing PCRE ------------ -To test the basic PCRE library on a Unix system, run the RunTest script that is -created by the configuring process. There is also a script called RunGrepTest -that tests the options of the pcregrep command. If the C++ wrapper library is -built, three test programs called pcrecpp_unittest, pcre_scanner_unittest, and -pcre_stringpiece_unittest are also built. +To test the basic PCRE library on a Unix-like system, run the RunTest script. +There is another script called RunGrepTest that tests the options of the +pcregrep command. If the C++ wrapper library is built, three test programs +called pcrecpp_unittest, pcre_scanner_unittest, and pcre_stringpiece_unittest +are also built. When JIT support is enabled, another test program called +pcre_jit_test is built. Both the scripts and all the program tests are run if you obey "make check" or -"make test". For other systems, see the instructions in NON-UNIX-USE. +"make test". For other environments, see the instructions in +NON-AUTOTOOLS-BUILD. The RunTest script runs the pcretest test program (which is documented in its -own man page) on each of the testinput files in the testdata directory in -turn, and compares the output with the contents of the corresponding testoutput -files. A file called testtry is used to hold the main output from pcretest -(testsavedregex is also used as a working file). To run pcretest on just one of -the test files, give its number as an argument to RunTest, for example: - - RunTest 2 - -The first test file can also be fed directly into the perltest.pl script to -check that Perl gives the same results. The only difference you should see is -in the first few lines, where the Perl version is given instead of the PCRE -version. +own man page) on each of the relevant testinput files in the testdata +directory, and compares the output with the contents of the corresponding +testoutput files. Some tests are relevant only when certain build-time options +were selected. For example, the tests for UTF-8/16 support are run only if +--enable-utf was used. RunTest outputs a comment when it skips a test. + +Many of the tests that are not skipped are run up to three times. The second +run forces pcre_study() to be called for all patterns except for a few in some +tests that are marked "never study" (see the pcretest program for how this is +done). If JIT support is available, the non-DFA tests are run a third time, +this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option. + +When both 8-bit and 16-bit support is enabled, the entire set of tests is run +twice, once for each library. If you want to run just one set of tests, call +RunTest with either the -8 or -16 option. + +RunTest uses a file called testtry to hold the main output from pcretest. +Other files whose names begin with "test" are used as working files in some +tests. To run pcretest on just one or more specific test files, give their +numbers as arguments to RunTest, for example: + + RunTest 2 7 11 + +You can also call RunTest with the single argument "list" to cause it to output +a list of tests. + +The first test file can be fed directly into the perltest.pl script to check +that Perl gives the same results. The only difference you should see is in the +first few lines, where the Perl version is given instead of the PCRE version. -The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(), +The second set of tests check pcre_fullinfo(), pcre_study(), pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error detection, and run-time flags that are specific to PCRE, as well as the POSIX wrapper API. It also uses the debugging flags to check some of the internals of @@ -572,33 +658,32 @@ Windows versions of test 2. More info on using RunTest.bat is included in the document entitled NON-UNIX-USE.] -The fourth test checks the UTF-8 support. It is not run automatically unless -PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when -running "configure". This file can be also fed directly to the perltest.pl -script, provided you are running Perl 5.8 or higher. - -The fifth test checks error handling with UTF-8 encoding, and internal UTF-8 -features of PCRE that are not relevant to Perl. - -The sixth test (which is Perl-5.10 compatible) checks the support for Unicode -character properties. It it not run automatically unless PCRE is built with -Unicode property support. To to this you must set --enable-unicode-properties -when running "configure". - -The seventh, eighth, and ninth tests check the pcre_dfa_exec() alternative -matching function, in non-UTF-8 mode, UTF-8 mode, and UTF-8 mode with Unicode -property support, respectively. The eighth and ninth tests are not run -automatically unless PCRE is build with the relevant support. - -The tenth test checks some internal offsets and code size features; it is run -only when the default "link size" of 2 is set (in other cases the sizes -change). - -The eleventh test checks out features that are new in Perl 5.10, and the -twelfth test checks a number internals and non-Perl features concerned with -Unicode property support. It it not run automatically unless PCRE is built with -Unicode property support. To to this you must set --enable-unicode-properties -when running "configure". +The fourth and fifth tests check the UTF-8/16 support and error handling and +internal UTF features of PCRE that are not relevant to Perl, respectively. The +sixth and seventh tests do the same for Unicode character properties support. + +The eighth, ninth, and tenth tests check the pcre_dfa_exec() alternative +matching function, in non-UTF-8/16 mode, UTF-8/16 mode, and UTF-8/16 mode with +Unicode property support, respectively. + +The eleventh test checks some internal offsets and code size features; it is +run only when the default "link size" of 2 is set (in other cases the sizes +change) and when Unicode property support is enabled. + +The twelfth test is run only when JIT support is available, and the thirteenth +test is run only when JIT support is not available. They test some JIT-specific +features such as information output from pcretest about JIT compilation. + +The fourteenth, fifteenth, and sixteenth tests are run only in 8-bit mode, and +the seventeenth, eighteenth, and nineteenth tests are run only in 16-bit mode. +These are tests that generate different output in the two modes. They are for +general cases, UTF-8/16 support, and Unicode property support, respectively. + +The twentieth test is run only in 16-bit mode. It tests some specific 16-bit +features of the DFA matching engine. + +The twenty-first and twenty-second tests are run only in 16-bit mode, when the +link size is set to 2. They test reloading pre-compiled patterns. Character tables @@ -658,7 +743,9 @@ File manifest ------------- -The distribution should contain the following files: +The distribution should contain the files listed below. Where a file name is +given as pcre[16]_xxx it means that there are two files, one with the name +pcre_xxx and the other with the name pcre16_xxx. (A) Source files of the PCRE library functions and their headers: @@ -667,33 +754,40 @@ pcre_chartables.c.dist a default set of character tables that assume ASCII coding; used, unless --enable-rebuild-chartables is - specified, by copying to pcre_chartables.c + specified, by copying to pcre[16]_chartables.c pcreposix.c ) - pcre_compile.c ) - pcre_config.c ) - pcre_dfa_exec.c ) - pcre_exec.c ) - pcre_fullinfo.c ) - pcre_get.c ) sources for the functions in the library, - pcre_globals.c ) and some internal functions that they use - pcre_info.c ) - pcre_maketables.c ) - pcre_newline.c ) + pcre[16]_byte_order.c ) + pcre[16]_compile.c ) + pcre[16]_config.c ) + pcre[16]_dfa_exec.c ) + pcre[16]_exec.c ) + pcre[16]_fullinfo.c ) + pcre[16]_get.c ) sources for the functions in the library, + pcre[16]_globals.c ) and some internal functions that they use + pcre[16]_jit_compile.c ) + pcre[16]_maketables.c ) + pcre[16]_newline.c ) + pcre[16]_refcount.c ) + pcre[16]_string_utils.c ) + pcre[16]_study.c ) + pcre[16]_tables.c ) + pcre[16]_ucd.c ) + pcre[16]_version.c ) + pcre[16]_xclass.c ) pcre_ord2utf8.c ) - pcre_refcount.c ) - pcre_study.c ) - pcre_tables.c ) - pcre_try_flipped.c ) - pcre_ucd.c ) pcre_valid_utf8.c ) - pcre_version.c ) - pcre_xclass.c ) - pcre_printint.src ) debugging function that is #included in pcretest, + pcre16_ord2utf16.c ) + pcre16_utf16_utils.c ) + pcre16_valid_utf16.c ) + + pcre[16]_printint.c ) debugging function that is used by pcretest, ) and can also be #included in pcre_compile() + pcre.h.in template for pcre.h when built by "configure" pcreposix.h header for the external POSIX wrapper API pcre_internal.h header for internal use + sljit/* 16 files that make up the JIT compiler ucp.h header for Unicode property handling config.h.in template for config.h, which is built by "configure" @@ -730,7 +824,8 @@ Makefile.am ) the automake input that was used to create ) Makefile.in NEWS important changes in this release - NON-UNIX-USE notes on building PCRE on non-Unix systems + NON-UNIX-USE the previous name for NON-AUTOTOOLS-BUILD + NON-AUTOTOOLS-BUILD notes on building PCRE without using autotools PrepareRelease script to make preparations for "make dist" README this file RunTest a Unix shell script for running tests @@ -751,6 +846,7 @@ doc/pcretest.txt plain text documentation of test program doc/perltest.txt plain text documentation of Perl test program install-sh a shell script for installing files + libpcre16.pc.in template for libpcre16.pc for pkg-config libpcre.pc.in template for libpcre.pc for pkg-config libpcreposix.pc.in template for libpcreposix.pc for pkg-config libpcrecpp.pc.in template for libpcrecpp.pc for pkg-config @@ -760,17 +856,20 @@ mkinstalldirs script for making install directories perltest.pl Perl test program pcre-config.in source of script which retains PCRE information + pcre_jit_test.c test program for the JIT compiler pcrecpp_unittest.cc ) pcre_scanner_unittest.cc ) test programs for the C++ wrapper pcre_stringpiece_unittest.cc ) testdata/testinput* test data for main library tests testdata/testoutput* expected test results testdata/grep* input and output for pcregrep tests + testdata/* other supporting test files (D) Auxiliary files for cmake support cmake/COPYING-CMAKE-SCRIPTS cmake/FindPackageHandleStandardArgs.cmake + cmake/FindEditline.cmake cmake/FindReadline.cmake CMakeLists.txt config-cmake.h.in @@ -796,4 +895,4 @@ Philip Hazel Email local part: ph10 Email domain: cam.ac.uk -Last updated: 19 January 2010 +Last updated: 18 June 2012 diff -Nru pcre3-8.12/RunGrepTest pcre3-8.31/RunGrepTest --- pcre3-8.12/RunGrepTest 2011-01-14 16:50:43.000000000 +0000 +++ pcre3-8.31/RunGrepTest 2012-03-04 16:48:24.000000000 +0000 @@ -5,15 +5,23 @@ # supported by pcregrep. # Set the C locale, so that sort(1) behaves predictably. + LC_ALL=C export LC_ALL +# Remove any non-default colouring and aliases that the caller may have set. + +unset PCREGREP_COLOUR PCREGREP_COLOR +unset cp ls mv rm + +# Set the program to be tested, and valgrind settings when requested. + pcregrep=`pwd`/pcregrep valgrind= while [ $# -gt 0 ] ; do case $1 in - valgrind) valgrind="valgrind -q --leak-check=no";; + valgrind) valgrind="valgrind -q --leak-check=no --smc-check=all";; *) echo "RunGrepTest: Unknown argument $1"; exit 1;; esac shift @@ -28,12 +36,11 @@ $pcregrep -V -cf="diff -ub" - # Set up a suitable "diff" command for comparison. Some systems have a diff # that lacks a -u option. Try to deal with this; better do the test for the -b # option as well. +cf="diff -ub" if diff -u /dev/null /dev/null; then if diff -ub /dev/null /dev/null; then cf="diff -ub"; else cf="diff -u"; fi else @@ -41,18 +48,26 @@ fi # If PCRE has been built in a directory other than the source directory, and -# this test is being run from "make check" as usual, then $(srcdir) will be -# set. If not, set it to the current directory. We then arrange to run the -# pcregrep command in the source directory so that the file names that appear -# in the output are always the same. +# this test is being run from "make check" as usual, then $srcdir will be +# set. If not, set it to the current or parent directory, whichever one +# contains the test data. We then arrange to run the pcregrep command in the +# source directory so that the file names that appear in the output are always +# the same. if [ -z "$srcdir" -o ! -d "$srcdir/testdata" ] ; then - srcdir=. + if [ -d "./testdata" ] ; then + srcdir=. + elif [ -d "../testdata" ] ; then + srcdir=.. + else + echo "Cannot find the testdata directory" + exit 1 + fi fi # Check for the availability of UTF-8 support -./pcretest -C | ./pcregrep "No UTF-8 support" >/dev/null +./pcretest -C utf >/dev/null utf8=$? echo "---------------------------- Test 1 ------------------------------" >testtry @@ -305,11 +320,11 @@ echo "RC=$?" >>testtry echo "---------------------------- Test 62 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --match-limit=1000 -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 +(cd $srcdir; $valgrind $pcregrep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 63 -----------------------------" >>testtry -(cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 +(cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1 echo "RC=$?" >>testtry echo "---------------------------- Test 64 ------------------------------" >>testtry @@ -340,6 +355,98 @@ (cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtry echo "RC=$?" >>testtry +echo "---------------------------- Test 71 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 72 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 73 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 74 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 75 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 76 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 77 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 78 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 79 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 80 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 81 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 82 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtry +echo "RC=$?" >>testtry + +echo "---------------------------- Test 83 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 84 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist "fox|complete") >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 85 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 86 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 87 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 88 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 89 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 90 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 91 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 92 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + +echo "---------------------------- Test 93 -----------------------------" >>testtry +(cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtry 2>&1 +echo "RC=$?" >>testtry + # Now compare the results. $cf $srcdir/testdata/grepoutput testtry @@ -388,8 +495,7 @@ $valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry -pattern=`printf 'xxx\r\njkl'` -$valgrind $pcregrep -n --newline=crlf -F "$pattern" testNinput >>testtry +$valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinput >>testtry printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry $valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry diff -Nru pcre3-8.12/RunTest pcre3-8.31/RunTest --- pcre3-8.12/RunTest 2010-10-27 09:28:29.000000000 +0000 +++ pcre3-8.31/RunTest 2012-02-24 13:20:16.000000000 +0000 @@ -1,35 +1,97 @@ #! /bin/sh -# Run PCRE tests. +# Run the PCRE tests using the pcretest program. The appropriate tests are +# selected, depending on which build-time options were used. -valgrind= - -# Set up a suitable "diff" command for comparison. Some systems -# have a diff that lacks a -u option. Try to deal with this. - -if diff -u /dev/null /dev/null; then cf="diff -u"; else cf="diff"; fi - -# Find the test data - -testdata=testdata -if [ -n "$srcdir" -a -d "$srcdir" ] ; then - testdata="$srcdir/testdata" +# All tests are now run both with and without -s, to ensure that everything is +# tested with and without studying. However, there are some tests that produce +# different output after studying, typically when we are tracing the actual +# matching process (for example, using auto-callouts). In these few cases, the +# tests are duplicated in the files, one with /S to force studying always, and +# one with /SS to force *not* studying always. The use of -s doesn't then make +# any difference to their output. There is also one test which compiles invalid +# UTF-8 with the UTF-8 check turned off; for this, studying must also be +# disabled with /SS. + +# When JIT support is available, all the tests are also run with -s+ to test +# (again, almost) everything with studying and the JIT option. There are also +# two tests for JIT-specific features, one to be run when JIT support is +# available, and one when it is not. + +# Whichever of the 8-bit and 16-bit libraries exist are tested. It is also +# possible to select which to test by the arguments -8 or -16. + +# Other arguments for this script can be individual test numbers, or the word +# "valgrind", or "sim" followed by an argument to run cross-compiled +# executables under a simulator, for example: +# +# RunTest 3 sim "qemu-arm -s 8388608" +# +# Finally, if the script is obeyed as "RunTest list", a list of available +# tests is output, but none of them are run. + +# Define test titles in variables so that they can be output as a list. Some +# of them are modified (e.g. with -8 or -16) when used in the actual tests. + +title1="Test 1: Main functionality (Compatible with Perl >= 5.10)" +title2="Test 2: API, errors, internals, and non-Perl stuff" +title3="Test 3: Locale-specific features" +title4A="Test 4: UTF" +title4B=" support (Compatible with Perl >= 5.10)" +title5="Test 5: API, internals, and non-Perl stuff for UTF" +title6="Test 6: Unicode property support (Compatible with Perl >= 5.10)" +title7="Test 7: API, internals, and non-Perl stuff for Unicode property support" +title8="Test 8: DFA matching main functionality" +title9="Test 9: DFA matching with UTF" +title10="Test 10: DFA matching with Unicode properties" +title11="Test 11: Internal offsets and code size tests" +title12="Test 12: JIT-specific features (JIT available)" +title13="Test 13: JIT-specific features (JIT not available)" +title14="Test 14: Specials for the basic 8-bit library" +title15="Test 15: Specials for the 8-bit library with UTF-8 support" +title16="Test 16: Specials for the 8-bit library with Unicode propery support" +title17="Test 17: Specials for the basic 16-bit library" +title18="Test 18: Specials for the 16-bit library with UTF-16 support" +title19="Test 19: Specials for the 16-bit library with Unicode propery support" +title20="Test 20: DFA specials for the basic 16-bit library" +title21="Test 21: Reloads for the basic 16-bit library" +title22="Test 22: Reloads for the 16-bit library with UTF-16 support" + +if [ $# -eq 1 -a "$1" = "list" ]; then + echo $title1 + echo $title2 "(not UTF)" + echo $title3 + echo $title4A $title4B + echo $title5 support + echo $title6 + echo $title7 + echo $title8 + echo $title9 + echo $title10 + echo $title11 + echo $title12 + echo $title13 + echo $title14 + echo $title15 + echo $title16 + echo $title17 + echo $title18 + echo $title19 + echo $title20 + echo $title21 + echo $title22 + exit 0 fi -# Find which optional facilities are available - -case `./pcretest -C | ./pcregrep 'Internal link size'` in - *2) link_size=2;; - *3) link_size=3;; - *4) link_size=4;; - *) echo "Failed to find internal link size"; exit 1;; -esac +# Default values -./pcretest -C | ./pcregrep 'No UTF-8 support' >/dev/null -utf8=$? +valgrind= +sim= +arg8= +arg16= -./pcretest -C | ./pcregrep 'No Unicode properties support' >/dev/null -ucp=$? +# This is in case the caller has set aliases (as I do - PH) +unset cp ls mv rm # Select which tests to run; for those that are explicitly requested, check # that the necessary optional facilities are available. @@ -46,6 +108,16 @@ do10=no do11=no do12=no +do13=no +do14=no +do15=no +do16=no +do17=no +do18=no +do19=no +do20=no +do21=no +do22=no while [ $# -gt 0 ] ; do case $1 in @@ -61,25 +133,132 @@ 10) do10=yes;; 11) do11=yes;; 12) do12=yes;; - valgrind) valgrind="valgrind -q";; - *) echo "Unknown test number $1"; exit 1;; + 13) do13=yes;; + 14) do14=yes;; + 15) do15=yes;; + 16) do16=yes;; + 17) do17=yes;; + 18) do18=yes;; + 19) do19=yes;; + 20) do20=yes;; + 21) do21=yes;; + 22) do22=yes;; + -8) arg8=yes;; + -16) arg16=yes;; + valgrind) valgrind="valgrind -q --smc-check=all";; + sim) shift; sim=$1;; + *) echo "Unknown test number '$1'"; exit 1;; esac shift done -if [ $utf8 -eq 0 ] ; then +# Set up a suitable "diff" command for comparison. Some systems +# have a diff that lacks a -u option. Try to deal with this. + +if diff -u /dev/null /dev/null; then cf="diff -u"; else cf="diff"; fi + +# Find the test data + +if [ -n "$srcdir" -a -d "$srcdir" ] ; then + testdata="$srcdir/testdata" +elif [ -d "./testdata" ] ; then + testdata=./testdata +elif [ -d "../testdata" ] ; then + testdata=../testdata +else + echo "Cannot find the testdata directory" + exit 1 +fi + +# Find which optional facilities are available. In some Windows environments +# the output of pcretest -C has CRLF at the end of each line, but the shell +# strips only linefeeds from the output of a `backquoted` command. Hence the +# alternative patterns. + +$sim ./pcretest -C linksize >/dev/null +link_size=$? +if [ $link_size -lt 2 ] ; then + echo "Failed to find internal link size" + exit 1 +fi +if [ $link_size -gt 4 ] ; then + echo "Failed to find internal link size" + exit 1 +fi + +# Both 8-bit and 16-bit character strings may be supported, but only one +# need be. + +$sim ./pcretest -C pcre8 >/dev/null +support8=$? +$sim ./pcretest -C pcre16 >/dev/null +support16=$? +if [ `expr $support8 + $support16` -eq 2 ] ; then + test8= + test16=-16 + if [ "$arg8" = yes -a "$arg16" != yes ] ; then + test16=skip + fi + if [ "$arg16" = yes -a "$arg8" != yes ] ; then + test8=skip + fi +else + if [ $support8 -ne 0 ] ; then + if [ "$arg16" = yes ] ; then + echo "Cannot run 16-bit library tests: 16-bit library not compiled" + exit 1 + fi + test8= + test16=skip + else + if [ "$arg8" = yes ] ; then + echo "Cannot run 8-bit library tests: 8-bit library not compiled" + exit 1 + fi + test8=skip + test16=-16 + fi +fi + +# UTF support always applies to both bit sizes if both are supported; we can't +# have UTF-8 support without UTF-16 support (for example). + +$sim ./pcretest -C utf >/dev/null +utf=$? + +$sim ./pcretest -C ucp >/dev/null +ucp=$? + +jitopt= +$sim ./pcretest -C jit >/dev/null +jit=$? +if [ $jit -ne 0 ] ; then + jitopt=-s+ +fi + +if [ $utf -eq 0 ] ; then if [ $do4 = yes ] ; then - echo "Can't run test 4 because UTF-8 support is not configured" + echo "Can't run test 4 because UTF support is not configured" exit 1 fi if [ $do5 = yes ] ; then - echo "Can't run test 5 because UTF-8 support is not configured" + echo "Can't run test 5 because UTF support is not configured" exit 1 fi - if [ $do8 = yes ] ; then - echo "Can't run test 8 because UTF-8 support is not configured" + if [ $do9 = yes ] ; then + echo "Can't run test 8 because UTF support is not configured" + exit 1 + fi + if [ $do15 = yes ] ; then + echo "Can't run test 15 because UTF support is not configured" exit 1 fi + if [ $do18 = yes ] ; then + echo "Can't run test 18 because UTF support is not configured" + fi + if [ $do22 = yes ] ; then + echo "Can't run test 22 because UTF support is not configured" + fi fi if [ $ucp -eq 0 ] ; then @@ -87,88 +266,137 @@ echo "Can't run test 6 because Unicode property support is not configured" exit 1 fi - if [ $do9 = yes ] ; then - echo "Can't run test 9 because Unicode property support is not configured" + if [ $do7 = yes ] ; then + echo "Can't run test 7 because Unicode property support is not configured" exit 1 fi if [ $do10 = yes ] ; then echo "Can't run test 10 because Unicode property support is not configured" exit 1 fi - if [ $do12 = yes ] ; then - echo "Can't run test 12 because Unicode property support is not configured" + if [ $do16 = yes ] ; then + echo "Can't run test 16 because Unicode property support is not configured" + exit 1 + fi + if [ $do19 = yes ] ; then + echo "Can't run test 19 because Unicode property support is not configured" exit 1 fi fi if [ $link_size -ne 2 ] ; then - if [ $do10 = yes ] ; then - echo "Can't run test 10 because the link size ($link_size) is not 2" + if [ $do11 = yes ] ; then + echo "Can't run test 11 because the link size ($link_size) is not 2" + exit 1 + fi +fi + +if [ $jit -eq 0 ] ; then + if [ $do12 = "yes" ] ; then + echo "Can't run test 12 because JIT support is not configured" + exit 1 + fi +else + if [ $do13 = "yes" ] ; then + echo "Can't run test 13 because JIT support is configured" exit 1 fi fi -# If no specific tests were requested, select all that are relevant. +# If no specific tests were requested, select all. Those that are not +# relevant will be skipped. -if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ - $do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \ - $do9 = no -a $do10 = no -a $do11 = no -a $do12 = no ] ; then +if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ + $do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \ + $do9 = no -a $do10 = no -a $do11 = no -a $do12 = no -a \ + $do13 = no -a $do14 = no -a $do15 = no -a $do16 = no -a \ + $do17 = no -a $do18 = no -a $do19 = no -a $do20 = no -a \ + $do21 = no -a $do22 = no ] ; then do1=yes do2=yes do3=yes - if [ $utf8 -ne 0 ] ; then do4=yes; fi - if [ $utf8 -ne 0 ] ; then do5=yes; fi - if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do6=yes; fi + do4=yes + do5=yes + do6=yes do7=yes - if [ $utf8 -ne 0 ] ; then do8=yes; fi - if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do9=yes; fi - if [ $link_size -eq 2 -a $ucp -ne 0 ] ; then do10=yes; fi + do8=yes + do9=yes + do10=yes do11=yes - if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do12=yes; fi + do12=yes + do13=yes + do14=yes + do15=yes + do16=yes + do17=yes + do18=yes + do19=yes + do20=yes + do21=yes + do22=yes fi -# Show which release +# Show which release and which test data echo "" -echo PCRE C library tests -./pcretest /dev/null +echo PCRE C library tests using test data from $testdata +$sim ./pcretest /dev/null + +for bmode in "$test8" "$test16"; do + case "$bmode" in + skip) continue;; + -16) if [ "$test8" != "skip" ] ; then echo ""; fi + bits=16; echo "---- Testing 16-bit library ----"; echo "";; + *) bits=8; echo "---- Testing 8-bit library ----"; echo "";; + esac -# Primary test, compatible with all versions of Perl >= 5.8 +# Primary test, compatible with JIT and all versions of Perl >= 5.8 if [ $do1 = yes ] ; then - echo "Test 1: main functionality (Compatible with Perl >= 5.8)" - $valgrind ./pcretest -q $testdata/testinput1 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput1 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 - fi - echo "OK" + echo $title1 + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput1 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput1 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi -# PCRE tests that are not Perl-compatible - API, errors, internals +# PCRE tests that are not JIT or Perl-compatible: API, errors, internals if [ $do2 = yes ] ; then - echo "Test 2: API, errors, internals, and non-Perl stuff" - $valgrind ./pcretest -q $testdata/testinput2 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput2 testtry - if [ $? != 0 ] ; then exit 1; fi - else - echo " " - echo "** Test 2 requires a lot of stack. If it has crashed with a" - echo "** segmentation fault, it may be that you do not have enough" - echo "** stack available by default. Please see the 'pcrestack' man" - echo "** page for a discussion of PCRE's stack usage." - echo " " - exit 1 - fi - echo "OK" + echo $title2 "(not UTF-$bits)" + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput2 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput2 testtry + if [ $? != 0 ] ; then exit 1; fi + else + echo " " + echo "** Test 2 requires a lot of stack. If it has crashed with a" + echo "** segmentation fault, it may be that you do not have enough" + echo "** stack available by default. Please see the 'pcrestack' man" + echo "** page for a discussion of PCRE's stack usage." + echo " " + exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi # Locale-specific tests, provided that either the "fr_FR" or the "french" # locale is available. The former is the Unix-like standard; the latter is -# for Windows. +# for Windows. Another possibility is "fr", which needs to be run against +# the Windows-specific input and output files. if [ $do3 = yes ] ; then locale -a | grep '^fr_FR$' >/dev/null @@ -177,152 +405,458 @@ infile=$testdata/testinput3 outfile=$testdata/testoutput3 else + infile=test3input + outfile=test3output locale -a | grep '^french$' >/dev/null if [ $? -eq 0 ] ; then locale=french sed 's/fr_FR/french/' $testdata/testinput3 >test3input sed 's/fr_FR/french/' $testdata/testoutput3 >test3output - infile=test3input - outfile=test3output else - locale= + locale -a | grep '^fr$' >/dev/null + if [ $? -eq 0 ] ; then + locale=fr + sed 's/fr_FR/fr/' $testdata/wintestinput3 >test3input + sed 's/fr_FR/fr/' $testdata/wintestoutput3 >test3output + else + locale= + fi fi fi if [ "$locale" != "" ] ; then - echo "Test 3: locale-specific features (using '$locale' locale)" - $valgrind ./pcretest -q $infile testtry - if [ $? = 0 ] ; then - $cf $outfile testtry - if [ $? != 0 ] ; then - echo " " - echo "Locale test did not run entirely successfully." - echo "This usually means that there is a problem with the locale" - echo "settings rather than a bug in PCRE." - else - echo "OK" + echo $title3 "(using '$locale' locale)" + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $infile testtry + if [ $? = 0 ] ; then + $cf $outfile testtry + if [ $? != 0 ] ; then + echo " " + echo "Locale test did not run entirely successfully." + echo "This usually means that there is a problem with the locale" + echo "settings rather than a bug in PCRE." + break; + else + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + fi + else exit 1 fi - else exit 1 - fi + done else - echo "Cannot test locale-specific features - neither the 'fr_FR' nor the" - echo "'french' locale exists, or the \"locale\" command is not available" + echo "Cannot test locale-specific features - none of the 'fr_FR', 'fr' or" + echo "'french' locales exist, or the \"locale\" command is not available" echo "to check for them." echo " " fi fi -# Additional tests for UTF8 support +# Additional tests for UTF support if [ $do4 = yes ] ; then - echo "Test 4: UTF-8 support (Compatible with Perl >= 5.8)" - $valgrind ./pcretest -q $testdata/testinput4 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput4 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 + echo ${title4A}-${bits}${title4B} + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput4 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput4 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi - echo "OK" fi if [ $do5 = yes ] ; then - echo "Test 5: API, internals, and non-Perl stuff for UTF-8 support" - $valgrind ./pcretest -q $testdata/testinput5 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput5 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 + echo ${title5}-${bits} support + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput5 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput5 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi - echo "OK" fi if [ $do6 = yes ] ; then - echo "Test 6: Unicode property support (Compatible with Perl >= 5.10)" - $valgrind ./pcretest -q $testdata/testinput6 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput6 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 + echo $title6 + if [ $utf -eq 0 -o $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput6 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput6 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi - echo "OK" fi -# Tests for DFA matching support +# Test non-Perl-compatible Unicode property support if [ $do7 = yes ] ; then - echo "Test 7: DFA matching" - $valgrind ./pcretest -q -dfa $testdata/testinput7 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput7 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 + echo $title7 + if [ $utf -eq 0 -o $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput7 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput7 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done fi - echo "OK" fi +# Tests for DFA matching support + if [ $do8 = yes ] ; then - echo "Test 8: DFA matching with UTF-8" - $valgrind ./pcretest -q -dfa $testdata/testinput8 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput8 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 - fi - echo "OK" + echo $title8 + for opt in "" "-s"; do + $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput8 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput8 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi + done fi if [ $do9 = yes ] ; then - echo "Test 9: DFA matching with Unicode properties" - $valgrind ./pcretest -q -dfa $testdata/testinput9 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput9 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 + echo ${title9}-${bits} + if [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" "-s"; do + $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput9 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput9 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi + done + fi +fi + +if [ $do10 = yes ] ; then + echo $title10 + if [ $utf -eq 0 -o $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s"; do + $sim $valgrind ./pcretest -q $bmode $opt -dfa $testdata/testinput10 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput10 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi + done fi - echo "OK" fi # Test of internal offsets and code sizes. This test is run only when there # is Unicode property support and the link size is 2. The actual tests are # mostly the same as in some of the above, but in this test we inspect some # offsets and sizes that require a known link size. This is a doublecheck for -# the maintainer, just in case something changes unexpectely. +# the maintainer, just in case something changes unexpectely. The output from +# this test is not the same in 8-bit and 16-bit modes. -if [ $do10 = yes ] ; then - echo "Test 10: Internal offsets and code size tests" - $valgrind ./pcretest -q $testdata/testinput10 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput10 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 +if [ $do11 = yes ] ; then + echo $title11 + if [ $link_size -ne 2 ] ; then + echo " Skipped because link size is not 2" + elif [ $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s"; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput11 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput11-$bits testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" ; else echo " OK"; fi + done fi - echo "OK" fi -# Test of Perl >= 5.10 features +# Test JIT-specific features when JIT is available -if [ $do11 = yes ] ; then - echo "Test 11: Features from Perl >= 5.10" - $valgrind ./pcretest -q $testdata/testinput11 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput11 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 +if [ $do12 = yes ] ; then + echo $title12 + if [ $jit -eq 0 ] ; then + echo " Skipped because JIT is not available or not usable" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput12 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput12 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" fi - echo "OK" fi -# Test non-Perl-compatible Unicode property support +# Test JIT-specific features when JIT is not available -if [ $do12 = yes ] ; then - echo "Test 12: API, internals, and non-Perl stuff for Unicode property support" - $valgrind ./pcretest -q $testdata/testinput12 testtry - if [ $? = 0 ] ; then - $cf $testdata/testoutput12 testtry - if [ $? != 0 ] ; then exit 1; fi - else exit 1 +if [ $do13 = yes ] ; then + echo $title13 + if [ $jit -ne 0 ] ; then + echo " Skipped because JIT is available" + else + $sim $valgrind ./pcretest -q $bmode $testdata/testinput13 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput13 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +# Tests for 8-bit-specific features + +if [ "$do14" = yes ] ; then + echo $title14 + if [ "$bits" = "16" ] ; then + echo " Skipped when running 16-bit tests" + else + cp -f $testdata/saved16 testsaved16 + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput14 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput14 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 8-bit-specific features (needs UTF-8 support) + +if [ "$do15" = yes ] ; then + echo $title15 + if [ "$bits" = "16" ] ; then + echo " Skipped when running 16-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput15 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput15 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 8-bit-specific features (Unicode property support) + +if [ $do16 = yes ] ; then + echo $title16 + if [ "$bits" = "16" ] ; then + echo " Skipped when running 16-bit tests" + elif [ $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput16 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput16 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 16-bit-specific features + +if [ $do17 = yes ] ; then + echo $title17 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput17 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput17 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 16-bit-specific features (UTF-16 support) + +if [ $do18 = yes ] ; then + echo $title18 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput18 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput18 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 16-bit-specific features (Unicode property support) + +if [ $do19 = yes ] ; then + echo $title19 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + elif [ $ucp -eq 0 ] ; then + echo " Skipped because Unicode property support is not available" + else + for opt in "" "-s" $jitopt; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput19 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput19 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study" + else echo " OK" + fi + done + fi +fi + +# Tests for 16-bit-specific features in DFA non-UTF-16 mode + +if [ $do20 = yes ] ; then + echo $title20 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + else + for opt in "" "-s"; do + $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput20 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput20 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + if [ "$opt" = "-s" ] ; then echo " OK with study" + else echo " OK" + fi + done + fi +fi + +# Tests for reloads with 16-bit library + +if [ $do21 = yes ] ; then + echo $title21 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + elif [ $link_size -ne 2 ] ; then + echo " Skipped because link size is not 2" + else + cp -f $testdata/saved8 testsaved8 + cp -f $testdata/saved16LE-1 testsaved16LE-1 + cp -f $testdata/saved16BE-1 testsaved16BE-1 + $sim $valgrind ./pcretest -q $bmode $testdata/testinput21 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput21 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" fi - echo "OK" fi +# Tests for reloads with 16-bit library (UTF-16 support) + +if [ $do22 = yes ] ; then + echo $title22 + if [ "$bits" = "8" ] ; then + echo " Skipped when running 8-bit tests" + elif [ $utf -eq 0 ] ; then + echo " Skipped because UTF-$bits support is not available" + elif [ $link_size -ne 2 ] ; then + echo " Skipped because link size is not 2" + else + cp -f $testdata/saved16LE-2 testsaved16LE-2 + cp -f $testdata/saved16BE-2 testsaved16BE-2 + $sim $valgrind ./pcretest -q $bmode $testdata/testinput22 testtry + if [ $? = 0 ] ; then + $cf $testdata/testoutput22 testtry + if [ $? != 0 ] ; then exit 1; fi + else exit 1 + fi + echo " OK" + fi +fi + +# End of loop for 8-bit/16-bit tests +done + +# Clean up local working files +rm -f test3input test3output testNinput testsaved* teststderr teststdout testtry + # End diff -Nru pcre3-8.12/RunTest.bat pcre3-8.31/RunTest.bat --- pcre3-8.12/RunTest.bat 2009-10-19 11:10:06.000000000 +0000 +++ pcre3-8.31/RunTest.bat 2012-01-17 14:10:47.000000000 +0000 @@ -1,43 +1,480 @@ -@rem This file was contributed by Ralf Junker, and touched up by -@rem Daniel Richard G. Tests 10-12 added by Philip H. -@rem Philip H also changed test 3 to use "wintest" files. -@rem -@rem MS Windows batch file to run pcretest on testfiles with the correct -@rem options. -@rem -@rem Output is written to a newly created subfolder named "testdata". - -setlocal - -if [%srcdir%]==[] set srcdir=. -if [%pcretest%]==[] set pcretest=pcretest - -if not exist testout md testout - -%pcretest% -q %srcdir%\testdata\testinput1 > testout\testoutput1 -%pcretest% -q %srcdir%\testdata\testinput2 > testout\testoutput2 -@rem %pcretest% -q %srcdir%\testdata\testinput3 > testout\testoutput3 -%pcretest% -q %srcdir%\testdata\wintestinput3 > testout\wintestoutput3 -%pcretest% -q %srcdir%\testdata\testinput4 > testout\testoutput4 -%pcretest% -q %srcdir%\testdata\testinput5 > testout\testoutput5 -%pcretest% -q %srcdir%\testdata\testinput6 > testout\testoutput6 -%pcretest% -q -dfa %srcdir%\testdata\testinput7 > testout\testoutput7 -%pcretest% -q -dfa %srcdir%\testdata\testinput8 > testout\testoutput8 -%pcretest% -q -dfa %srcdir%\testdata\testinput9 > testout\testoutput9 -%pcretest% -q %srcdir%\testdata\testinput10 > testout\testoutput10 -%pcretest% -q %srcdir%\testdata\testinput11 > testout\testoutput11 -%pcretest% -q %srcdir%\testdata\testinput12 > testout\testoutput12 - -fc /n %srcdir%\testdata\testoutput1 testout\testoutput1 -fc /n %srcdir%\testdata\testoutput2 testout\testoutput2 -rem fc /n %srcdir%\testdata\testoutput3 testout\testoutput3 -fc /n %srcdir%\testdata\wintestoutput3 testout\wintestoutput3 -fc /n %srcdir%\testdata\testoutput4 testout\testoutput4 -fc /n %srcdir%\testdata\testoutput5 testout\testoutput5 -fc /n %srcdir%\testdata\testoutput6 testout\testoutput6 -fc /n %srcdir%\testdata\testoutput7 testout\testoutput7 -fc /n %srcdir%\testdata\testoutput8 testout\testoutput8 -fc /n %srcdir%\testdata\testoutput9 testout\testoutput9 -fc /n %srcdir%\testdata\testoutput10 testout\testoutput10 -fc /n %srcdir%\testdata\testoutput11 testout\testoutput11 -fc /n %srcdir%\testdata\testoutput12 testout\testoutput12 +@echo off +@rem This file must use CRLF linebreaks to function properly +@rem and requires both pcretest and pcregrep +@rem This file was originally contributed by Ralf Junker, and touched up by +@rem Daniel Richard G. Tests 10-12 added by Philip H. +@rem Philip H also changed test 3 to use "wintest" files. +@rem +@rem Updated by Tom Fortmann to support explicit test numbers on the command line. +@rem Added argument validation and added error reporting. +@rem +@rem MS Windows batch file to run pcretest on testfiles with the correct +@rem options. +@rem +@rem Sheri Pierce added logic to skip feature dependent tests +@rem tests 4 5 9 15 and 18 require utf support +@rem tests 6 7 10 16 and 19 require ucp support +@rem 11 requires ucp and link size 2 +@rem 12 requires presense of jit support +@rem 13 requires absence of jit support +@rem Sheri P also added override tests for study and jit testing +@rem Zoltan Herczeg added libpcre16 support + +setlocal enabledelayedexpansion +if [%srcdir%]==[] ( +if exist testdata\ set srcdir=.) +if [%srcdir%]==[] ( +if exist ..\testdata\ set srcdir=..) +if [%srcdir%]==[] ( +if exist ..\..\testdata\ set srcdir=..\..) +if NOT exist "%srcdir%\testdata\" ( +Error: echo distribution testdata folder not found! +call :conferror +exit /b 1 +goto :eof +) + +if "%pcretest%"=="" set pcretest=.\pcretest.exe + +echo source dir is %srcdir% +echo pcretest=%pcretest% + +if NOT exist "%pcretest%" ( +echo Error: "%pcretest%" not found! +echo. +call :conferror +exit /b 1 +) + +"%pcretest%" -C linksize >NUL +set link_size=%ERRORLEVEL% +"%pcretest%" -C pcre8 >NUL +set support8=%ERRORLEVEL% +"%pcretest%" -C pcre16 >NUL +set support16=%ERRORLEVEL% +"%pcretest%" -C utf >NUL +set utf=%ERRORLEVEL% +"%pcretest%" -C ucp >NUL +set ucp=%ERRORLEVEL% +"%pcretest%" -C jit >NUL +set jit=%ERRORLEVEL% + +if %support8% EQU 1 ( +if not exist testout8 md testout8 +if not exist testoutstudy8 md testoutstudy8 +if not exist testoutjit8 md testoutjit8 +) + +if %support16% EQU 1 ( +if not exist testout16 md testout16 +if not exist testoutstudy16 md testoutstudy16 +if not exist testoutjit16 md testoutjit16 +) + +set do1=no +set do2=no +set do3=no +set do4=no +set do5=no +set do6=no +set do7=no +set do8=no +set do9=no +set do10=no +set do11=no +set do12=no +set do13=no +set do14=no +set do15=no +set do16=no +set do17=no +set do18=no +set do19=no +set do20=no +set all=yes + +for %%a in (%*) do ( + set valid=no + for %%v in (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) do if %%v == %%a set valid=yes + if "!valid!" == "yes" ( + set do%%a=yes + set all=no +) else ( + echo Invalid test number - %%a! + echo Usage %0 [ test_number ] ... + echo Where test_number is one or more optional test numbers 1 through 20, default is all tests. + exit /b 1 +) +) +set failed="no" + +if "%all%" == "yes" ( + set do1=yes + set do2=yes + set do3=yes + set do4=yes + set do5=yes + set do6=yes + set do7=yes + set do8=yes + set do9=yes + set do10=yes + set do11=yes + set do12=yes + set do13=yes + set do14=yes + set do15=yes + set do16=yes + set do17=yes + set do18=yes + set do19=yes + set do20=yes +) + +@echo RunTest.bat's pcretest output is written to newly created subfolders named +@echo testout, testoutstudy and testoutjit. +@echo. + +set mode= +set bits=8 + +:nextMode +if "%mode%" == "" ( + if %support8% EQU 0 goto modeSkip + echo. + echo ---- Testing 8-bit library ---- + echo. +) else ( + if %support16% EQU 0 goto modeSkip + echo. + echo ---- Testing 16-bit library ---- + echo. +) +if "%do1%" == "yes" call :do1 +if "%do2%" == "yes" call :do2 +if "%do3%" == "yes" call :do3 +if "%do4%" == "yes" call :do4 +if "%do5%" == "yes" call :do5 +if "%do6%" == "yes" call :do6 +if "%do7%" == "yes" call :do7 +if "%do8%" == "yes" call :do8 +if "%do9%" == "yes" call :do9 +if "%do10%" == "yes" call :do10 +if "%do11%" == "yes" call :do11 +if "%do12%" == "yes" call :do12 +if "%do13%" == "yes" call :do13 +if "%do14%" == "yes" call :do14 +if "%do15%" == "yes" call :do15 +if "%do16%" == "yes" call :do16 +if "%do17%" == "yes" call :do17 +if "%do18%" == "yes" call :do18 +if "%do19%" == "yes" call :do19 +if "%do20%" == "yes" call :do20 +:modeSkip +if "%mode%" == "" ( + set mode=-16 + set bits=16 + goto nextMode +) + +if %failed% == "yes" ( +echo In above output, one or more of the various tests failed! +exit /b 1 +) +echo All OK +goto :eof + +:runsub +@rem Function to execute pcretest and compare the output +@rem Arguments are as follows: +@rem +@rem 1 = test number +@rem 2 = outputdir +@rem 3 = test name use double quotes +@rem 4 - 9 = pcretest options + +if [%1] == [] ( + echo Missing test number argument! + exit /b 1 +) + +if [%2] == [] ( + echo Missing outputdir! + exit /b 1 +) + +if [%3] == [] ( + echo Missing test name argument! + exit /b 1 +) + +set testinput=testinput%1 +set testoutput=testoutput%1 +if exist %srcdir%\testdata\win%testinput% ( + set testinput=wintestinput%1 + set testoutput=wintestoutput%1 +) + +echo Test %1: %3 +"%pcretest%" %mode% %4 %5 %6 %7 %8 %9 "%srcdir%\testdata\%testinput%">%2%bits%\%testoutput% +if errorlevel 1 ( + echo. failed executing command-line: + echo. "%pcretest%" %mode% %4 %5 %6 %7 %8 %9 "%srcdir%\testdata\%testinput%"^>%2%bits%\%testoutput% + set failed="yes" + goto :eof +) + +if [%1]==[11] ( + fc /n "%srcdir%\testdata\%testoutput%-%bits%" "%2%bits%\%testoutput%">NUL +) else ( + fc /n "%srcdir%\testdata\%testoutput%" "%2%bits%\%testoutput%">NUL +) +if errorlevel 1 ( + echo. failed comparison: fc /n "%srcdir%\testdata\%testoutput%" "%2%bits%\%testoutput%" + if [%1]==[2] ( + echo. + echo ** Test 2 requires a lot of stack. PCRE can be configured to + echo ** use heap for recursion. Otherwise, to pass Test 2 + echo ** you generally need to allocate 8 mb stack to PCRE. + echo ** See the 'pcrestack' page for a discussion of PCRE's + echo ** stack usage. + echo. +) + if [%1]==[3] ( + echo. + echo ** Test 3 failure usually means french locale is not + echo ** available on the system, rather than a bug or problem with PCRE. + echo. + goto :eof +) + + set failed="yes" + goto :eof +) + +echo. Passed. +goto :eof + +:do1 +call :runsub 1 testout "Main functionality - Compatible with Perl 5.8 and above" -q +call :runsub 1 testoutstudy "Test with Study Override" -q -s +if %jit% EQU 1 call :runsub 1 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do2 + call :runsub 2 testout "API, errors, internals, and non-Perl stuff (not UTF-8)" -q + call :runsub 2 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 2 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do3 + call :runsub 3 testout "Locale-specific features" -q + call :runsub 3 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 3 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do4 + if %utf% EQU 0 ( + echo Test 4 Skipped due to absence of UTF-%bits% support. + goto :eof +) + call :runsub 4 testout "UTF-%bits% support - Compatible with Perl 5.8 and above" -q + call :runsub 4 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 4 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do5 + if %utf% EQU 0 ( + echo Test 5 Skipped due to absence of UTF-%bits% support. + goto :eof +) + call :runsub 5 testout "API, internals, and non-Perl stuff for UTF-%bits% support" -q + call :runsub 5 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 5 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do6 +if %ucp% EQU 0 ( + echo Test 6 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 6 testout "Unicode property support (Compatible with Perl >= 5.10)" -q + call :runsub 6 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 6 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do7 +if %ucp% EQU 0 ( + echo Test 7 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 7 testout "API, internals, and non-Perl stuff for Unicode property support" -q + call :runsub 7 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 7 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do8 + call :runsub 8 testout "DFA matching main functionality" -q -dfa + call :runsub 8 testoutstudy "Test with Study Override" -q -dfa -s +goto :eof + +:do9 + if %utf% EQU 0 ( + echo Test 9 Skipped due to absence of UTF-%bits% support. + goto :eof +) + call :runsub 9 testout "DFA matching with UTF-%bits%" -q -dfa + call :runsub 9 testoutstudy "Test with Study Override" -q -dfa -s + goto :eof + +:do10 + if %ucp% EQU 0 ( + echo Test 10 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 10 testout "DFA matching with Unicode properties" -q -dfa + call :runsub 10 testoutstudy "Test with Study Override" -q -dfa -s +goto :eof + +:do11 + if NOT %link_size% EQU 2 ( + echo Test 11 Skipped because link size is not 2. + goto :eof +) + if %ucp% EQU 0 ( + echo Test 11 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 11 testout "Internal offsets and code size tests" -q + call :runsub 11 testoutstudy "Test with Study Override" -q -s +goto :eof + +:do12 +if %jit% EQU 0 ( + echo Test 12 Skipped due to absence of JIT support. + goto :eof +) + call :runsub 12 testout "JIT-specific features - have JIT" -q +goto :eof + +:do13 + if %jit% EQU 1 ( + echo Test 13 Skipped due to presence of JIT support. + goto :eof +) + call :runsub 13 testout "JIT-specific features - no JIT" -q +goto :eof + +:do14 + if NOT %bits% EQU 8 ( + echo Test 14 Skipped when running 16-bit tests. + goto :eof +) + copy /Y "%srcdir%\testdata\saved16" testsaved16 + call :runsub 14 testout "Specials for the basic 8-bit library" -q + call :runsub 14 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 14 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do15 + if NOT %bits% EQU 8 ( + echo Test 15 Skipped when running 16-bit tests. + goto :eof +) + if %utf% EQU 0 ( + echo Test 15 Skipped due to absence of UTF-8 support. + goto :eof +) + call :runsub 15 testout "Specials for the 8-bit library with UTF-8 support" -q + call :runsub 15 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 15 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do16 + if NOT %bits% EQU 8 ( + echo Test 16 Skipped when running 16-bit tests. + goto :eof +) + if %ucp% EQU 0 ( + echo Test 16 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 16 testout "Specials for the 8-bit library with Unicode propery support" -q + call :runsub 16 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 16 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do17 + if NOT %bits% EQU 16 ( + echo Test 17 Skipped when running 8-bit tests. + goto :eof +) + copy /Y "%srcdir%\testdata\saved8" testsaved8 + copy /Y "%srcdir%\testdata\saved16LE-1" testsaved16LE-1 + copy /Y "%srcdir%\testdata\saved16BE-1" testsaved16BE-1 + call :runsub 17 testout "Specials for the basic 8-bit library" -q + call :runsub 17 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 17 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do18 + if NOT %bits% EQU 16 ( + echo Test 18 Skipped when running 8-bit tests. + goto :eof +) + if %utf% EQU 0 ( + echo Test 18 Skipped due to absence of UTF-8 support. + goto :eof +) + copy /Y "%srcdir%\testdata\saved16LE-2" testsaved16LE-2 + copy /Y "%srcdir%\testdata\saved16BE-2" testsaved16BE-2 + call :runsub 18 testout "Specials for the basic 8-bit library" -q + call :runsub 18 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 18 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do19 + if NOT %bits% EQU 16 ( + echo Test 19 Skipped when running 8-bit tests. + goto :eof +) + if %ucp% EQU 0 ( + echo Test 19 Skipped due to absence of Unicode property support. + goto :eof +) + call :runsub 19 testout "Specials for the basic 8-bit library" -q + call :runsub 19 testoutstudy "Test with Study Override" -q -s + if %jit% EQU 1 call :runsub 19 testoutjit "Test with JIT Override" -q -s+ +goto :eof + +:do20 + if NOT %bits% EQU 16 ( + echo Test 20 Skipped when running 8-bit tests. + goto :eof +) + call :runsub 20 testout "DFA specials for the basic 16-bit library" -q + call :runsub 20 testoutstudy "Test with Study Override" -q -s +goto :eof + +:conferror +@echo. +@echo Either your build is incomplete or you have a configuration error. +@echo. +@echo If configured with cmake and executed via "make test" or the MSVC "RUN_TESTS" +@echo project, pcre_test.bat defines variables and automatically calls RunTest.bat. +@echo For manual testing of all available features, after configuring with cmake +@echo and building, you can run the built pcre_test.bat. For best results with +@echo cmake builds and tests avoid directories with full path names that include +@echo spaces for source or build. +@echo. +@echo Otherwise, if the build dir is in a subdir of the source dir, testdata needed +@echo for input and verification should be found automatically when (from the +@echo location of the the built exes) you call RunTest.bat. By default RunTest.bat +@echo runs all tests compatible with the linked pcre library but it can be given +@echo a test number as an argument. +@echo. +@echo If the build dir is not under the source dir you can either copy your exes +@echo to the source folder or copy RunTest.bat and the testdata folder to the +@echo location of your built exes and then run RunTest.bat. +@echo. +goto :eof diff -Nru pcre3-8.12/aclocal.m4 pcre3-8.31/aclocal.m4 --- pcre3-8.12/aclocal.m4 2011-01-15 11:27:55.000000000 +0000 +++ pcre3-8.31/aclocal.m4 2012-07-06 09:01:58.000000000 +0000 @@ -13,8 +13,8 @@ m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],, -[m4_warning([this file was generated for autoconf 2.65. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) @@ -189,10 +189,13 @@ dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our @@ -763,15 +766,12 @@ # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) - _LT_PROG_XSI_SHELLFNS + _LT_PROG_REPLACE_SHELLFNS - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || + mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], @@ -1088,30 +1088,41 @@ fi ]) -# _LT_SYS_MODULE_PATH_AIX -# ----------------------- +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl -AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi ])# _LT_SYS_MODULE_PATH_AIX @@ -1136,7 +1147,7 @@ AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. -if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then @@ -1180,6 +1191,39 @@ ])# _LT_PROG_ECHO_BACKSLASH +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], @@ -1326,14 +1370,47 @@ ])# _LT_ENABLE_LOCK +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], -[AC_CHECK_TOOL(AR, ar, false) -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1]) +[_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: @@ -1673,10 +1750,10 @@ /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -void fnord () __attribute__((visibility("default"))); +int fnord () __attribute__((visibility("default"))); #endif -void fnord () { int i=42; } +int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); @@ -2216,8 +2293,9 @@ need_version=no need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + case $GCC,$cc_basename in + yes,*) + # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ @@ -2250,13 +2328,71 @@ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' ;; *) + # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' ;; esac - dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; @@ -2973,6 +3109,11 @@ esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' @@ -3191,6 +3332,21 @@ ;; esac ]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown @@ -3198,7 +3354,11 @@ _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method == "file_magic"]) + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD @@ -3301,6 +3461,67 @@ dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + # LT_LIB_M # -------- @@ -3427,8 +3648,8 @@ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -3464,6 +3685,7 @@ else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -3497,6 +3719,18 @@ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + #ifdef __cplusplus extern "C" { #endif @@ -3508,7 +3742,7 @@ cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ -const struct { +LT@&t@_DLSYM_CONST struct { const char *name; void *address; } @@ -3534,15 +3768,15 @@ _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi @@ -3575,6 +3809,13 @@ AC_MSG_RESULT(ok) fi +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], @@ -3585,6 +3826,8 @@ _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS @@ -3596,7 +3839,6 @@ _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= -AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then @@ -3701,6 +3943,12 @@ ;; esac ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; dgux*) case $cc_basename in ec++*) @@ -4075,6 +4323,12 @@ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4194,9 +4448,11 @@ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac -AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. @@ -4215,6 +4471,8 @@ _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # @@ -4235,6 +4493,7 @@ m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl @@ -4243,6 +4502,7 @@ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. @@ -4257,15 +4517,20 @@ ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; + ;; cygwin* | mingw* | cegcc*) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; + case $cc_basename in + cl*) ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; + ;; esac - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= @@ -4433,7 +4698,8 @@ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -4481,7 +4747,7 @@ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then - tmp_addflag= + tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler @@ -4551,8 +4817,8 @@ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -4570,8 +4836,8 @@ _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4617,8 +4883,8 @@ *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4748,7 +5014,7 @@ _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. - _LT_SYS_MODULE_PATH_AIX + _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else @@ -4759,7 +5025,7 @@ else # Determine the default libpath from the value encoded in an # empty executable. - _LT_SYS_MODULE_PATH_AIX + _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. @@ -4803,20 +5069,63 @@ # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac ;; darwin* | rhapsody*) @@ -4854,7 +5163,7 @@ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -4862,7 +5171,7 @@ hpux9*) if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi @@ -4878,7 +5187,7 @@ hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi @@ -4902,10 +5211,10 @@ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else @@ -4952,16 +5261,31 @@ irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE(int foo(void) {}, - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - ) - LDFLAGS="$save_LDFLAGS" + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' @@ -5046,7 +5370,7 @@ osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' @@ -5065,9 +5389,9 @@ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) @@ -5339,8 +5663,6 @@ to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [fix_srcfile_path], [1], - [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], @@ -5351,6 +5673,8 @@ [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented @@ -5448,6 +5772,7 @@ m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then @@ -5509,6 +5834,7 @@ # Allow CC to be a program name with arguments. lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX @@ -5526,6 +5852,7 @@ fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) @@ -5547,8 +5874,8 @@ # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' @@ -5689,7 +6016,7 @@ _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. - _LT_SYS_MODULE_PATH_AIX + _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" @@ -5701,7 +6028,7 @@ else # Determine the default libpath from the value encoded in an # empty executable. - _LT_SYS_MODULE_PATH_AIX + _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. @@ -5743,29 +6070,75 @@ ;; cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; @@ -5840,7 +6213,7 @@ ;; *) if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -5911,10 +6284,10 @@ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -5955,9 +6328,9 @@ *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -6235,7 +6608,7 @@ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac @@ -6322,9 +6695,9 @@ if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -6453,6 +6826,7 @@ fi # test -n "$compiler" CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC @@ -6467,6 +6841,29 @@ ])# _LT_LANG_CXX_CONFIG +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose @@ -6475,6 +6872,7 @@ # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= @@ -6525,6 +6923,13 @@ }; _LT_EOF ]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then @@ -6536,7 +6941,7 @@ pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case $p in + case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. @@ -6545,13 +6950,22 @@ test $p = "-R"; then prev=$p continue - else - prev= fi + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) + case ${prev} in + -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. @@ -6571,8 +6985,10 @@ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi + prev= ;; + *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. @@ -6608,6 +7024,7 @@ fi $RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], @@ -6757,7 +7174,9 @@ # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} + CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) @@ -6811,6 +7230,7 @@ GCC=$lt_save_GCC CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP @@ -6887,7 +7307,9 @@ # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} + CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu @@ -6943,7 +7365,8 @@ fi # test -n "$compiler" GCC=$lt_save_GCC - CC="$lt_save_CC" + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP @@ -6980,10 +7403,12 @@ _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. -lt_save_CC="$CC" +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" @@ -7010,7 +7435,8 @@ AC_LANG_RESTORE GCC=$lt_save_GCC -CC="$lt_save_CC" +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG @@ -7045,9 +7471,11 @@ # Allow CC to be a program name with arguments. lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} +CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) @@ -7060,7 +7488,8 @@ GCC=$lt_save_GCC AC_LANG_RESTORE -CC="$lt_save_CC" +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG @@ -7119,6 +7548,15 @@ AC_SUBST([OBJDUMP]) ]) +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) # _LT_DECL_SED # ------------ @@ -7210,8 +7648,8 @@ # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes @@ -7250,209 +7688,165 @@ ])# _LT_CHECK_SHELL_FEATURES -# _LT_PROG_XSI_SHELLFNS -# --------------------- -# Bourne and XSI compatible variants of some useful shell functions. -m4_defun([_LT_PROG_XSI_SHELLFNS], -[case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $[*] )) -} + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) -dnl func_dirname_and_basename -dnl A portable version of this function is already defined in general.m4sh -dnl so there is no need for it here. - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[[^=]]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[[^.]]*$/.lo/'` -} +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$[@]"` -} + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` -} + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi -_LT_EOF -esac +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]+=\$[2]" -} -_LT_EOF +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$[1]=\$$[1]\$[2]" -} - -_LT_EOF + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac ;; - esac + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac ]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # @@ -7951,17 +8345,17 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# Generated from ltversion.in. +# @configure_input@ -# serial 3175 ltversion.m4 +# serial 3293 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.2.10]) -m4_define([LT_PACKAGE_REVISION], [1.3175]) +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3293]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.2.10' -macro_revision='1.3175' +[macro_version='2.4' +macro_revision='1.3293' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) @@ -8852,6 +9246,33 @@ fi AC_MSG_RESULT(yes)]) +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# (`yes' being less verbose, `no' or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation diff -Nru pcre3-8.12/cmake/FindEditline.cmake pcre3-8.31/cmake/FindEditline.cmake --- pcre3-8.12/cmake/FindEditline.cmake 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/cmake/FindEditline.cmake 2012-02-26 17:08:10.000000000 +0000 @@ -0,0 +1,17 @@ +# Modified from FindReadline.cmake (PH Feb 2012) + +if(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) + set(EDITLINE_FOUND TRUE) +else(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) + FIND_PATH(EDITLINE_INCLUDE_DIR readline.h + /usr/include/editline + /usr/include/edit/readline + /usr/include/readline + ) + + FIND_LIBRARY(EDITLINE_LIBRARY NAMES edit) + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY ) + + MARK_AS_ADVANCED(EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY) +endif(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY AND NCURSES_LIBRARY) diff -Nru pcre3-8.12/config-cmake.h.in pcre3-8.31/config-cmake.h.in --- pcre3-8.12/config-cmake.h.in 2008-01-20 19:21:11.000000000 +0000 +++ pcre3-8.31/config-cmake.h.in 2012-02-26 16:53:00.000000000 +0000 @@ -18,7 +18,11 @@ #cmakedefine PCRE_STATIC 1 -#cmakedefine SUPPORT_UTF8 1 +#cmakedefine SUPPORT_PCRE8 1 +#cmakedefine SUPPORT_PCRE16 1 +#cmakedefine SUPPORT_JIT 1 +#cmakedefine SUPPORT_PCREGREP_JIT 1 +#cmakedefine SUPPORT_UTF 1 #cmakedefine SUPPORT_UCP 1 #cmakedefine EBCDIC 1 #cmakedefine BSR_ANYCRLF 1 @@ -29,6 +33,7 @@ #cmakedefine SUPPORT_LIBBZ2 1 #cmakedefine SUPPORT_LIBZ 1 +#cmakedefine SUPPORT_LIBEDIT 1 #cmakedefine SUPPORT_LIBREADLINE 1 #define NEWLINE @NEWLINE@ @@ -36,7 +41,7 @@ #define LINK_SIZE @PCRE_LINK_SIZE@ #define MATCH_LIMIT @PCRE_MATCH_LIMIT@ #define MATCH_LIMIT_RECURSION @PCRE_MATCH_LIMIT_RECURSION@ - +#define PCREGREP_BUFSIZE @PCREGREP_BUFSIZE@ #define MAX_NAME_SIZE 32 #define MAX_NAME_COUNT 10000 diff -Nru pcre3-8.12/config.guess pcre3-8.31/config.guess --- pcre3-8.12/config.guess 2011-01-15 11:28:00.000000000 +0000 +++ pcre3-8.31/config.guess 2012-07-06 09:02:04.000000000 +0000 @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -# Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2010-09-24' +timestamp='2012-02-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -17,9 +17,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -57,8 +55,8 @@ Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -92,7 +90,7 @@ exit 1 fi -trap 'exit 1' HUP INT TERM +trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires @@ -106,7 +104,7 @@ set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || @@ -168,7 +166,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -204,7 +202,7 @@ fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -247,7 +245,7 @@ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on @@ -293,7 +291,10 @@ # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -319,7 +320,7 @@ echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} @@ -418,23 +419,23 @@ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; @@ -504,8 +505,8 @@ echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -518,7 +519,7 @@ else echo i586-dg-dgux${UNAME_RELEASE} fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -618,52 +619,52 @@ 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -754,22 +755,22 @@ exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -793,14 +794,14 @@ exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -812,13 +813,12 @@ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -827,15 +827,18 @@ *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; @@ -881,6 +884,13 @@ i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -890,7 +900,7 @@ EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac + esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -902,20 +912,29 @@ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo cris-axis-linux-${LIBC} + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-${LIBC} + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo frv-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} @@ -949,7 +968,7 @@ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or32:Linux:*:*) - echo or32-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} @@ -975,7 +994,7 @@ echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} @@ -984,16 +1003,16 @@ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-tilera-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1002,11 +1021,11 @@ echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1038,7 +1057,7 @@ fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1066,13 +1085,13 @@ exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp - exit ;; + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1107,8 +1126,8 @@ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ @@ -1151,10 +1170,10 @@ echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1180,11 +1199,11 @@ exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1297,13 +1316,13 @@ echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1321,6 +1340,9 @@ i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1343,11 +1365,11 @@ #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif diff -Nru pcre3-8.12/config.h.generic pcre3-8.31/config.h.generic --- pcre3-8.12/config.h.generic 2011-01-15 17:27:55.000000000 +0000 +++ pcre3-8.31/config.h.generic 2012-07-06 09:55:37.000000000 +0000 @@ -31,8 +31,8 @@ character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define this macro, PCRE - will assume input strings are ASCII or UTF-8 Unicode. It is not possible to - build a version of PCRE that supports both EBCDIC and UTF-8. */ + will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible + to build a version of PCRE that supports both EBCDIC and UTF-8/16. */ /* #undef EBCDIC */ /* Define to 1 if you have the `bcopy' function. */ @@ -58,6 +58,12 @@ #define HAVE_DLFCN_H 1 #endif +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDITLINE_READLINE_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EDIT_READLINE_READLINE_H */ + /* Define to 1 if you have the header file. */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 @@ -84,14 +90,10 @@ #endif /* Define to 1 if you have the header file. */ -#ifndef HAVE_READLINE_HISTORY_H -#define HAVE_READLINE_HISTORY_H 1 -#endif +/* #undef HAVE_READLINE_HISTORY_H */ /* Define to 1 if you have the header file. */ -#ifndef HAVE_READLINE_READLINE_H -#define HAVE_READLINE_READLINE_H 1 -#endif +/* #undef HAVE_READLINE_READLINE_H */ /* Define to 1 if you have the header file. */ #ifndef HAVE_STDINT_H @@ -250,7 +252,7 @@ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE 8.12" +#define PACKAGE_STRING "PCRE 8.31" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -259,7 +261,17 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "8.12" +#define PACKAGE_VERSION "8.31" + +/* 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,10 +305,16 @@ #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 */ +/* Define to allow pcretest to be linked with libedit. */ +/* #undef SUPPORT_LIBEDIT */ + /* Define to allow pcretest to be linked with libreadline. */ /* #undef SUPPORT_LIBREADLINE */ @@ -304,18 +322,29 @@ handle .gz files. */ /* #undef SUPPORT_LIBZ */ -/* Define to enable support for Unicode properties */ +/* Define to enable the 16 bit PCRE library. */ +/* #undef SUPPORT_PCRE16 */ + +/* Define to enable the 8 bit PCRE library. */ +#ifndef SUPPORT_PCRE8 +#define SUPPORT_PCRE8 /**/ +#endif + +/* 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 +/* Define to enable support for the UTF-8/16 Unicode encoding. This will work even in an EBCDIC environment, but it is incompatible with the EBCDIC - macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8, but - not both at once. */ -/* #undef SUPPORT_UTF8 */ + macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, + but not both at once. */ +/* #undef SUPPORT_UTF */ /* Version number of package */ #ifndef VERSION -#define VERSION "8.12" +#define VERSION "8.31" #endif /* Define to empty if `const' does not conform to ANSI C. */ diff -Nru pcre3-8.12/config.h.in pcre3-8.31/config.h.in --- pcre3-8.12/config.h.in 2011-01-15 11:28:00.000000000 +0000 +++ pcre3-8.31/config.h.in 2012-07-06 09:02:03.000000000 +0000 @@ -30,8 +30,8 @@ character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define this macro, PCRE - will assume input strings are ASCII or UTF-8 Unicode. It is not possible to - build a version of PCRE that supports both EBCDIC and UTF-8. */ + will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible + to build a version of PCRE that supports both EBCDIC and UTF-8/16. */ #undef EBCDIC /* Define to 1 if you have the `bcopy' function. */ @@ -49,6 +49,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_EDITLINE_READLINE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EDIT_READLINE_READLINE_H + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H @@ -200,6 +206,14 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* 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. */ +#undef PCREGREP_BUFSIZE + /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition @@ -228,10 +242,16 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* 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 +/* Define to allow pcretest to be linked with libedit. */ +#undef SUPPORT_LIBEDIT + /* Define to allow pcretest to be linked with libreadline. */ #undef SUPPORT_LIBREADLINE @@ -239,14 +259,23 @@ handle .gz files. */ #undef SUPPORT_LIBZ -/* Define to enable support for Unicode properties */ +/* Define to enable the 16 bit PCRE library. */ +#undef SUPPORT_PCRE16 + +/* Define to enable the 8 bit PCRE library. */ +#undef SUPPORT_PCRE8 + +/* 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 +/* Define to enable support for the UTF-8/16 Unicode encoding. This will work even in an EBCDIC environment, but it is incompatible with the EBCDIC - macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8, but - not both at once. */ -#undef SUPPORT_UTF8 + macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, + but not both at once. */ +#undef SUPPORT_UTF /* Version number of package */ #undef VERSION diff -Nru pcre3-8.12/config.sub pcre3-8.31/config.sub --- pcre3-8.12/config.sub 2011-01-15 11:28:00.000000000 +0000 +++ pcre3-8.31/config.sub 2012-07-06 09:02:04.000000000 +0000 @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -# Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2010-09-11' +timestamp='2012-02-10' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -21,9 +21,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -76,8 +74,8 @@ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free -Software Foundation, Inc. +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -132,6 +130,10 @@ os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -158,8 +160,8 @@ os= basic_machine=$1 ;; - -bluegene*) - os=-cnk + -bluegene*) + os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= @@ -175,10 +177,10 @@ os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; @@ -247,17 +249,22 @@ # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx | dvp \ + | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ @@ -286,22 +293,23 @@ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ + | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | rx \ + | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; @@ -314,8 +322,7 @@ c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -325,6 +332,21 @@ basic_machine=mt-unknown ;; + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. @@ -339,11 +361,13 @@ # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ @@ -352,8 +376,10 @@ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ @@ -382,24 +408,26 @@ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* | rx-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ + | tile*-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | vax-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) @@ -424,7 +452,7 @@ basic_machine=a29k-amd os=-udi ;; - abacus) + abacus) basic_machine=abacus-unknown ;; adobe68k) @@ -507,7 +535,7 @@ basic_machine=c90-cray os=-unicos ;; - cegcc) + cegcc) basic_machine=arm-unknown os=-cegcc ;; @@ -539,7 +567,7 @@ basic_machine=craynv-cray os=-unicosmp ;; - cr16) + cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; @@ -697,7 +725,6 @@ i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -755,7 +782,7 @@ basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze) basic_machine=microblaze-xilinx ;; mingw32) @@ -812,10 +839,18 @@ ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -880,10 +915,10 @@ np1) basic_machine=np1-gould ;; - neo-tandem) + neo-tandem) basic_machine=neo-tandem ;; - nse-tandem) + nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) @@ -968,9 +1003,10 @@ ;; power) basic_machine=power-ibm ;; - ppc) basic_machine=powerpc-unknown + ppc | ppcbe) basic_machine=powerpc-unknown ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown @@ -1064,6 +1100,9 @@ basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -1120,13 +1159,8 @@ basic_machine=t90-cray os=-unicos ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1196,6 +1230,9 @@ xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos @@ -1293,11 +1330,11 @@ if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + -auroraux) + os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` @@ -1333,7 +1370,7 @@ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ @@ -1382,7 +1419,7 @@ -opened*) os=-openedition ;; - -os400*) + -os400*) os=-os400 ;; -wince*) @@ -1431,7 +1468,7 @@ -sinix*) os=-sysv4 ;; - -tpf*) + -tpf*) os=-tpf ;; -triton*) @@ -1476,8 +1513,8 @@ -dicos*) os=-dicos ;; - -nacl*) - ;; + -nacl*) + ;; -none) ;; *) @@ -1500,10 +1537,10 @@ # system, and we'll never get to this point. case $basic_machine in - score-*) + score-*) os=-elf ;; - spu-*) + spu-*) os=-elf ;; *-acorn) @@ -1515,8 +1552,8 @@ arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff + c4x-* | tic4x-*) + os=-coff ;; tic54x-*) os=-coff @@ -1545,14 +1582,11 @@ ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout ;; - mep-*) + mep-*) os=-elf ;; mips*-cisco) @@ -1579,7 +1613,7 @@ *-ibm) os=-aix ;; - *-knuth) + *-knuth) os=-mmixware ;; *-wec) diff -Nru pcre3-8.12/configure pcre3-8.31/configure --- pcre3-8.12/configure 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/configure 2012-07-06 09:02:02.000000000 +0000 @@ -1,11 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for PCRE 8.12. +# Generated by GNU Autoconf 2.68 for PCRE 8.31. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -89,6 +89,7 @@ IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -222,11 +223,18 @@ # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -324,7 +332,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -364,19 +372,19 @@ fi # as_fn_arith -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -540,7 +548,7 @@ exec 6>&1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -559,8 +567,8 @@ # Identity of this package. PACKAGE_NAME='PCRE' PACKAGE_TARNAME='pcre' -PACKAGE_VERSION='8.12' -PACKAGE_STRING='PCRE 8.12' +PACKAGE_VERSION='8.31' +PACKAGE_STRING='PCRE 8.31' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -605,23 +613,34 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -LIBREADLINE LIBBZ2 LIBZ DISTCHECK_CONFIGURE_FLAGS EXTRA_LIBPCRECPP_LDFLAGS EXTRA_LIBPCREPOSIX_LDFLAGS +EXTRA_LIBPCRE16_LDFLAGS EXTRA_LIBPCRE_LDFLAGS PCRE_STATIC_CFLAG +LIBREADLINE +WITH_UTF_FALSE +WITH_UTF_TRUE +WITH_JIT_FALSE +WITH_JIT_TRUE WITH_REBUILD_CHARTABLES_FALSE WITH_REBUILD_CHARTABLES_TRUE WITH_PCRE_CPP_FALSE WITH_PCRE_CPP_TRUE +WITH_PCRE16_FALSE +WITH_PCRE16_TRUE +WITH_PCRE8_FALSE +WITH_PCRE8_TRUE pcre_have_bits_type_traits pcre_have_type_traits pcre_have_ulong_long pcre_have_long_long enable_cpp +enable_pcre16 +enable_pcre8 PCRE_DATE PCRE_PRERELEASE PCRE_MINOR @@ -632,7 +651,9 @@ LIPO NMEDIT DSYMUTIL +MANIFEST_TOOL RANLIB +ac_ct_AR AR LN_S NM @@ -678,6 +699,8 @@ LDFLAGS CFLAGS CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY am__untar am__tar AMTAR @@ -742,16 +765,23 @@ ac_subst_files='' ac_user_opts=' enable_option_checking +enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld +with_sysroot enable_libtool_lock +enable_pcre8 +enable_pcre16 enable_cpp +enable_jit +enable_pcregrep_jit enable_rebuild_chartables enable_utf8 +enable_utf enable_unicode_properties enable_newline_is_cr enable_newline_is_lf @@ -763,6 +793,8 @@ enable_stack_for_recursion enable_pcregrep_libz enable_pcregrep_libbz2 +with_pcregrep_bufsize +enable_pcretest_libedit enable_pcretest_libreadline with_posix_malloc_threshold with_link_size @@ -844,8 +876,9 @@ fi case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -890,7 +923,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -916,7 +949,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1120,7 +1153,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1136,7 +1169,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1166,8 +1199,8 @@ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information." + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) @@ -1175,7 +1208,7 @@ # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1185,7 +1218,7 @@ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1193,13 +1226,13 @@ if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" + as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1222,7 +1255,7 @@ [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1236,8 +1269,8 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1252,9 +1285,9 @@ ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error "working directory cannot be determined" + as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error "pwd does not report name of working directory" + as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1293,11 +1326,11 @@ fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1323,7 +1356,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCRE 8.12 to adapt to many kinds of systems. +\`configure' configures PCRE 8.31 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1337,7 +1370,7 @@ --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1393,7 +1426,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCRE 8.12:";; + short | recursive ) echo "Configuration of PCRE 8.31:";; esac cat <<\_ACEOF @@ -1401,6 +1434,8 @@ --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0') --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] @@ -1408,14 +1443,20 @@ --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) + --disable-pcre8 disable 8 bit character support + --enable-pcre16 enable 16 bit character support --disable-cpp disable C++ support + --enable-jit enable Just-In-Time compiling support + --disable-pcregrep-jit disable JIT support in pcregrep --enable-rebuild-chartables rebuild character tables in current locale - --enable-utf8 enable UTF-8 support (incompatible with + --enable-utf8 another name for --enable-utf. Kept only for + compatibility reasons + --enable-utf enable UTF-8/16 support (incompatible with --enable-ebcdic) --enable-unicode-properties enable Unicode properties support (implies - --enable-utf8) + --enable-utf) --enable-newline-is-cr use CR as newline character --enable-newline-is-lf use LF as newline character (default) --enable-newline-is-crlf @@ -1425,13 +1466,15 @@ --enable-newline-is-any use any valid Unicode newline sequence --enable-bsr-anycrlf \R matches only CR, LF, CRLF by default --enable-ebcdic assume EBCDIC coding rather than ASCII; incompatible - with --enable-utf8; use only in (uncommon) EBCDIC + with --enable-utf; use only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables --disable-stack-for-recursion don't use stack recursion when matching --enable-pcregrep-libz link pcregrep with libz to handle .gz files --enable-pcregrep-libbz2 link pcregrep with libbz2 to handle .bz2 files + --enable-pcretest-libedit + link pcretest with libedit --enable-pcretest-libreadline link pcretest with libreadline @@ -1441,6 +1484,10 @@ --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-pcregrep-bufsize=N + pcregrep buffer size (default=20480) --with-posix-malloc-threshold=NBYTES threshold for POSIX malloc usage (default=10) --with-link-size=N internal link size (2, 3, or 4 allowed; default=2) @@ -1528,10 +1575,10 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCRE configure 8.12 -generated by GNU Autoconf 2.65 +PCRE configure 8.31 +generated by GNU Autoconf 2.68 -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1575,7 +1622,7 @@ ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1613,7 +1660,7 @@ ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -1639,7 +1686,7 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { + test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1650,7 +1697,7 @@ ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -1692,7 +1739,7 @@ ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run @@ -1706,7 +1753,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1724,7 +1771,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile @@ -1737,7 +1784,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1788,8 +1835,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - eval as_val=\$$3 - if test "x$as_val" = x""no; then : + if eval test \"x\$"$3"\" = x"no"; then : else break @@ -1799,7 +1845,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_intX_t @@ -1844,7 +1890,7 @@ # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link @@ -1857,7 +1903,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1912,7 +1958,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func @@ -1937,7 +1983,7 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { + test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : @@ -1948,7 +1994,7 @@ ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -1994,7 +2040,7 @@ # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2007,10 +2053,10 @@ ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2046,7 +2092,7 @@ else ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -2073,7 +2119,7 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2082,7 +2128,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel @@ -2094,10 +2140,10 @@ ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2133,7 +2179,7 @@ else ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -2160,7 +2206,7 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2169,7 +2215,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel @@ -2182,7 +2228,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -2223,7 +2269,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type @@ -2236,7 +2282,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -2277,15 +2323,15 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCRE $as_me 8.12, which was -generated by GNU Autoconf 2.65. Invocation command line was +It was created by PCRE $as_me 8.31, which was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2395,11 +2441,9 @@ { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( @@ -2433,11 +2477,9 @@ ) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do @@ -2450,11 +2492,9 @@ echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## + $as_echo "## ------------------- ## ## File substitutions. ## -## ------------------- ## -_ASBOX +## ------------------- ##" echo for ac_var in $ac_subst_files do @@ -2468,11 +2508,9 @@ fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo cat confdefs.h echo @@ -2527,7 +2565,12 @@ ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2542,7 +2585,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } fi done @@ -2618,7 +2665,7 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2636,16 +2683,22 @@ ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - for ac_t in install-sh install.sh shtool; do - if test -f "$ac_dir/$ac_t"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/$ac_t -c" - break 2 - fi - done + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi done if test -z "$ac_aux_dir"; then - as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2674,7 +2727,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : +if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2761,11 +2814,11 @@ ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's @@ -2787,7 +2840,7 @@ # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". - as_fn_error "ls -t appears to fail. Make sure there is not a broken + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi @@ -2797,7 +2850,7 @@ # Ok. : else - as_fn_error "newly created file is older than distributed files! + as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -2851,7 +2904,7 @@ set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -2891,7 +2944,7 @@ set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -2944,7 +2997,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then - if test "${ac_cv_path_mkdir+set}" = set; then : + if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2995,7 +3048,7 @@ set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -3035,7 +3088,7 @@ $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF @@ -3043,7 +3096,7 @@ all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; @@ -3077,7 +3130,7 @@ am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then - as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi @@ -3093,7 +3146,7 @@ # Define the identity of the package. PACKAGE='pcre' - VERSION='8.12' + VERSION='8.31' cat >>confdefs.h <<_ACEOF @@ -3133,6 +3186,18 @@ +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; +esac +AM_BACKSLASH='\' + ac_config_headers="$ac_config_headers config.h" @@ -3162,7 +3227,7 @@ set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -3202,7 +3267,7 @@ set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -3255,7 +3320,7 @@ set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -3295,7 +3360,7 @@ set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -3354,7 +3419,7 @@ set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -3398,7 +3463,7 @@ set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -3452,8 +3517,8 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "no acceptable C compiler found in \$PATH -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -3567,9 +3632,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "C compiler cannot create executables -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3611,8 +3675,8 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3669,9 +3733,9 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. +as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5; } fi fi fi @@ -3682,7 +3746,7 @@ ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3722,8 +3786,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of object files: cannot compile -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -3733,7 +3797,7 @@ ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3770,7 +3834,7 @@ ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -3848,7 +3912,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -4009,7 +4073,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : +if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then @@ -4148,7 +4212,7 @@ set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then : +if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -4192,7 +4256,7 @@ set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -4270,7 +4334,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4307,7 +4371,7 @@ ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then : +if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -4393,7 +4457,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then @@ -4586,7 +4650,7 @@ CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -4616,7 +4680,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4632,11 +4696,11 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4675,7 +4739,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4691,18 +4755,18 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c @@ -4714,7 +4778,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -4763,7 +4827,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP @@ -4777,7 +4841,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -4829,7 +4893,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP @@ -4844,7 +4908,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4961,8 +5025,7 @@ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -4987,27 +5050,27 @@ # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && - as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -5025,14 +5088,14 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi @@ -5040,7 +5103,7 @@ $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -5065,7 +5128,7 @@ set dummy ${ac_tool_prefix}as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AS+set}" = set; then : +if ${ac_cv_prog_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AS"; then @@ -5105,7 +5168,7 @@ set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AS+set}" = set; then : +if ${ac_cv_prog_ac_ct_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AS"; then @@ -5157,7 +5220,7 @@ set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DLLTOOL+set}" = set; then : +if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then @@ -5197,7 +5260,7 @@ set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then : +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then @@ -5249,7 +5312,7 @@ set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -5289,7 +5352,7 @@ set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -5367,8 +5430,8 @@ -macro_version='2.2.10' -macro_revision='1.3175' +macro_version='2.4' +macro_revision='1.3293' @@ -5408,7 +5471,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. -if test "X`print -r -- -n 2>/dev/null`" = X-n && \ +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then @@ -5455,7 +5518,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -5510,7 +5573,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then - as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED @@ -5537,7 +5600,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -5589,7 +5652,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then - as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP @@ -5668,7 +5731,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi -if test "${lt_cv_path_LD+set}" = set; then : +if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then @@ -5705,10 +5768,10 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if test "${lt_cv_prog_gnu_ld+set}" = set; then : +if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. @@ -5735,7 +5798,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if test "${lt_cv_path_NM+set}" = set; then : +if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -5798,7 +5861,7 @@ set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -5842,7 +5905,7 @@ set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then @@ -5914,7 +5977,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } -if test "${lt_cv_nm_interface+set}" = set; then : +if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" @@ -5949,7 +6012,7 @@ # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } -if test "${lt_cv_sys_max_cmd_len+set}" = set; then : +if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 @@ -6094,8 +6157,8 @@ # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes @@ -6144,9 +6207,83 @@ +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } -if test "${lt_cv_ld_reload_flag+set}" = set; then : +if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' @@ -6160,6 +6297,11 @@ esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' @@ -6182,7 +6324,7 @@ set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -6222,7 +6364,7 @@ set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -6278,7 +6420,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } -if test "${lt_cv_deplibs_check_method+set}" = set; then : +if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' @@ -6480,6 +6622,21 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown @@ -6495,12 +6652,162 @@ + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -6513,7 +6820,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AR="${ac_tool_prefix}ar" + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -6533,14 +6840,18 @@ fi + test -n "$AR" && break + done fi -if test -z "$ac_cv_prog_AR"; then +if test -z "$AR"; then ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -6553,7 +6864,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_AR="ar" + ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -6572,6 +6883,10 @@ $as_echo "no" >&6; } fi + + test -n "$ac_ct_AR" && break +done + if test "x$ac_ct_AR" = x; then AR="false" else @@ -6583,16 +6898,72 @@ esac AR=$ac_ct_AR fi -else - AR="$ac_cv_prog_AR" fi -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi @@ -6605,7 +6976,7 @@ set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -6645,7 +7016,7 @@ set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -6704,7 +7075,7 @@ set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then : +if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then @@ -6744,7 +7115,7 @@ set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then @@ -6873,7 +7244,7 @@ # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : +if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else @@ -6934,8 +7305,8 @@ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -6971,6 +7342,7 @@ else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -7012,6 +7384,18 @@ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + #ifdef __cplusplus extern "C" { #endif @@ -7023,7 +7407,7 @@ cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ -const struct { +LT_DLSYM_CONST struct { const char *name; void *address; } @@ -7049,8 +7433,8 @@ _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 @@ -7060,8 +7444,8 @@ test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi @@ -7098,6 +7482,12 @@ $as_echo "ok" >&6; } fi +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi @@ -7119,9 +7509,52 @@ -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes @@ -7244,7 +7677,7 @@ CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if test "${lt_cv_cc_needs_belf+set}" = set; then : +if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c @@ -7312,6 +7745,123 @@ need_locks="$enable_libtool_lock" +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + case $host_os in rhapsody* | darwin*) @@ -7320,7 +7870,7 @@ set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : +if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then @@ -7360,7 +7910,7 @@ set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then @@ -7412,7 +7962,7 @@ set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NMEDIT+set}" = set; then : +if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then @@ -7452,7 +8002,7 @@ set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then @@ -7504,7 +8054,7 @@ set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_LIPO+set}" = set; then : +if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then @@ -7544,7 +8094,7 @@ set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then @@ -7596,7 +8146,7 @@ set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL+set}" = set; then : +if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then @@ -7636,7 +8186,7 @@ set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then @@ -7688,7 +8238,7 @@ set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OTOOL64+set}" = set; then : +if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then @@ -7728,7 +8278,7 @@ set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then @@ -7803,7 +8353,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } -if test "${lt_cv_apple_cc_single_mod+set}" = set; then : +if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no @@ -7832,7 +8382,7 @@ $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : +if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no @@ -7864,7 +8414,7 @@ $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } -if test "${lt_cv_ld_force_load+set}" = set; then : +if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no @@ -7933,7 +8483,7 @@ do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " -if test "x$ac_cv_header_dlfcn_h" = x""yes; then : +if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF @@ -7944,6 +8494,16 @@ +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + # Set options @@ -8118,7 +8678,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } -if test "${lt_cv_objdir+set}" = set; then : +if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null @@ -8196,7 +8756,7 @@ if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -8262,7 +8822,7 @@ if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } -if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : +if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in @@ -8400,7 +8960,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no @@ -8453,8 +9013,6 @@ lt_prog_compiler_pic= lt_prog_compiler_static= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' @@ -8619,6 +9177,12 @@ lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -8738,13 +9302,17 @@ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 -$as_echo "$lt_prog_compiler_pic" >&6; } - - - - +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. @@ -8752,7 +9320,7 @@ if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : +if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no @@ -8805,13 +9373,18 @@ + + + + + # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if test "${lt_cv_prog_compiler_static_works+set}" = set; then : +if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no @@ -8854,7 +9427,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -8909,7 +9482,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o+set}" = set; then : +if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no @@ -9155,7 +9728,8 @@ allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -9203,7 +9777,7 @@ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then - tmp_addflag= + tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler @@ -9273,8 +9847,8 @@ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -9292,8 +9866,8 @@ _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9339,8 +9913,8 @@ *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9470,7 +10044,13 @@ allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -9483,22 +10063,29 @@ _ACEOF if ac_fn_c_try_link "$LINENO"; then : -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" @@ -9510,7 +10097,13 @@ else # Determine the default libpath from the value encoded in an # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -9523,22 +10116,29 @@ _ACEOF if ac_fn_c_try_link "$LINENO"; then : -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, @@ -9583,20 +10183,63 @@ # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes=yes + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac ;; darwin* | rhapsody*) @@ -9661,7 +10304,7 @@ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no @@ -9669,7 +10312,7 @@ hpux9*) if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi @@ -9685,7 +10328,7 @@ hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi @@ -9709,10 +10352,10 @@ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else @@ -9729,7 +10372,7 @@ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } -if test "${lt_cv_prog_compiler__b+set}" = set; then : +if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no @@ -9791,23 +10434,36 @@ irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int foo(void) {} +int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' @@ -9892,7 +10548,7 @@ osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' @@ -9911,9 +10567,9 @@ no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' - archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) @@ -10101,7 +10757,7 @@ # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : +if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* @@ -10489,8 +11145,9 @@ need_version=no need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + case $GCC,$cc_basename in + yes,*) + # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ @@ -10523,13 +11180,71 @@ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' ;; *) + # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' ;; esac - dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; @@ -10756,7 +11471,7 @@ shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH - if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no @@ -11176,7 +11891,7 @@ # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11210,7 +11925,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else @@ -11224,12 +11939,12 @@ *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = x""yes; then : +if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } -if test "${ac_cv_lib_dld_shl_load+set}" = set; then : +if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11263,16 +11978,16 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = x""yes; then : +if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11306,12 +12021,12 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } -if test "${ac_cv_lib_svld_dlopen+set}" = set; then : +if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11345,12 +12060,12 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } -if test "${ac_cv_lib_dld_dld_link+set}" = set; then : +if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11384,7 +12099,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi @@ -11425,7 +12140,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self+set}" = set; then : +if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -11478,10 +12193,10 @@ /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -void fnord () __attribute__((visibility("default"))); +int fnord () __attribute__((visibility("default"))); #endif -void fnord () { int i=42; } +int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); @@ -11531,7 +12246,7 @@ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if test "${lt_cv_dlopen_self_static+set}" = set; then : +if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -11584,10 +12299,10 @@ /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -void fnord () __attribute__((visibility("default"))); +int fnord () __attribute__((visibility("default"))); #endif -void fnord () { int i=42; } +int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); @@ -11768,7 +12483,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then : + if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -11798,7 +12513,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -11814,11 +12529,11 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -11857,7 +12572,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -11873,18 +12588,18 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c @@ -11979,6 +12694,7 @@ # Allow CC to be a program name with arguments. lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX @@ -11996,6 +12712,7 @@ fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do @@ -12069,7 +12786,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi -if test "${lt_cv_path_LD+set}" = set; then : +if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then @@ -12106,10 +12823,10 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if test "${lt_cv_prog_gnu_ld+set}" = set; then : +if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. @@ -12135,8 +12852,8 @@ # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' @@ -12278,7 +12995,13 @@ allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -12291,22 +13014,29 @@ _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" @@ -12319,7 +13049,13 @@ else # Determine the default libpath from the value encoded in an # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -12332,22 +13068,29 @@ _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, @@ -12390,29 +13133,75 @@ ;; cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_CXX='-L$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=no - enable_shared_with_static_runtimes_CXX=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs_CXX=no - fi - ;; + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; darwin* | rhapsody*) @@ -12518,7 +13307,7 @@ ;; *) if test "$GXX" = yes; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -12589,10 +13378,10 @@ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -12633,9 +13422,9 @@ *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes @@ -12913,7 +13702,7 @@ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac @@ -13000,9 +13789,9 @@ if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -13137,6 +13926,13 @@ }; _LT_EOF + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +esac + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -13150,7 +13946,7 @@ pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case $p in + case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. @@ -13159,13 +13955,22 @@ test $p = "-R"; then prev=$p continue - else - prev= fi + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) + case ${prev} in + -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. @@ -13185,8 +13990,10 @@ postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi + prev= ;; + *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. @@ -13222,6 +14029,7 @@ fi $RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in @@ -13322,8 +14130,6 @@ lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then @@ -13427,6 +14233,11 @@ ;; esac ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; dgux*) case $cc_basename in ec++*) @@ -13644,10 +14455,17 @@ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 -$as_echo "$lt_prog_compiler_pic_CXX" >&6; } - +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. @@ -13655,7 +14473,7 @@ if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } -if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then : +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no @@ -13705,13 +14523,15 @@ + + # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then : +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no @@ -13751,7 +14571,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no @@ -13803,7 +14623,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no @@ -13882,6 +14702,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. @@ -13896,15 +14717,20 @@ ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" - ;; + ;; cygwin* | mingw* | cegcc*) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - ;; + case $cc_basename in + cl*) ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; + ;; esac - exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } @@ -13936,7 +14762,7 @@ # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if test "${lt_cv_archive_cmds_need_lc_CXX+set}" = set; then : +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* @@ -14167,8 +14993,9 @@ need_version=no need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + case $GCC,$cc_basename in + yes,*) + # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ @@ -14200,13 +15027,71 @@ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' ;; *) + # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' ;; esac - dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; @@ -14432,7 +15317,7 @@ shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH - if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no @@ -14773,6 +15658,7 @@ fi # test -n "$compiler" CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC @@ -14822,9 +15708,9 @@ PCRE_MAJOR="8" -PCRE_MINOR="12" +PCRE_MINOR="31" PCRE_PRERELEASE="" -PCRE_DATE="2011-01-15" +PCRE_DATE="2012-07-06" if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" then @@ -14846,16 +15732,54 @@ htmldir='${docdir}/html' fi +# Handle --disable-pcre8 (enabled by default) +# Check whether --enable-pcre8 was given. +if test "${enable_pcre8+set}" = set; then : + enableval=$enable_pcre8; +else + enable_pcre8=unset +fi + + + +# Handle --enable-pcre16 (disabled by default) +# Check whether --enable-pcre16 was given. +if test "${enable_pcre16+set}" = set; then : + enableval=$enable_pcre16; +else + enable_pcre16=unset +fi + + + # Handle --disable-cpp. The substitution of enable_cpp is needed for use in # pcre-config. # Check whether --enable-cpp was given. if test "${enable_cpp+set}" = set; then : enableval=$enable_cpp; else - enable_cpp=yes + enable_cpp=unset +fi + + + +# Handle --enable-jit (disabled by default) +# Check whether --enable-jit was given. +if test "${enable_jit+set}" = set; then : + enableval=$enable_jit; +else + enable_jit=no fi +# Handle --disable-pcregrep-jit (enabled by default) +# Check whether --enable-pcregrep-jit was given. +if test "${enable_pcregrep_jit+set}" = set; then : + enableval=$enable_pcregrep_jit; +else + enable_pcregrep_jit=yes +fi + # Handle --enable-rebuild-chartables # Check whether --enable-rebuild-chartables was given. @@ -14875,6 +15799,15 @@ fi +# Handle --enable-utf (disabled by default) +# Check whether --enable-utf was given. +if test "${enable_utf+set}" = set; then : + enableval=$enable_utf; +else + enable_utf=unset +fi + + # Handle --enable-unicode-properties # Check whether --enable-unicode-properties was given. if test "${enable_unicode_properties+set}" = set; then : @@ -14960,6 +15893,25 @@ fi +# Handle --with-pcregrep-bufsize=N + +# Check whether --with-pcregrep-bufsize was given. +if test "${with_pcregrep_bufsize+set}" = set; then : + withval=$with_pcregrep_bufsize; +else + with_pcregrep_bufsize=20480 +fi + + +# Handle --enable-pcretest-libedit +# Check whether --enable-pcretest-libedit was given. +if test "${enable_pcretest_libedit+set}" = set; then : + enableval=$enable_pcretest_libedit; +else + enable_pcretest_libedit=no +fi + + # Handle --enable-pcretest-libreadline # Check whether --enable-pcretest-libreadline was given. if test "${enable_pcretest_libreadline+set}" = set; then : @@ -15016,34 +15968,76 @@ fi -# Make sure that if enable_unicode_properties was set, that UTF-8 support -# is enabled. -# +# Copy enable_utf8 value to enable_utf for compatibility reasons +if test "x$enable_utf8" != "xunset" +then + if test "x$enable_utf" != "xunset" + then + as_fn_error $? "--enable/disable-utf8 is kept only for compatibility reasons and its value is copied to --enable/disable-utf. Newer code must use --enable/disable-utf alone." "$LINENO" 5 + fi + enable_utf=$enable_utf8 +fi + +# Set the default value for pcre8 +if test "x$enable_pcre8" = "xunset" +then + enable_pcre8=yes +fi + +# Set the default value for pcre16 +if test "x$enable_pcre16" = "xunset" +then + enable_pcre16=no +fi + +# Make sure enable_pcre8 or enable_pcre16 was set +if test "x$enable_pcre8$enable_pcre16" = "xnono" +then + as_fn_error $? "Either 8 or 16 bit (or both) pcre library must be enabled" "$LINENO" 5 +fi + +# Make sure that if enable_unicode_properties was set, that UTF support is enabled. if test "x$enable_unicode_properties" = "xyes" then - if test "x$enable_utf8" = "xno" + if test "x$enable_utf" = "xno" then - as_fn_error "support for Unicode properties requires UTF-8 support" "$LINENO" 5 + as_fn_error $? "support for Unicode properties requires UTF-8/16 support" "$LINENO" 5 fi - enable_utf8=yes + enable_utf=yes +fi + +# enable_utf is disabled by default. +if test "x$enable_utf" = "xunset" +then + enable_utf=no +fi + +# enable_cpp copies the value of enable_pcre8 by default +if test "x$enable_cpp" = "xunset" +then + enable_cpp=$enable_pcre8 fi -if test "x$enable_utf8" = "xunset" +# Make sure that if enable_cpp was set, that enable_pcre8 support is enabled +if test "x$enable_cpp" = "xyes" then - enable_utf8=no + if test "x$enable_pcre8" = "xno" + then + as_fn_error $? "C++ library requires pcre library with 8 bit characters" "$LINENO" 5 + fi fi # Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. -# Also check that UTF-8 support is not requested, because PCRE cannot handle -# EBCDIC and UTF-8 in the same build. To do so it would need to use different +# Also check that UTF support is not requested, because PCRE cannot handle +# EBCDIC and UTF in the same build. To do so it would need to use different # character constants depending on the mode. # if test "x$enable_ebcdic" = "xyes" then enable_rebuild_chartables=yes - if test "x$enable_utf8" = "xyes" + if test "x$enable_utf" = "xyes" then - as_fn_error "support for EBCDIC and UTF-8 cannot be enabled at the same time" "$LINENO" 5 + as_fn_error $? "support for EBCDIC and UTF-8/16 cannot be enabled at the same time" "$LINENO" 5 fi fi @@ -15055,7 +16049,7 @@ anycrlf) ac_pcre_newline_value=-2 ;; any) ac_pcre_newline_value=-1 ;; *) - as_fn_error "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5 + as_fn_error $? "invalid argument \"$enable_newline\" to --enable-newline option" "$LINENO" 5 ;; esac @@ -15063,7 +16057,7 @@ case "$with_link_size" in 2|3|4) ;; *) - as_fn_error "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 + as_fn_error $? "invalid argument \"$with_link_size\" to --with-link-size option" "$LINENO" 5 ;; esac @@ -15072,7 +16066,7 @@ # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -15186,8 +16180,7 @@ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -15257,7 +16250,7 @@ for ac_header in string do : ac_fn_cxx_check_header_mongrel "$LINENO" "string" "ac_cv_header_string" "$ac_includes_default" -if test "x$ac_cv_header_string" = x""yes; then : +if test "x$ac_cv_header_string" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRING 1 _ACEOF @@ -15271,7 +16264,7 @@ for ac_header in bits/type_traits.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "bits/type_traits.h" "ac_cv_header_bits_type_traits_h" "$ac_includes_default" -if test "x$ac_cv_header_bits_type_traits_h" = x""yes; then : +if test "x$ac_cv_header_bits_type_traits_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BITS_TYPE_TRAITS_H 1 _ACEOF @@ -15285,7 +16278,7 @@ for ac_header in type_traits.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "type_traits.h" "ac_cv_header_type_traits_h" "$ac_includes_default" -if test "x$ac_cv_header_type_traits_h" = x""yes; then : +if test "x$ac_cv_header_type_traits_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TYPE_TRAITS_H 1 _ACEOF @@ -15347,7 +16340,7 @@ if test "$have_strto_fn" = 1; then ac_fn_cxx_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" -if test "x$ac_cv_type_long_long" = x""yes; then : +if test "x$ac_cv_type_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LONG_LONG 1 @@ -15359,7 +16352,7 @@ fi ac_fn_cxx_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$ac_includes_default" -if test "x$ac_cv_type_unsigned_long_long" = x""yes; then : +if test "x$ac_cv_type_unsigned_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNSIGNED_LONG_LONG 1 @@ -15389,6 +16382,22 @@ # Conditional compilation + if test "x$enable_pcre8" = "xyes"; then + WITH_PCRE8_TRUE= + WITH_PCRE8_FALSE='#' +else + WITH_PCRE8_TRUE='#' + WITH_PCRE8_FALSE= +fi + + if test "x$enable_pcre16" = "xyes"; then + WITH_PCRE16_TRUE= + WITH_PCRE16_FALSE='#' +else + WITH_PCRE16_TRUE='#' + WITH_PCRE16_FALSE= +fi + if test "x$enable_cpp" = "xyes"; then WITH_PCRE_CPP_TRUE= WITH_PCRE_CPP_FALSE='#' @@ -15405,12 +16414,28 @@ WITH_REBUILD_CHARTABLES_FALSE= fi + if test "x$enable_jit" = "xyes"; then + WITH_JIT_TRUE= + WITH_JIT_FALSE='#' +else + WITH_JIT_TRUE='#' + WITH_JIT_FALSE= +fi + + if test "x$enable_utf" = "xyes"; then + WITH_UTF_TRUE= + WITH_UTF_FALSE='#' +else + WITH_UTF_TRUE='#' + WITH_UTF_FALSE= +fi + # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if test "${ac_cv_c_const+set}" = set; then : +if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -15489,7 +16514,7 @@ fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = x""yes; then : +if test "x$ac_cv_type_size_t" = xyes; then : else @@ -15506,8 +16531,7 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -15521,7 +16545,7 @@ for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = x""yes; then : +if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF @@ -15532,7 +16556,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 $as_echo_n "checking for gzopen in -lz... " >&6; } -if test "${ac_cv_lib_z_gzopen+set}" = set; then : +if ${ac_cv_lib_z_gzopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -15566,7 +16590,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 $as_echo "$ac_cv_lib_z_gzopen" >&6; } -if test "x$ac_cv_lib_z_gzopen" = x""yes; then : +if test "x$ac_cv_lib_z_gzopen" = xyes; then : HAVE_LIBZ=1 fi @@ -15590,7 +16614,7 @@ for ac_header in bzlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = x""yes; then : +if test "x$ac_cv_header_bzlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BZLIB_H 1 _ACEOF @@ -15635,10 +16659,11 @@ # Check for the availabiity of libreadline -for ac_header in readline/readline.h +if test "$enable_pcretest_libreadline" = "yes"; then + for ac_header in readline/readline.h do : ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_readline_h" = x""yes; then : +if test "x$ac_cv_header_readline_readline_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE_READLINE_H 1 _ACEOF @@ -15647,10 +16672,10 @@ done -for ac_header in readline/history.h + for ac_header in readline/history.h do : ac_fn_c_check_header_mongrel "$LINENO" "readline/history.h" "ac_cv_header_readline_history_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_history_h" = x""yes; then : +if test "x$ac_cv_header_readline_history_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_READLINE_HISTORY_H 1 _ACEOF @@ -15659,9 +16684,9 @@ done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 $as_echo_n "checking for readline in -lreadline... " >&6; } -if test "${ac_cv_lib_readline_readline+set}" = set; then : +if ${ac_cv_lib_readline_readline+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -15695,10 +16720,315 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 $as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = x""yes; then : - HAVE_LIB_READLINE=1 +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lreadline" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-ltinfo" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lcurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lcurses" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lncurses" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-lncursesw" +else + unset ac_cv_lib_readline_readline; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline -ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + LIBREADLINE="-ltermcap" +else + LIBREADLINE="" +fi + +fi + +fi + +fi + +fi + +fi + + + if test -n "$LIBREADLINE"; then + if test "$LIBREADLINE" != "-lreadline"; then + echo "-lreadline needs $LIBREADLINE" + LIBREADLINE="-lreadline $LIBREADLINE" + fi + fi +fi + + +# Check for the availability of libedit. Different distributions put its +# headers in different places. Try to cover the most common ones. + +if test "$enable_pcretest_libedit" = "yes"; then + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDITLINE_READLINE_H 1 +_ACEOF + HAVE_EDITLINE_READLINE_H=1 +else + for ac_header in edit/readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "edit/readline/readline.h" "ac_cv_header_edit_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_edit_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDIT_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_READLINE_H=1 +else + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + HAVE_READLINE_READLINE_H=1 +fi + +done + +fi + +done + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +$as_echo_n "checking for readline in -ledit... " >&6; } +if ${ac_cv_lib_edit_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_edit_readline=yes +else + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +$as_echo "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes; then : + LIBEDIT="-ledit" fi +fi # This facilitates -ansi builds under Linux @@ -15713,9 +17043,35 @@ # Here is where pcre specific defines are handled -if test "$enable_utf8" = "yes"; then +if test "$enable_pcre8" = "yes"; then + +$as_echo "#define SUPPORT_PCRE8 /**/" >>confdefs.h + +fi + +if test "$enable_pcre16" = "yes"; then + +$as_echo "#define SUPPORT_PCRE16 /**/" >>confdefs.h + +fi + +if test "$enable_jit" = "yes"; then -$as_echo "#define SUPPORT_UTF8 /**/" >>confdefs.h +$as_echo "#define SUPPORT_JIT /**/" >>confdefs.h + +else + enable_pcregrep_jit="no" +fi + +if test "$enable_pcregrep_jit" = "yes"; then + +$as_echo "#define SUPPORT_PCREGREP_JIT /**/" >>confdefs.h + +fi + +if test "$enable_utf" = "yes"; then + +$as_echo "#define SUPPORT_UTF /**/" >>confdefs.h fi @@ -15743,7 +17099,22 @@ fi -if test "$enable_pcretest_libreadline" = "yes"; then +if test $with_pcregrep_bufsize -lt 8192 ; then + with_pcregrep_bufsize="8192" +fi + + +cat >>confdefs.h <<_ACEOF +#define PCREGREP_BUFSIZE $with_pcregrep_bufsize +_ACEOF + + +if test "$enable_pcretest_libedit" = "yes"; then + +$as_echo "#define SUPPORT_LIBEDIT /**/" >>confdefs.h + + LIBREADLINE="$LIBEDIT" +elif test "$enable_pcretest_libreadline" = "yes"; then $as_echo "#define SUPPORT_LIBREADLINE /**/" >>confdefs.h @@ -15819,10 +17190,13 @@ # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ - $NO_UNDEFINED -version-info 15:1:12" + $NO_UNDEFINED -version-info 1:1:0" + +EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ + $NO_UNDEFINED -version-info 0:1:0" EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ - $NO_UNDEFINED -version-info 15:1:12" + $NO_UNDEFINED -version-info 0:1:0" EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ $NO_UNDEFINED -version-info 0:0:0 \ @@ -15832,8 +17206,10 @@ -# When we run 'make distcheck', use these arguments. -DISTCHECK_CONFIGURE_FLAGS="--enable-cpp --enable-unicode-properties" + +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-jit --enable-cpp --enable-unicode-properties" # Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is @@ -15867,6 +17243,23 @@ # Similarly for --enable-pcretest-readline +if test "$enable_pcretest_libedit" = "yes"; then + if test "$enable_pcretest_libreadline" = "yes"; then + echo "** Cannot use both --enable-pcretest-libedit and --enable-pcretest-readline" + exit 1 + fi + if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ + "$HAVE_READLINE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcretest-libedit because neither editline/readline.h" + echo "** nor readline/readline.h was found." + exit 1 + fi + if test -z "$LIBEDIT"; then + echo "** Cannot --enable-pcretest-libedit because libedit library was not found." + exit 1 + fi +fi + if test "$enable_pcretest_libreadline" = "yes"; then if test "$HAVE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found." @@ -15876,12 +17269,14 @@ echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." exit 1 fi - LIBREADLINE="-lreadline" + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcretest-readline because readline library was not found." + exit 1 + fi fi - # Produce these files, in addition to config.h. -ac_config_files="$ac_config_files Makefile libpcre.pc libpcreposix.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h" +ac_config_files="$ac_config_files Makefile libpcre.pc libpcre16.pc libpcreposix.pc libpcrecpp.pc pcre-config pcre.h pcre_stringpiece.h pcrecpparg.h" # Make the generated script files executable. @@ -15957,10 +17352,21 @@ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -15976,6 +17382,7 @@ ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -15999,27 +17406,43 @@ fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error "conditional \"AMDEP\" was never defined. + as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error "conditional \"am__fastdepCC\" was never defined. + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - as_fn_error "conditional \"am__fastdepCXX\" was never defined. + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_PCRE8_TRUE}" && test -z "${WITH_PCRE8_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE8\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_PCRE16_TRUE}" && test -z "${WITH_PCRE16_FALSE}"; then + as_fn_error $? "conditional \"WITH_PCRE16\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE_CPP_TRUE}" && test -z "${WITH_PCRE_CPP_FALSE}"; then - as_fn_error "conditional \"WITH_PCRE_CPP\" was never defined. + as_fn_error $? "conditional \"WITH_PCRE_CPP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_REBUILD_CHARTABLES_TRUE}" && test -z "${WITH_REBUILD_CHARTABLES_FALSE}"; then - as_fn_error "conditional \"WITH_REBUILD_CHARTABLES\" was never defined. + as_fn_error $? "conditional \"WITH_REBUILD_CHARTABLES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_JIT_TRUE}" && test -z "${WITH_JIT_FALSE}"; then + as_fn_error $? "conditional \"WITH_JIT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_UTF_TRUE}" && test -z "${WITH_UTF_FALSE}"; then + as_fn_error $? "conditional \"WITH_UTF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -16120,6 +17543,7 @@ IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -16165,19 +17589,19 @@ (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -16373,7 +17797,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -16426,8 +17850,8 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCRE $as_me 8.12, which was -generated by GNU Autoconf 2.65. Invocation command line was +This file was extended by PCRE $as_me 8.31, which was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -16492,11 +17916,11 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PCRE config.status 8.12 -configured by $0, generated by GNU Autoconf 2.65, +PCRE config.status 8.31 +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -16514,11 +17938,16 @@ while test $# != 0 do case $1 in - --*=*) + --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; *) ac_option=$1 ac_optarg=$2 @@ -16540,6 +17969,7 @@ $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -16552,7 +17982,7 @@ ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error "ambiguous option: \`$1' + as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -16561,7 +17991,7 @@ ac_cs_silent=: ;; # This is an error. - -*) as_fn_error "unrecognized option: \`$1' + -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -16646,12 +18076,18 @@ lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' @@ -16666,14 +18102,17 @@ lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' @@ -16706,12 +18145,12 @@ hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' @@ -16750,8 +18189,8 @@ compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' @@ -16778,12 +18217,12 @@ hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' -fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' @@ -16823,8 +18262,12 @@ reload_flag \ deplibs_check_method \ file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ +archiver_list_spec \ STRIP \ RANLIB \ CC \ @@ -16834,12 +18277,14 @@ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_wl \ lt_prog_compiler_pic \ +lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ +MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ @@ -16855,7 +18300,6 @@ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ -fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ @@ -16877,8 +18321,8 @@ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ -lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ @@ -16890,7 +18334,6 @@ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ -fix_srcfile_path_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ @@ -16924,6 +18367,7 @@ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ +postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ @@ -16938,7 +18382,8 @@ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ -prelink_cmds_CXX; do +prelink_cmds_CXX \ +postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" @@ -16984,6 +18429,7 @@ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libpcre.pc") CONFIG_FILES="$CONFIG_FILES libpcre.pc" ;; + "libpcre16.pc") CONFIG_FILES="$CONFIG_FILES libpcre16.pc" ;; "libpcreposix.pc") CONFIG_FILES="$CONFIG_FILES libpcreposix.pc" ;; "libpcrecpp.pc") CONFIG_FILES="$CONFIG_FILES libpcrecpp.pc" ;; "pcre-config") CONFIG_FILES="$CONFIG_FILES pcre-config" ;; @@ -16993,7 +18439,7 @@ "script-chmod") CONFIG_COMMANDS="$CONFIG_COMMANDS script-chmod" ;; "delete-old-chartables") CONFIG_COMMANDS="$CONFIG_COMMANDS delete-old-chartables" ;; - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -17016,9 +18462,10 @@ # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -17026,12 +18473,13 @@ { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -17048,12 +18496,12 @@ fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\r' + ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -17062,18 +18510,18 @@ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -17081,7 +18529,7 @@ rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -17129,7 +18577,7 @@ rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -17161,21 +18609,29 @@ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// s/^[^=]*=[ ]*$// }' fi @@ -17187,7 +18643,7 @@ # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -17199,11 +18655,11 @@ # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -17288,7 +18744,7 @@ _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error "could not setup config headers machinery" "$LINENO" 5 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -17301,7 +18757,7 @@ esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -17320,7 +18776,7 @@ for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -17329,7 +18785,7 @@ [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -17355,8 +18811,8 @@ esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -17492,23 +18948,24 @@ s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 +which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} +which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -17517,21 +18974,21 @@ if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error "could not create -" "$LINENO" 5 + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" @@ -17805,16 +19262,36 @@ # turn newlines into spaces. NL2SP=$lt_lt_NL2SP +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method -# Command to use when deplibs_check_method == "file_magic". +# Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + # The archiver. AR=$lt_AR + +# Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + # A symbol stripping program. STRIP=$lt_STRIP @@ -17844,6 +19321,12 @@ # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + # The name of the directory that contains temporary libtool files. objdir=$objdir @@ -17853,6 +19336,9 @@ # Must we lock files when doing compilation? need_locks=$lt_need_locks +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL @@ -17967,12 +19453,12 @@ # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static @@ -18059,9 +19545,6 @@ # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path=$lt_fix_srcfile_path - # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols @@ -18077,6 +19560,9 @@ # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + # Specify filename containing input files. file_list_spec=$lt_file_list_spec @@ -18123,210 +19609,169 @@ # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $* )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[^=]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$@"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1+=\$2" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1=\$$1\$2" -} - -_LT_EOF - ;; - esac + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - mv -f "$cfgfile" "$ofile" || + mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" @@ -18354,12 +19799,12 @@ # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_CXX - # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX @@ -18446,9 +19891,6 @@ # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path=$lt_fix_srcfile_path_CXX - # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX @@ -18464,6 +19906,9 @@ # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX @@ -18500,7 +19945,7 @@ ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -18521,7 +19966,7 @@ exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit $? + $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 @@ -18548,8 +19993,11 @@ Linker flags .................... : ${LDFLAGS} Extra libraries ................. : ${LIBS} + Build 8 bit pcre library ........ : ${enable_pcre8} + Build 16 bit pcre library ....... : ${enable_pcre16} Build C++ library ............... : ${enable_cpp} - Enable UTF-8 support ............ : ${enable_utf8} + Enable JIT compiling support .... : ${enable_jit} + Enable UTF-8/16 support ......... : ${enable_utf} Unicode properties .............. : ${enable_unicode_properties} Newline char/sequence ........... : ${enable_newline} \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf} @@ -18562,8 +20010,11 @@ Match limit recursion ........... : ${with_match_limit_recursion} Build shared libs ............... : ${enable_shared} Build static libs ............... : ${enable_static} + Use JIT in pcregrep ............. : ${enable_pcregrep_jit} + Buffer size for pcregrep ........ : ${with_pcregrep_bufsize} Link pcregrep with libz ......... : ${enable_pcregrep_libz} Link pcregrep with libbz2 ....... : ${enable_pcregrep_libbz2} + Link pcretest with libedit ...... : ${enable_pcretest_libedit} Link pcretest with libreadline .. : ${enable_pcretest_libreadline} EOF diff -Nru pcre3-8.12/configure.ac pcre3-8.31/configure.ac --- pcre3-8.12/configure.ac 2011-01-15 10:38:51.000000000 +0000 +++ pcre3-8.31/configure.ac 2012-07-06 09:01:42.000000000 +0000 @@ -9,19 +9,24 @@ dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre_major, [8]) -m4_define(pcre_minor, [12]) +m4_define(pcre_minor, [31]) m4_define(pcre_prerelease, []) -m4_define(pcre_date, [2011-01-15]) +m4_define(pcre_date, [2012-07-06]) + +# NOTE: The CMakeLists.txt file searches for the above variables in the first +# 50 lines of this file. Please update that if the variables above are moved. # Libtool shared library interface versions (current:revision:age) -m4_define(libpcre_version, [0:1:0]) -m4_define(libpcreposix_version, [0:0:0]) +m4_define(libpcre_version, [1:1:0]) +m4_define(libpcre16_version, [0:1:0]) +m4_define(libpcreposix_version, [0:1:0]) m4_define(libpcrecpp_version, [0:0:0]) AC_PREREQ(2.57) AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre) AC_CONFIG_SRCDIR([pcre.h.in]) AM_INIT_AUTOMAKE([dist-bzip2 dist-zip]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS(config.h) # This was added at the suggestion of libtoolize (03-Jan-10) @@ -68,7 +73,7 @@ # AC_PROG_CXX will return "g++" even if no c++ compiler is installed. # Check for that case, and just disable c++ code if g++ doesn't run. AC_LANG_PUSH(C++) -AC_COMPILE_IFELSE(AC_LANG_PROGRAM([],[]),, CXX=""; CXXCP=""; CXXFLAGS="") +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],, CXX=""; CXXCP=""; CXXFLAGS="") AC_LANG_POP # Check for a 64-bit integer type @@ -76,7 +81,7 @@ AC_PROG_INSTALL AC_LIBTOOL_WIN32_DLL -AC_PROG_LIBTOOL +LT_INIT AC_PROG_LN_S PCRE_MAJOR="pcre_major" @@ -104,14 +109,40 @@ htmldir='${docdir}/html' fi +# Handle --disable-pcre8 (enabled by default) +AC_ARG_ENABLE(pcre8, + AS_HELP_STRING([--disable-pcre8], + [disable 8 bit character support]), + , enable_pcre8=unset) +AC_SUBST(enable_pcre8) + +# Handle --enable-pcre16 (disabled by default) +AC_ARG_ENABLE(pcre16, + AS_HELP_STRING([--enable-pcre16], + [enable 16 bit character support]), + , enable_pcre16=unset) +AC_SUBST(enable_pcre16) + # Handle --disable-cpp. The substitution of enable_cpp is needed for use in # pcre-config. AC_ARG_ENABLE(cpp, AS_HELP_STRING([--disable-cpp], [disable C++ support]), - , enable_cpp=yes) + , enable_cpp=unset) AC_SUBST(enable_cpp) +# Handle --enable-jit (disabled by default) +AC_ARG_ENABLE(jit, + AS_HELP_STRING([--enable-jit], + [enable Just-In-Time compiling support]), + , enable_jit=no) + +# Handle --disable-pcregrep-jit (enabled by default) +AC_ARG_ENABLE(pcregrep-jit, + AS_HELP_STRING([--disable-pcregrep-jit], + [disable JIT support in pcregrep]), + , enable_pcregrep_jit=yes) + # Handle --enable-rebuild-chartables AC_ARG_ENABLE(rebuild-chartables, AS_HELP_STRING([--enable-rebuild-chartables], @@ -121,13 +152,19 @@ # Handle --enable-utf8 (disabled by default) AC_ARG_ENABLE(utf8, AS_HELP_STRING([--enable-utf8], - [enable UTF-8 support (incompatible with --enable-ebcdic)]), + [another name for --enable-utf. Kept only for compatibility reasons]), , enable_utf8=unset) +# Handle --enable-utf (disabled by default) +AC_ARG_ENABLE(utf, + AS_HELP_STRING([--enable-utf], + [enable UTF-8/16 support (incompatible with --enable-ebcdic)]), + , enable_utf=unset) + # Handle --enable-unicode-properties AC_ARG_ENABLE(unicode-properties, AS_HELP_STRING([--enable-unicode-properties], - [enable Unicode properties support (implies --enable-utf8)]), + [enable Unicode properties support (implies --enable-utf)]), , enable_unicode_properties=no) # Handle --enable-newline=NL @@ -169,7 +206,7 @@ # Handle --enable-ebcdic AC_ARG_ENABLE(ebcdic, AS_HELP_STRING([--enable-ebcdic], - [assume EBCDIC coding rather than ASCII; incompatible with --enable-utf8; use only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables]), + [assume EBCDIC coding rather than ASCII; incompatible with --enable-utf; use only in (uncommon) EBCDIC environments; it implies --enable-rebuild-chartables]), , enable_ebcdic=no) # Handle --disable-stack-for-recursion @@ -190,6 +227,18 @@ [link pcregrep with libbz2 to handle .bz2 files]), , enable_pcregrep_libbz2=no) +# Handle --with-pcregrep-bufsize=N +AC_ARG_WITH(pcregrep-bufsize, + AS_HELP_STRING([--with-pcregrep-bufsize=N], + [pcregrep buffer size (default=20480)]), + , with_pcregrep_bufsize=20480) + +# Handle --enable-pcretest-libedit +AC_ARG_ENABLE(pcretest-libedit, + AS_HELP_STRING([--enable-pcretest-libedit], + [link pcretest with libedit]), + , enable_pcretest_libedit=no) + # Handle --enable-pcretest-libreadline AC_ARG_ENABLE(pcretest-libreadline, AS_HELP_STRING([--enable-pcretest-libreadline], @@ -227,34 +276,76 @@ [default limit on internal recursion (default=MATCH_LIMIT)]), , with_match_limit_recursion=MATCH_LIMIT) -# Make sure that if enable_unicode_properties was set, that UTF-8 support -# is enabled. -# +# Copy enable_utf8 value to enable_utf for compatibility reasons +if test "x$enable_utf8" != "xunset" +then + if test "x$enable_utf" != "xunset" + then + AC_MSG_ERROR([--enable/disable-utf8 is kept only for compatibility reasons and its value is copied to --enable/disable-utf. Newer code must use --enable/disable-utf alone.]) + fi + enable_utf=$enable_utf8 +fi + +# Set the default value for pcre8 +if test "x$enable_pcre8" = "xunset" +then + enable_pcre8=yes +fi + +# Set the default value for pcre16 +if test "x$enable_pcre16" = "xunset" +then + enable_pcre16=no +fi + +# Make sure enable_pcre8 or enable_pcre16 was set +if test "x$enable_pcre8$enable_pcre16" = "xnono" +then + AC_MSG_ERROR([Either 8 or 16 bit (or both) pcre library must be enabled]) +fi + +# Make sure that if enable_unicode_properties was set, that UTF support is enabled. if test "x$enable_unicode_properties" = "xyes" then - if test "x$enable_utf8" = "xno" + if test "x$enable_utf" = "xno" then - AC_MSG_ERROR([support for Unicode properties requires UTF-8 support]) + AC_MSG_ERROR([support for Unicode properties requires UTF-8/16 support]) fi - enable_utf8=yes + enable_utf=yes +fi + +# enable_utf is disabled by default. +if test "x$enable_utf" = "xunset" +then + enable_utf=no fi -if test "x$enable_utf8" = "xunset" +# enable_cpp copies the value of enable_pcre8 by default +if test "x$enable_cpp" = "xunset" then - enable_utf8=no + enable_cpp=$enable_pcre8 +fi + +# Make sure that if enable_cpp was set, that enable_pcre8 support is enabled +if test "x$enable_cpp" = "xyes" +then + if test "x$enable_pcre8" = "xno" + then + AC_MSG_ERROR([C++ library requires pcre library with 8 bit characters]) + fi fi # Make sure that if enable_ebcdic is set, rebuild_chartables is also enabled. -# Also check that UTF-8 support is not requested, because PCRE cannot handle -# EBCDIC and UTF-8 in the same build. To do so it would need to use different +# Also check that UTF support is not requested, because PCRE cannot handle +# EBCDIC and UTF in the same build. To do so it would need to use different # character constants depending on the mode. # if test "x$enable_ebcdic" = "xyes" then enable_rebuild_chartables=yes - if test "x$enable_utf8" = "xyes" + if test "x$enable_utf" = "xyes" then - AC_MSG_ERROR([support for EBCDIC and UTF-8 cannot be enabled at the same time]) + AC_MSG_ERROR([support for EBCDIC and UTF-8/16 cannot be enabled at the same time]) fi fi @@ -320,11 +411,11 @@ LDFLAGS="$OLD_LDFLAGS -Wl,$flag" # We try to run the linker with this new ld flag. If the link fails, # we give up and remove the new flag from LDFLAGS. - AC_LINK_IFELSE(AC_LANG_PROGRAM([namespace pcrecpp { + AC_LINK_IFELSE([AC_LANG_PROGRAM([namespace pcrecpp { class RE { static int no_arg; }; int RE::no_arg; }], - []), + [])], [AC_MSG_RESULT([yes]); EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS -Wl,$flag"; break;], @@ -361,8 +452,8 @@ else include=stdlib.h fi - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include <$include>], - [char* e; return $fn("100", &e, 10)]), + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <$include>], + [char* e; return $fn("100", &e, 10)])], [AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(HAVE_`echo $fn | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`, 1, [Define to 1 if you have `$fn'.]) @@ -392,8 +483,12 @@ AC_SUBST(pcre_have_bits_type_traits) # Conditional compilation +AM_CONDITIONAL(WITH_PCRE8, test "x$enable_pcre8" = "xyes") +AM_CONDITIONAL(WITH_PCRE16, test "x$enable_pcre16" = "xyes") AM_CONDITIONAL(WITH_PCRE_CPP, test "x$enable_cpp" = "xyes") AM_CONDITIONAL(WITH_REBUILD_CHARTABLES, test "x$enable_rebuild_chartables" = "xyes") +AM_CONDITIONAL(WITH_JIT, test "x$enable_jit" = "xyes") +AM_CONDITIONAL(WITH_UTF, test "x$enable_utf" = "xyes") # Checks for typedefs, structures, and compiler characteristics. @@ -434,20 +529,56 @@ AC_MSG_CHECKING([for libbz2]) OLD_LIBS="$LIBS" LIBS="$LIBS -lbz2" -AC_LINK_IFELSE( AC_LANG_PROGRAM([[ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #ifdef HAVE_BZLIB_H #include #endif]], -[[return (int)BZ2_bzopen("conftest", "rb");]]), +[[return (int)BZ2_bzopen("conftest", "rb");]])], [AC_MSG_RESULT([yes]);HAVE_LIBBZ2=1; break;], AC_MSG_RESULT([no])) LIBS="$OLD_LIBS" # Check for the availabiity of libreadline -AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1]) -AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1]) -AC_CHECK_LIB([readline], [readline], [HAVE_LIB_READLINE=1]) +if test "$enable_pcretest_libreadline" = "yes"; then + AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1]) + AC_CHECK_HEADERS([readline/history.h], [HAVE_HISTORY_H=1]) + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lreadline"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltinfo"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lcurses"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncurses"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-lncursesw"], + [unset ac_cv_lib_readline_readline; + AC_CHECK_LIB([readline], [readline], [LIBREADLINE="-ltermcap"], + [LIBREADLINE=""], + [-ltermcap])], + [-lncursesw])], + [-lncurses])], + [-lcurses])], + [-ltinfo])]) + AC_SUBST(LIBREADLINE) + if test -n "$LIBREADLINE"; then + if test "$LIBREADLINE" != "-lreadline"; then + echo "-lreadline needs $LIBREADLINE" + LIBREADLINE="-lreadline $LIBREADLINE" + fi + fi +fi + + +# Check for the availability of libedit. Different distributions put its +# headers in different places. Try to cover the most common ones. + +if test "$enable_pcretest_libedit" = "yes"; then + AC_CHECK_HEADERS([editline/readline.h], [HAVE_EDITLINE_READLINE_H=1], + [AC_CHECK_HEADERS([edit/readline/readline.h], [HAVE_READLINE_READLINE_H=1], + [AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_READLINE_H=1])])]) + AC_CHECK_LIB([edit], [readline], [LIBEDIT="-ledit"]) +fi # This facilitates -ansi builds under Linux dnl AC_DEFINE([_GNU_SOURCE], [], [Enable GNU extensions in glibc]) @@ -462,17 +593,39 @@ # Here is where pcre specific defines are handled -if test "$enable_utf8" = "yes"; then - AC_DEFINE([SUPPORT_UTF8], [], [ - Define to enable support for the UTF-8 Unicode encoding. This will - work even in an EBCDIC environment, but it is incompatible with - the EBCDIC macro. That is, PCRE can support *either* EBCDIC code - *or* ASCII/UTF-8, but not both at once.]) +if test "$enable_pcre8" = "yes"; then + AC_DEFINE([SUPPORT_PCRE8], [], [ + Define to enable the 8 bit PCRE library.]) +fi + +if test "$enable_pcre16" = "yes"; then + AC_DEFINE([SUPPORT_PCRE16], [], [ + Define to enable the 16 bit PCRE library.]) +fi + +if test "$enable_jit" = "yes"; then + AC_DEFINE([SUPPORT_JIT], [], [ + Define to enable support for Just-In-Time compiling.]) +else + enable_pcregrep_jit="no" +fi + +if test "$enable_pcregrep_jit" = "yes"; then + AC_DEFINE([SUPPORT_PCREGREP_JIT], [], [ + Define to enable JIT support in pcregrep.]) +fi + +if test "$enable_utf" = "yes"; then + AC_DEFINE([SUPPORT_UTF], [], [ + Define to enable support for the UTF-8/16 Unicode encoding. This + will work even in an EBCDIC environment, but it is incompatible + with the EBCDIC macro. That is, PCRE can support *either* EBCDIC + code *or* ASCII/UTF-8/16, but not both at once.]) fi if test "$enable_unicode_properties" = "yes"; then AC_DEFINE([SUPPORT_UCP], [], [ - Define to enable support for Unicode properties]) + Define to enable support for Unicode properties.]) fi if test "$enable_stack_for_recursion" = "no"; then @@ -500,7 +653,23 @@ able to handle .bz2 files.]) fi -if test "$enable_pcretest_libreadline" = "yes"; then +if test $with_pcregrep_bufsize -lt 8192 ; then + with_pcregrep_bufsize="8192" +fi + +AC_DEFINE_UNQUOTED([PCREGREP_BUFSIZE], [$with_pcregrep_bufsize], [ + 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.]) + +if test "$enable_pcretest_libedit" = "yes"; then + AC_DEFINE([SUPPORT_LIBEDIT], [], [ + Define to allow pcretest to be linked with libedit.]) + LIBREADLINE="$LIBEDIT" +elif test "$enable_pcretest_libreadline" = "yes"; then AC_DEFINE([SUPPORT_LIBREADLINE], [], [ Define to allow pcretest to be linked with libreadline.]) fi @@ -590,9 +759,9 @@ character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. PCRE will then assume that all input strings are in EBCDIC. If you do not define - this macro, PCRE will assume input strings are ASCII or UTF-8 Unicode. - It is not possible to build a version of PCRE that supports both - EBCDIC and UTF-8.]) + this macro, PCRE will assume input strings are ASCII or UTF-8/16 + Unicode. It is not possible to build a version of PCRE that + supports both EBCDIC and UTF-8/16.]) fi # Platform specific issues @@ -613,6 +782,9 @@ EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ $NO_UNDEFINED -version-info libpcre_version" +EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ + $NO_UNDEFINED -version-info libpcre16_version" + EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ $NO_UNDEFINED -version-info libpcreposix_version" @@ -621,11 +793,13 @@ $EXPORT_ALL_SYMBOLS" AC_SUBST(EXTRA_LIBPCRE_LDFLAGS) +AC_SUBST(EXTRA_LIBPCRE16_LDFLAGS) AC_SUBST(EXTRA_LIBPCREPOSIX_LDFLAGS) AC_SUBST(EXTRA_LIBPCRECPP_LDFLAGS) -# When we run 'make distcheck', use these arguments. -DISTCHECK_CONFIGURE_FLAGS="--enable-cpp --enable-unicode-properties" +# When we run 'make distcheck', use these arguments. Turning off compiler +# optimization makes it run faster. +DISTCHECK_CONFIGURE_FLAGS="CFLAGS='' CXXFLAGS='' --enable-pcre16 --enable-jit --enable-cpp --enable-unicode-properties" AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) # Check that, if --enable-pcregrep-libz or --enable-pcregrep-libbz2 is @@ -659,6 +833,23 @@ # Similarly for --enable-pcretest-readline +if test "$enable_pcretest_libedit" = "yes"; then + if test "$enable_pcretest_libreadline" = "yes"; then + echo "** Cannot use both --enable-pcretest-libedit and --enable-pcretest-readline" + exit 1 + fi + if test "$HAVE_EDITLINE_READLINE_H" != "1" -a \ + "$HAVE_READLINE_READLINE_H" != "1"; then + echo "** Cannot --enable-pcretest-libedit because neither editline/readline.h" + echo "** nor readline/readline.h was found." + exit 1 + fi + if test -z "$LIBEDIT"; then + echo "** Cannot --enable-pcretest-libedit because libedit library was not found." + exit 1 + fi +fi + if test "$enable_pcretest_libreadline" = "yes"; then if test "$HAVE_READLINE_H" != "1"; then echo "** Cannot --enable-pcretest-readline because readline/readline.h was not found." @@ -668,15 +859,18 @@ echo "** Cannot --enable-pcretest-readline because readline/history.h was not found." exit 1 fi - LIBREADLINE="-lreadline" + if test -z "$LIBREADLINE"; then + echo "** Cannot --enable-pcretest-readline because readline library was not found." + exit 1 + fi fi -AC_SUBST(LIBREADLINE) # Produce these files, in addition to config.h. AC_CONFIG_FILES( Makefile libpcre.pc - libpcreposix.pc + libpcre16.pc + libpcreposix.pc libpcrecpp.pc pcre-config pcre.h @@ -712,8 +906,11 @@ Linker flags .................... : ${LDFLAGS} Extra libraries ................. : ${LIBS} + Build 8 bit pcre library ........ : ${enable_pcre8} + Build 16 bit pcre library ....... : ${enable_pcre16} Build C++ library ............... : ${enable_cpp} - Enable UTF-8 support ............ : ${enable_utf8} + Enable JIT compiling support .... : ${enable_jit} + Enable UTF-8/16 support ......... : ${enable_utf} Unicode properties .............. : ${enable_unicode_properties} Newline char/sequence ........... : ${enable_newline} \R matches only ANYCRLF ......... : ${enable_bsr_anycrlf} @@ -726,8 +923,11 @@ Match limit recursion ........... : ${with_match_limit_recursion} Build shared libs ............... : ${enable_shared} Build static libs ............... : ${enable_static} + Use JIT in pcregrep ............. : ${enable_pcregrep_jit} + Buffer size for pcregrep ........ : ${with_pcregrep_bufsize} Link pcregrep with libz ......... : ${enable_pcregrep_libz} Link pcregrep with libbz2 ....... : ${enable_pcregrep_libbz2} + Link pcretest with libedit ...... : ${enable_pcretest_libedit} Link pcretest with libreadline .. : ${enable_pcretest_libreadline} EOF diff -Nru pcre3-8.12/debian/changelog pcre3-8.31/debian/changelog --- pcre3-8.12/debian/changelog 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/debian/changelog 2013-03-27 06:23:49.000000000 +0000 @@ -1,3 +1,69 @@ +pcre3 (1:8.31-2~precise1) precise; urgency=low + + * No-change backport to precise + + -- Elliot Saba Tue, 26 Mar 2013 23:23:49 -0700 + +pcre3 (1:8.31-2) unstable; urgency=low + + * Build -dev package as Multi-arch: same. Thanks Steve Langasek / Ubuntu + for the patch (Closes: 696217) + + -- Mark Baker Thu, 03 Jan 2013 20:30:05 +0000 + +pcre3 (1:8.31-1) unstable; urgency=low + + * New upstream release + * Applied patch from upstream bugzilla #1287 to fix bug where wrong + value is in re_nsub in some cases (Closes: #686495) + + -- Mark Baker Thu, 13 Sep 2012 19:58:45 +0100 + +pcre3 (1:8.30-5) unstable; urgency=low + + * There is no use in including debug information for the libraries from + the udeb in the debug package; more importantly, because the + installation system isn't multiarch, if they are included they result + in arch specific files in arch independent paths (debug package is + Multi-arch:same). Removed. (Closes: #670018) + + -- Mark Baker Tue, 01 May 2012 22:38:42 +0100 + +pcre3 (1:8.30-4) unstable; urgency=low + + * Reluctantly using an epoch, as it seems the funny version number with + extra dots causes problems + * Bumped standard version to 3.9.3. No changes needed + * Converted to use new source format / quilt + * Put back obsolete pcre_info() API that up + * Don't include pcregrep binary in debug package + + Thanks to Elimar Riesebieter for the conversion to the new source format. + + -- Mark Baker Fri, 23 Mar 2012 22:34:54 +0000 + +pcre3 (8.30..-3) unstable; urgency=low + + * configure: fixed libpcreposix version (this is not the same bug as the + previous one, though it's in the same few lines) + + -- Mark Baker Thu, 22 Mar 2012 19:45:03 +0000 + +pcre3 (8.30..-2) unstable; urgency=low + + * configure: Correct library version so soname is libpcre.so.3 instead + of .2 (Closes: #664983) + * Horrible version number is because of NMU of "8.30.really8.12-1.1"; + this will sort between that and 8.31-1 + + -- Mark Baker Thu, 22 Mar 2012 17:52:35 +0000 + +pcre3 (8.30-1) unstable; urgency=low + + * New upstream release (Closes:#664166) + + -- Mark Baker Wed, 21 Mar 2012 21:03:39 +0000 + pcre3 (8.12-4) unstable; urgency=low * Multi-arch support. Thanks Steve Langasek for patch (Closes: 634250) diff -Nru pcre3-8.12/debian/control pcre3-8.31/debian/control --- pcre3-8.12/debian/control 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/debian/control 2013-01-03 20:27:02.000000000 +0000 @@ -2,7 +2,7 @@ Section: libs Priority: optional Maintainer: Mark Baker -Standards-Version: 3.9.1 +Standards-Version: 3.9.3 Build-Depends: debhelper (>= 5.0.22), dpkg-dev (>= 1.16.0) Package: libpcre3 @@ -58,6 +58,7 @@ Package: libpcre3-dev Section: libdevel Architecture: any +Multi-Arch: same Depends: libc6-dev, libpcre3 (= ${binary:Version}), libpcrecpp0 (= ${binary:Version}), ${misc:Depends} Conflicts: libpcre1-dev, libpcre2-dev Description: Perl 5 Compatible Regular Expression Library - development files diff -Nru pcre3-8.12/debian/patches/PCRE6_compatible_API.patch pcre3-8.31/debian/patches/PCRE6_compatible_API.patch --- pcre3-8.12/debian/patches/PCRE6_compatible_API.patch 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/PCRE6_compatible_API.patch 2012-09-13 18:36:00.000000000 +0000 @@ -0,0 +1,46 @@ +From: Mark Baker +Description: Include old interface to RE::Init() for PCRE 6.x compatibility + +Index: pcre-8.30/pcrecpp.cc +=================================================================== +--- pcre-8.30.orig/pcrecpp.cc 2012-01-15 19:00:31.000000000 +0100 ++++ pcre-8.30/pcrecpp.cc 2012-03-23 11:05:02.219693149 +0100 +@@ -80,6 +80,12 @@ + // If the user doesn't ask for any options, we just use this one + static RE_Options default_options; + ++// PCRE6.x compatible API ++void RE::Init(const char *c_pat, const RE_Options* options) { ++ const string cxx_pat(c_pat); ++ Init(cxx_pat, options); ++} ++ + void RE::Init(const string& pat, const RE_Options* options) { + pattern_ = pat; + if (options == NULL) { +Index: pcre-8.30/pcrecpp.h +=================================================================== +--- pcre-8.30.orig/pcrecpp.h 2010-01-02 17:25:49.000000000 +0100 ++++ pcre-8.30/pcrecpp.h 2012-03-23 11:05:02.223026534 +0100 +@@ -658,6 +658,8 @@ + private: + + void Init(const string& pattern, const RE_Options* options); ++ // Old version from PCRE 6.x, for compatibility ++ void Init(const char *pattern, const RE_Options* options); + void Cleanup(); + + // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with +Index: pcre-8.30/pcretest.c +=================================================================== +--- pcre-8.30.orig/pcretest.c 2012-02-04 15:35:53.000000000 +0100 ++++ pcre-8.30/pcretest.c 2012-03-23 11:05:02.233026691 +0100 +@@ -2152,7 +2152,7 @@ + { + FILE *infile = stdin; + const char *version; +-int options = 0; ++long int options = 0; + int study_options = 0; + int default_find_match_limit = FALSE; + int op = 1; diff -Nru pcre3-8.12/debian/patches/bug1287 pcre3-8.31/debian/patches/bug1287 --- pcre3-8.12/debian/patches/bug1287 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/bug1287 2012-09-13 18:57:31.000000000 +0000 @@ -0,0 +1,27 @@ +Origin: http://bugs.exim.org/attachment.cgi?id=586 +Bug: http://bugs.exim.org/show_bug.cgi?id=1287 +Bug-Debian: http://bugs.debian.org/686495 +Description: Fix for upstream bug 1287 - wrong value in re_nsub + This is due to a wrong cast. Bug fix from upstream bugzilla. +Index: pcre3-8.31/pcreposix.c +=================================================================== +--- pcre3-8.31.orig/pcreposix.c 2012-06-20 16:08:49.000000000 +0100 ++++ pcre3-8.31/pcreposix.c 2012-09-13 19:53:34.000000000 +0100 +@@ -259,6 +259,7 @@ + int erroffset; + int errorcode; + int options = 0; ++int re_nsub = 0; + + if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS; + if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE; +@@ -282,7 +283,8 @@ + } + + (void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, +- &(preg->re_nsub)); ++ &re_nsub); ++preg->re_nsub = (size_t)re_nsub; + return 0; + } + diff -Nru pcre3-8.12/debian/patches/pcre_info.patch pcre3-8.31/debian/patches/pcre_info.patch --- pcre3-8.12/debian/patches/pcre_info.patch 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/pcre_info.patch 2012-09-13 18:36:00.000000000 +0000 @@ -0,0 +1,165 @@ +From: Mark Baker +Description: Restore obsolete pcre_info() API for compatiblity + +Index: pcre-8.30/Makefile.am +=================================================================== +--- pcre-8.30.orig/Makefile.am 2012-03-23 22:33:00.000000000 +0000 ++++ pcre-8.30/Makefile.am 2012-03-23 22:38:00.000000000 +0000 +@@ -187,6 +187,7 @@ + pcre_fullinfo.c \ + pcre_get.c \ + pcre_globals.c \ ++ pcre_info.c \ + pcre_internal.h \ + pcre_jit_compile.c \ + pcre_maketables.c \ +@@ -448,7 +449,7 @@ + # nice DLL for Windows use". (It is used by the pcre.dll target.) + DLL_OBJS= pcre_byte_order.o pcre_compile.o pcre_config.o \ + pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ +- pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ ++ pcre_globals.o pcre_info.o pcre_jit_compile.o pcre_maketables.o \ + pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ + pcre_study.o pcre_tables.o pcre_ucd.o \ + pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ +Index: pcre-8.30/Makefile.in +=================================================================== +--- pcre-8.30.orig/Makefile.in 2012-03-23 22:33:00.000000000 +0000 ++++ pcre-8.30/Makefile.in 2012-03-23 22:38:00.000000000 +0000 +@@ -136,7 +136,7 @@ + libpcre_la_LIBADD = + am__libpcre_la_SOURCES_DIST = pcre_byte_order.c pcre_compile.c \ + pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c \ +- pcre_get.c pcre_globals.c pcre_internal.h pcre_jit_compile.c \ ++ pcre_get.c pcre_globals.c pcre_info.c pcre_internal.h pcre_jit_compile.c \ + pcre_maketables.c pcre_newline.c pcre_ord2utf8.c \ + pcre_refcount.c pcre_string_utils.c pcre_study.c pcre_tables.c \ + pcre_ucd.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c \ +@@ -145,6 +145,7 @@ + @WITH_PCRE8_TRUE@ pcre_compile.lo pcre_config.lo \ + @WITH_PCRE8_TRUE@ pcre_dfa_exec.lo pcre_exec.lo \ + @WITH_PCRE8_TRUE@ pcre_fullinfo.lo pcre_get.lo pcre_globals.lo \ ++@WITH_PCRE8_TRUE@ pcre_info.lo \ + @WITH_PCRE8_TRUE@ pcre_jit_compile.lo pcre_maketables.lo \ + @WITH_PCRE8_TRUE@ pcre_newline.lo pcre_ord2utf8.lo \ + @WITH_PCRE8_TRUE@ pcre_refcount.lo pcre_string_utils.lo \ +@@ -642,6 +643,7 @@ + @WITH_PCRE8_TRUE@ pcre_fullinfo.c \ + @WITH_PCRE8_TRUE@ pcre_get.c \ + @WITH_PCRE8_TRUE@ pcre_globals.c \ ++@WITH_PCRE8_TRUE@ pcre_info.c \ + @WITH_PCRE8_TRUE@ pcre_internal.h \ + @WITH_PCRE8_TRUE@ pcre_jit_compile.c \ + @WITH_PCRE8_TRUE@ pcre_maketables.c \ +@@ -720,7 +722,7 @@ + # nice DLL for Windows use". (It is used by the pcre.dll target.) + DLL_OBJS = pcre_byte_order.o pcre_compile.o pcre_config.o \ + pcre_dfa_exec.o pcre_exec.o pcre_fullinfo.o pcre_get.o \ +- pcre_globals.o pcre_jit_compile.o pcre_maketables.o \ ++ pcre_globals.o pcre_info.o pcre_jit_compile.o pcre_maketables.o \ + pcre_newline.o pcre_ord2utf8.o pcre_refcount.o \ + pcre_study.o pcre_tables.o pcre_ucd.o \ + pcre_valid_utf8.o pcre_version.o pcre_chartables.o \ +@@ -1039,6 +1041,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_fullinfo.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_get.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_globals.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_info.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_compile.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_jit_test.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcre_maketables.Plo@am__quote@ +Index: pcre-8.30/pcre_info.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ pcre-8.30/pcre_info.c 2012-03-23 23:54:06.000000000 +0000 +@@ -0,0 +1,90 @@ ++/************************************************* ++* Perl-Compatible Regular Expressions * ++*************************************************/ ++ ++/* PCRE is a library of functions to support regular expressions whose syntax ++and semantics are as close as possible to those of the Perl 5 language. ++ ++ Written by Philip Hazel ++ Copyright (c) 1997-2009 University of Cambridge ++ ++----------------------------------------------------------------------------- ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright notice, ++ this list of conditions and the following disclaimer. ++ ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ * Neither the name of the University of Cambridge nor the names of its ++ contributors may be used to endorse or promote products derived from ++ this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGE. ++----------------------------------------------------------------------------- ++*/ ++ ++ ++/* This module contains the external function pcre_info(), which gives some ++information about a compiled pattern. However, use of this function is now ++deprecated, as it has been superseded by pcre_fullinfo(). */ ++ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "pcre_internal.h" ++ ++ ++/************************************************* ++* (Obsolete) Return info about compiled pattern * ++*************************************************/ ++ ++/* This is the original "info" function. It picks potentially useful data out ++of the private structure, but its interface was too rigid. It remains for ++backwards compatibility. The public options are passed back in an int - though ++the re->options field has been expanded to a long int, all the public options ++at the low end of it, and so even on 16-bit systems this will still be OK. ++Therefore, I haven't changed the API for pcre_info(). ++ ++Arguments: ++ argument_re points to compiled code ++ optptr where to pass back the options ++ first_byte where to pass back the first character, ++ or -1 if multiline and all branches start ^, ++ or -2 otherwise ++ ++Returns: number of capturing subpatterns ++ or negative values on error ++*/ ++ ++PCRE_EXP_DEFN int PCRE_CALL_CONVENTION ++pcre_info(const pcre *argument_re, int *optptr, int *first_byte) ++{ ++const real_pcre *re = (const real_pcre *)argument_re; ++if (re == NULL) return PCRE_ERROR_NULL; ++if (re->magic_number != MAGIC_NUMBER) ++ return PCRE_ERROR_BADMAGIC; ++ ++if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_COMPILE_OPTIONS); ++if (first_byte != NULL) ++ *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char : ++ ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; ++return re->top_bracket; ++} ++ ++/* End of pcre_info.c */ diff -Nru pcre3-8.12/debian/patches/pcregrep.1-patch pcre3-8.31/debian/patches/pcregrep.1-patch --- pcre3-8.12/debian/patches/pcregrep.1-patch 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/pcregrep.1-patch 2012-09-13 18:36:00.000000000 +0000 @@ -0,0 +1,26 @@ +From: Mark Baker +Description: Mention zpcregrep wrapper script in pcregrep man page. + + +Index: pcre-8.30/doc/pcregrep.1 +=================================================================== +--- pcre-8.30.orig/doc/pcregrep.1 2011-09-11 16:28:04.000000000 +0200 ++++ pcre-8.30/doc/pcregrep.1 2012-03-23 11:05:02.276360705 +0100 +@@ -3,6 +3,7 @@ + pcregrep - a grep with Perl-compatible regular expressions. + .SH SYNOPSIS + .B pcregrep [options] [long options] [pattern] [path1 path2 ...] ++.B zpcregrep [options] [long options] [pattern] [file1 file2 ...] + . + .SH DESCRIPTION + .rs +@@ -82,6 +83,9 @@ + If the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variable is set, + \fBpcregrep\fP uses the value to set a locale when calling the PCRE library. + The \fB--locale\fP option can be used to override this. ++.P ++\fBzpcregrep\fR is a wrapper script that allows pcregrep to work on ++gzip compressed files. + . + . + .SH "SUPPORT FOR COMPRESSED FILES" diff -Nru pcre3-8.12/debian/patches/pcreposix.patch pcre3-8.31/debian/patches/pcreposix.patch --- pcre3-8.12/debian/patches/pcreposix.patch 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/pcreposix.patch 2012-09-13 18:36:00.000000000 +0000 @@ -0,0 +1,31 @@ +From: Mark Baker +Description: Fix PCRE posix interface otherwise libc regexes are used (Bug 22525) + +Index: pcre-8.30/pcreposix.h +=================================================================== +--- pcre-8.30.orig/pcreposix.h 2011-12-28 17:57:51.000000000 +0100 ++++ pcre-8.30/pcreposix.h 2012-03-23 11:05:02.223026534 +0100 +@@ -133,14 +133,19 @@ + + /* The functions */ + +-PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int); +-PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, ++PCREPOSIX_EXP_DECL int pcreposix_regcomp(regex_t *, const char *, int); ++PCREPOSIX_EXP_DECL int pcreposix_regexec(const regex_t *, const char *, size_t, + regmatch_t *, int); +-PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); +-PCREPOSIX_EXP_DECL void regfree(regex_t *); ++PCREPOSIX_EXP_DECL size_t pcreposix_regerror(int, const regex_t *, char *, size_t); ++PCREPOSIX_EXP_DECL void pcreposix_regfree(regex_t *); + + #ifdef __cplusplus + } /* extern "C" */ + #endif + ++#define regcomp pcreposix_regcomp ++#define regexec pcreposix_regexec ++#define regerror pcreposix_regerror ++#define regfree pcreposix_regfree ++ + #endif /* End of pcreposix.h */ diff -Nru pcre3-8.12/debian/patches/series pcre3-8.31/debian/patches/series --- pcre3-8.12/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/series 2012-09-13 18:51:33.000000000 +0000 @@ -0,0 +1,6 @@ +PCRE6_compatible_API.patch +pcreposix.patch +pcre_info.patch +pcregrep.1-patch +soname.patch +bug1287 diff -Nru pcre3-8.12/debian/patches/soname.patch pcre3-8.31/debian/patches/soname.patch --- pcre3-8.12/debian/patches/soname.patch 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/patches/soname.patch 2012-09-13 18:48:44.000000000 +0000 @@ -0,0 +1,23 @@ +From: Mark Baker +Description: Change soname to what debian use +Index: pcre3-8.31/configure +=================================================================== +--- pcre3-8.31.orig/configure 2012-07-06 10:02:02.000000000 +0100 ++++ pcre3-8.31/configure 2012-09-13 19:47:13.000000000 +0100 +@@ -17190,13 +17190,13 @@ + # (Note: The libpcre*_version bits are m4 variables, assigned above) + + EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ +- $NO_UNDEFINED -version-info 1:1:0" ++ $NO_UNDEFINED -version-info 16:1:13" + + EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ +- $NO_UNDEFINED -version-info 0:1:0" ++ $NO_UNDEFINED -version-info 16:1:13" + + EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ +- $NO_UNDEFINED -version-info 0:1:0" ++ $NO_UNDEFINED -version-info 16:1:13" + + EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ + $NO_UNDEFINED -version-info 0:0:0 \ diff -Nru pcre3-8.12/debian/rules pcre3-8.31/debian/rules --- pcre3-8.12/debian/rules 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/debian/rules 2013-01-03 20:27:02.000000000 +0000 @@ -38,8 +38,9 @@ --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ --enable-utf8 --enable-unicode-properties - -build: build-stamp +build: build-arch build-indep +build-arch: build-stamp +build-indep: build-stamp build-stamp: config.status dh_testdir @@ -55,15 +56,12 @@ dh_testdir dh_testroot rm -f build-stamp - # Add here commands to clean up after the build process. [ ! -f Makefile ] || $(MAKE) distclean ### -test -r /usr/share/misc/config.sub && \ ### cp -f /usr/share/misc/config.sub config.sub ### -test -r /usr/share/misc/config.guess && \ ### cp -f /usr/share/misc/config.guess config.guess - - rm -f dftables testsavedregex dh_clean @@ -87,6 +85,9 @@ mkdir -p debian/libpcre3/lib/$(DEB_HOST_MULTIARCH) mv debian/libpcre3/usr/lib/$(DEB_HOST_MULTIARCH)/libpcre.so.* debian/libpcre3/lib/$(DEB_HOST_MULTIARCH) ln -sf /lib/$(DEB_HOST_MULTIARCH)/libpcre.so.3 debian/libpcre3-dev/usr/lib/$(DEB_HOST_MULTIARCH)/libpcre.so + # we never need to reference the library path in pcre-config on + # Debian, so clip it out so that the script will be multiarch-safe. + sed -i -e"s,/$(DEB_HOST_MULTIARCH),,g" debian/libpcre3-dev/usr/bin/pcre-config dh_link -a @@ -105,6 +106,9 @@ # dh_undocumented -a dh_installchangelogs -a ChangeLog dh_strip -a --dbg-package=libpcre3-dbg + # Don't include pcregrep or libraries from udeb in debug package + rm -r debian/libpcre3-dbg/usr/lib/debug/usr/bin + rm debian/libpcre3-dbg/usr/lib/debug/usr/lib/libpcre* dh_compress -a dh_fixperms -a dh_makeshlibs -plibpcre3 --add-udeb="libpcre3-udeb" -V 'libpcre3 (>= 8.10)' diff -Nru pcre3-8.12/debian/source/format pcre3-8.31/debian/source/format --- pcre3-8.12/debian/source/format 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/debian/source/format 2013-03-27 06:36:17.276505331 +0000 @@ -1 +1 @@ -1.0 +3.0 (quilt) diff -Nru pcre3-8.12/debian/source/options pcre3-8.31/debian/source/options --- pcre3-8.12/debian/source/options 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/debian/source/options 2012-09-13 18:36:00.000000000 +0000 @@ -0,0 +1,2 @@ +compression = "gzip" +compression-level = 9 diff -Nru pcre3-8.12/dftables.c pcre3-8.31/dftables.c --- pcre3-8.12/dftables.c 2008-01-20 20:01:29.000000000 +0000 +++ pcre3-8.31/dftables.c 2011-12-28 16:57:51.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -114,7 +114,7 @@ "#endif\n\n" "#include \"pcre_internal.h\"\n\n"); fprintf(f, - "const unsigned char _pcre_default_tables[] = {\n\n" + "const pcre_uint8 PRIV(default_tables)[] = {\n\n" "/* This table is a lower casing table. */\n\n"); fprintf(f, " "); diff -Nru pcre3-8.12/doc/html/index.html pcre3-8.31/doc/html/index.html --- pcre3-8.12/doc/html/index.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/index.html 2012-07-06 09:55:28.000000000 +0000 @@ -18,6 +18,9 @@ pcre   Introductory page +pcre16 +   Discussion of the 16-bit PCRE library + pcre-config   Information about the installation configuration @@ -42,6 +45,12 @@ pcregrep   The pcregrep command +pcrejit +   Discussion of the just-in-time optimization support + +pcrelimits +   Details of size and other limits + pcrematching   Discussion of the two matching algorithms @@ -71,15 +80,21 @@ pcretest   The pcretest command for testing PCRE + +pcreunicode +   Discussion of Unicode and UTF-8/UTF-16 support

There are also individual pages that summarize the interface for each function -in the library: +in the library. There is a single page for each pair of 8-bit/16-bit functions.

+ + + @@ -99,6 +114,9 @@ + + + @@ -127,15 +145,27 @@ + + + + + + + + + + + +
pcre_assign_jit_stack  Assign stack for JIT matching
pcre_compile   Compile a regular expression
  Match a compiled pattern to a subject string (DFA algorithm; not Perl compatible)
pcre_free_study  Free study data
pcre_exec   Match a compiled pattern to a subject string (Perl compatible)
pcre_info   Obsolete information extraction function
pcre_jit_stack_alloc  Create a stack for JIT matching
pcre_jit_stack_free  Free a JIT matching stack
pcre_maketables   Build character tables in current locale
pcre_pattern_to_host_byte_order  Convert compiled pattern to host byte order if necessary
pcre_refcount   Maintain reference count in compiled pattern
pcre_study   Study a compiled pattern
pcre_utf16_to_host_byte_order  Convert UTF-16 string to host byte order if necessary
pcre_version   Return PCRE version and release date
diff -Nru pcre3-8.12/doc/html/pcre-config.html pcre3-8.31/doc/html/pcre-config.html --- pcre3-8.12/doc/html/pcre-config.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre-config.html 2012-07-06 09:55:27.000000000 +0000 @@ -23,12 +23,16 @@
SYNOPSIS

pcre-config [--prefix] [--exec-prefix] [--version] [--libs] -[--libs-posix] [--cflags] [--cflags-posix] +[--libs16] [--libs-cpp] [--libs-posix] [--cflags] +[--cflags-posix]


DESCRIPTION

pcre-config returns the configuration of the installed PCRE -libraries and the options required to compile a program to use them. +libraries and the options required to compile a program to use them. Some of +the options apply only to the 8-bit or 16-bit libraries, respectively, and are +not available if only one of those libraries has been built. If an unavailable +option is encountered, the "usage" information is output.


OPTIONS

@@ -50,12 +54,23 @@

--libs Writes to the standard output the command line options required to link -with PCRE (-lpcre on many systems). +with the 8-bit PCRE library (-lpcre on many systems). +

+

+--libs16 +Writes to the standard output the command line options required to link +with the 16-bit PCRE library (-lpcre16 on many systems). +

+

+--libs-cpp +Writes to the standard output the command line options required to link with +PCRE's C++ wrapper library (-lpcrecpp -lpcre on many +systems).

--libs-posix Writes to the standard output the command line options required to link with -the PCRE posix emulation library (-lpcreposix -lpcre on many +PCRE's POSIX API wrapper library (-lpcreposix -lpcre on many systems).

@@ -67,7 +82,7 @@

--cflags-posix Writes to the standard output the command line options required to compile -files that use the PCRE posix emulation library (this may include some -I +files that use PCRE's POSIX API wrapper library (this may include some -I options, but is blank on many systems).


SEE ALSO
@@ -77,11 +92,11 @@
AUTHOR

This manual page was originally written by Mark Baker for the Debian GNU/Linux -system. It has been slightly revised as a generic PCRE man page. +system. It has been subsequently revised as a generic PCRE man page.


REVISION

-Last updated: 18 April 2007 +Last updated: 01 January 2012

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcre.html pcre3-8.31/doc/html/pcre.html --- pcre3-8.12/doc/html/pcre.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre.html 2012-07-06 09:55:27.000000000 +0000 @@ -15,10 +15,8 @@


INTRODUCTION

@@ -30,10 +28,29 @@ for requesting some minor changes that give better JavaScript compatibility.

+Starting with release 8.30, it is possible to compile two separate PCRE +libraries: the original, which supports 8-bit character strings (including +UTF-8 strings), and a second library that supports 16-bit character strings +(including UTF-16 strings). The build process allows either one or both to be +built. The majority of the work to make this possible was done by Zoltan +Herczeg. +

+

+The two libraries contain identical sets of functions, except that the names in +the 16-bit library start with pcre16_ instead of pcre_. To avoid +over-complication and reduce the documentation maintenance load, most of the +documentation describes the 8-bit library, with the differences for the 16-bit +library described separately in the +pcre16 +page. References to functions or structures of the form pcre[16]_xxx +should be read as meaning "pcre_xxx when using the 8-bit library and +pcre16_xxx when using the 16-bit library". +

+

The current implementation of PCRE corresponds approximately with Perl 5.12, -including support for UTF-8 encoded strings and Unicode general category -properties. However, UTF-8 and Unicode support has to be explicitly enabled; it -is not the default. The Unicode tables correspond to Unicode release 5.2.0. +including support for UTF-8/16 encoded strings and Unicode general category +properties. However, UTF-8/16 and Unicode support has to be explicitly enabled; +it is not the default. The Unicode tables correspond to Unicode release 6.0.0.

In addition to the Perl-compatible matching function, PCRE contains an @@ -46,8 +63,8 @@

PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, Google Inc. -have provided a comprehensive C++ wrapper. This is now included as part of the -PCRE distribution. The +have provided a comprehensive C++ wrapper for the 8-bit library. This is now +included as part of the PCRE distribution. The pcrecpp page has details of this interface. Other people's contributions can be found in the Contrib directory at the primary FTP site, which is: @@ -75,13 +92,13 @@ distribution.

-The library contains a number of undocumented internal functions and data +The libraries contains a number of undocumented internal functions and data tables that are used by more than one of the exported external functions, but which are not intended for use by external callers. Their names all begin with -"_pcre_", which hopefully will not provoke any name clashes. In some -environments, it is possible to control which external symbols are exported -when a shared library is built, and in these cases the undocumented symbols are -not exported. +"_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In +some environments, it is possible to control which external symbols are +exported when a shared library is built, and in these cases the undocumented +symbols are not exported.


USER DOCUMENTATION

@@ -92,204 +109,33 @@ of searching. The sections are as follows:

   pcre              this document
+  pcre16            details of the 16-bit library
   pcre-config       show PCRE installation configuration information
   pcreapi           details of PCRE's native C API
   pcrebuild         options for building PCRE
   pcrecallout       details of the callout feature
   pcrecompat        discussion of Perl compatibility
-  pcrecpp           details of the C++ wrapper
+  pcrecpp           details of the C++ wrapper for the 8-bit library
   pcredemo          a demonstration C program that uses PCRE
-  pcregrep          description of the pcregrep command
+  pcregrep          description of the pcregrep command (8-bit only)
+  pcrejit           discussion of the just-in-time optimization support
+  pcrelimits        details of size and other limits
   pcrematching      discussion of the two matching algorithms
   pcrepartial       details of the partial matching facility
   pcrepattern       syntax and semantics of supported regular expressions
   pcreperform       discussion of performance issues
-  pcreposix         the POSIX-compatible C API
+  pcreposix         the POSIX-compatible C API for the 8-bit library
   pcreprecompile    details of saving and re-using precompiled patterns
   pcresample        discussion of the pcredemo program
   pcrestack         discussion of stack usage
   pcresyntax        quick syntax reference
   pcretest          description of the pcretest testing command
+  pcreunicode       discussion of Unicode and UTF-8/16 support
 
In addition, in the "man" and HTML formats, there is a short page for each -C library function, listing its arguments and results. -

-
LIMITATIONS
-

-There are some size limitations in PCRE but it is hoped that they will never in -practice be relevant. -

-

-The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE is -compiled with the default internal linkage size of 2. If you want to process -regular expressions that are truly enormous, you can compile PCRE with an -internal linkage size of 3 or 4 (see the README file in the source -distribution and the -pcrebuild -documentation for details). In these cases the limit is substantially larger. -However, the speed of execution is slower. -

-

-All values in repeating quantifiers must be less than 65536. -

-

-There is no limit to the number of parenthesized subpatterns, but there can be -no more than 65535 capturing subpatterns. -

-

-The maximum length of name for a named subpattern is 32 characters, and the -maximum number of named subpatterns is 10000. -

-

-The maximum length of a subject string is the largest positive number that an -integer variable can hold. However, when using the traditional matching -function, PCRE uses recursion to handle subpatterns and indefinite repetition. -This means that the available stack space may limit the size of a subject -string that can be processed by certain patterns. For a discussion of stack -issues, see the -pcrestack -documentation. -

-
UTF-8 AND UNICODE PROPERTY SUPPORT
-

-From release 3.3, PCRE has had some support for character strings encoded in -the UTF-8 format. For release 4.0 this was greatly extended to cover most -common requirements, and in release 5.0 additional support for Unicode general -category properties was added. -

-

-In order process UTF-8 strings, you must build PCRE to include UTF-8 support in -the code, and, in addition, you must call -pcre_compile() -with the PCRE_UTF8 option flag, or the pattern must start with the sequence -(*UTF8). When either of these is the case, both the pattern and any subject -strings that are matched against it are treated as UTF-8 strings instead of -strings of 1-byte characters. -

-

-If you compile PCRE with UTF-8 support, but do not use it at run time, the -library will be a bit bigger, but the additional run time overhead is limited -to testing the PCRE_UTF8 flag occasionally, so should not be very big. -

-

-If PCRE is built with Unicode character property support (which implies UTF-8 -support), the escape sequences \p{..}, \P{..}, and \X are supported. -The available properties that can be tested are limited to the general -category properties such as Lu for an upper case letter or Nd for a decimal -number, the Unicode script names such as Arabic or Han, and the derived -properties Any and L&. A full list is given in the -pcrepattern -documentation. Only the short names for properties are supported. For example, -\p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported. -Furthermore, in Perl, many properties may optionally be prefixed by "Is", for -compatibility with Perl 5.6. PCRE does not support this. -

-
-Validity of UTF-8 strings -
-

-When you set the PCRE_UTF8 flag, the strings passed as patterns and subjects -are (by default) checked for validity on entry to the relevant functions. From -release 7.3 of PCRE, the check is according the rules of RFC 3629, which are -themselves derived from the Unicode specification. Earlier releases of PCRE -followed the rules of RFC 2279, which allows the full range of 31-bit values (0 -to 0x7FFFFFFF). The current check allows only values in the range U+0 to -U+10FFFF, excluding U+D800 to U+DFFF. -

-

-The excluded code points are the "Low Surrogate Area" of Unicode, of which the -Unicode Standard says this: "The Low Surrogate Area does not contain any -character assignments, consequently no character code charts or namelists are -provided for this area. Surrogates are reserved for use with UTF-16 and then -must be used in pairs." The code points that are encoded by UTF-16 pairs are -available as independent code points in the UTF-8 encoding. (In other words, -the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up -UTF-8.) -

-

-If an invalid UTF-8 string is passed to PCRE, an error return -(PCRE_ERROR_BADUTF8) is given. In some situations, you may already know that -your strings are valid, and therefore want to skip these checks in order to -improve performance. If you set the PCRE_NO_UTF8_CHECK flag at compile time or -at run time, PCRE assumes that the pattern or subject it is given -(respectively) contains only valid UTF-8 codes. In this case, it does not -diagnose an invalid UTF-8 string. -

-

-If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what -happens depends on why the string is invalid. If the string conforms to the -"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters -in the range 0 to 0x7FFFFFFF. In other words, apart from the initial validity -test, PCRE (when in UTF-8 mode) handles strings according to the more liberal -rules of RFC 2279. However, if the string does not even conform to RFC 2279, -the result is undefined. Your program may crash. -

-

-If you want to process strings of values in the full range 0 to 0x7FFFFFFF, -encoded in a UTF-8-like manner as per the old RFC, you can set -PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this -situation, you will have to apply your own validity check. -

-
-General comments about UTF-8 mode -
-

-1. An unbraced hexadecimal escape sequence (such as \xb3) matches a two-byte -UTF-8 character if the value is greater than 127. -

-

-2. Octal numbers up to \777 are recognized, and match two-byte UTF-8 -characters for values greater than \177. -

-

-3. Repeat quantifiers apply to complete UTF-8 characters, not to individual -bytes, for example: \x{100}{3}. -

-

-4. The dot metacharacter matches one UTF-8 character instead of a single byte. -

-

-5. The escape sequence \C can be used to match a single byte in UTF-8 mode, -but its use can lead to some strange effects. This facility is not available in -the alternative matching function, pcre_dfa_exec(). -

-

-6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly -test characters of any code value, but, by default, the characters that PCRE -recognizes as digits, spaces, or word characters remain the same set as before, -all with values less than 256. This remains true even when PCRE is built to -include Unicode property support, because to do otherwise would slow down PCRE -in many common cases. Note in particular that this applies to \b and \B, -because they are defined in terms of \w and \W. If you really want to test -for a wider sense of, say, "digit", you can use explicit Unicode property tests -such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that -the character escapes work is changed so that Unicode properties are used to -determine which characters match. There are more details in the section on -generic character types -in the -pcrepattern -documentation. -

-

-7. Similarly, characters that match the POSIX named character classes are all -low-valued characters, unless the PCRE_UCP option is set. -

-

-8. However, the horizontal and vertical whitespace matching escapes (\h, \H, -\v, and \V) do match all the appropriate Unicode characters, whether or not -PCRE_UCP is set. -

-

-9. Case-insensitive matching applies only to characters whose values are less -than 128, unless PCRE is built with Unicode property support. Even when Unicode -property support is available, PCRE still uses its own character tables when -checking the case of low-valued characters, so as not to degrade performance. -The Unicode property information is used only for characters with higher -values. Furthermore, PCRE supports case-insensitive matching only when there is -a one-to-one mapping between a letter's cases. There are a small number of -many-to-one mappings in Unicode; these are not supported by PCRE. +8-bit C library function, listing its arguments and results.

-
AUTHOR
+
AUTHOR

Philip Hazel
@@ -303,11 +149,11 @@ taken it away. If you want to email me, use my two initials, followed by the two digits 10, at the domain cam.ac.uk.

-
REVISION
+
REVISION

-Last updated: 13 November 2010 +Last updated: 10 January 2012
-Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcre16.html pcre3-8.31/doc/html/pcre16.html --- pcre3-8.12/doc/html/pcre16.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre16.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,382 @@ + + +pcre16 specification + + +

pcre16 man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+

+

+#include <pcre.h> +

+
PCRE 16-BIT API BASIC FUNCTIONS
+

+pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +

+

+pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, +int *errorcodeptr, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +

+

+pcre16_extra *pcre16_study(const pcre16 *code, int options, +const char **errptr); +

+

+void pcre16_free_study(pcre16_extra *extra); +

+

+int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, +PCRE_SPTR16 subject, int length, int startoffset, +int options, int *ovector, int ovecsize); +

+

+int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, +PCRE_SPTR16 subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +int *workspace, int wscount); +

+
PCRE 16-BIT API STRING EXTRACTION FUNCTIONS
+

+int pcre16_copy_named_substring(const pcre16 *code, +PCRE_SPTR16 subject, int *ovector, +int stringcount, PCRE_SPTR16 stringname, +PCRE_UCHAR16 *buffer, int buffersize); +

+

+int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, +int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, +int buffersize); +

+

+int pcre16_get_named_substring(const pcre16 *code, +PCRE_SPTR16 subject, int *ovector, +int stringcount, PCRE_SPTR16 stringname, +PCRE_SPTR16 *stringptr); +

+

+int pcre16_get_stringnumber(const pcre16 *code, +PCRE_SPTR16 name); +

+

+int pcre16_get_stringtable_entries(const pcre16 *code, +PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); +

+

+int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, +int stringcount, int stringnumber, +PCRE_SPTR16 *stringptr); +

+

+int pcre16_get_substring_list(PCRE_SPTR16 subject, +int *ovector, int stringcount, PCRE_SPTR16 **listptr); +

+

+void pcre16_free_substring(PCRE_SPTR16 stringptr); +

+

+void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); +

+
PCRE 16-BIT API AUXILIARY FUNCTIONS
+

+pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize); +

+

+void pcre16_jit_stack_free(pcre16_jit_stack *stack); +

+

+void pcre16_assign_jit_stack(pcre16_extra *extra, +pcre16_jit_callback callback, void *data); +

+

+const unsigned char *pcre16_maketables(void); +

+

+int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, +int what, void *where); +

+

+int pcre16_refcount(pcre16 *code, int adjust); +

+

+int pcre16_config(int what, void *where); +

+

+const char *pcre16_version(void); +

+

+int pcre16_pattern_to_host_byte_order(pcre16 *code, +pcre16_extra *extra, const unsigned char *tables); +

+
PCRE 16-BIT API INDIRECTED FUNCTIONS
+

+void *(*pcre16_malloc)(size_t); +

+

+void (*pcre16_free)(void *); +

+

+void *(*pcre16_stack_malloc)(size_t); +

+

+void (*pcre16_stack_free)(void *); +

+

+int (*pcre16_callout)(pcre16_callout_block *); +

+
PCRE 16-BIT API 16-BIT-ONLY FUNCTION
+

+int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, +PCRE_SPTR16 input, int length, int *byte_order, +int keep_boms); +

+
THE PCRE 16-BIT LIBRARY
+

+Starting with release 8.30, it is possible to compile a PCRE library that +supports 16-bit character strings, including UTF-16 strings, as well as or +instead of the original 8-bit library. The majority of the work to make this +possible was done by Zoltan Herczeg. The two libraries contain identical sets +of functions, used in exactly the same way. Only the names of the functions and +the data types of their arguments and results are different. To avoid +over-complication and reduce the documentation maintenance load, most of the +PCRE documentation describes the 8-bit library, with only occasional references +to the 16-bit library. This page describes what is different when you use the +16-bit library. +

+

+WARNING: A single application can be linked with both libraries, but you must +take care when processing any particular pattern to use functions from just one +library. For example, if you want to study a pattern that was compiled with +pcre16_compile(), you must do so with pcre16_study(), not +pcre_study(), and you must free the study data with +pcre16_free_study(). +

+
THE HEADER FILE
+

+There is only one header file, pcre.h. It contains prototypes for all the +functions in both libraries, as well as definitions of flags, structures, error +codes, etc. +

+
THE LIBRARY NAME
+

+In Unix-like systems, the 16-bit library is called libpcre16, and can +normally be accesss by adding -lpcre16 to the command for linking an +application that uses PCRE. +

+
STRING TYPES
+

+In the 8-bit library, strings are passed to PCRE library functions as vectors +of bytes with the C type "char *". In the 16-bit library, strings are passed as +vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an +appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In +very many environments, "short int" is a 16-bit data type. When PCRE is built, +it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit +data type. If it is not, the build fails with an error message telling the +maintainer to modify the definition appropriately. +

+
STRUCTURE TYPES
+

+The types of the opaque structures that are used for compiled 16-bit patterns +and JIT stacks are pcre16 and pcre16_jit_stack respectively. The +type of the user-accessible structure that is returned by pcre16_study() +is pcre16_extra, and the type of the structure that is used for passing +data to a callout function is pcre16_callout_block. These structures +contain the same fields, with the same names, as their 8-bit counterparts. The +only difference is that pointers to character strings are 16-bit instead of +8-bit types. +

+
16-BIT FUNCTIONS
+

+For every function in the 8-bit library there is a corresponding function in +the 16-bit library with a name that starts with pcre16_ instead of +pcre_. The prototypes are listed above. In addition, there is one extra +function, pcre16_utf16_to_host_byte_order(). This is a utility function +that converts a UTF-16 character string to host byte order if necessary. The +other 16-bit functions expect the strings they are passed to be in host byte +order. +

+

+The input and output arguments of +pcre16_utf16_to_host_byte_order() may point to the same address, that is, +conversion in place is supported. The output buffer must be at least as long as +the input. +

+

+The length argument specifies the number of 16-bit data units in the +input string; a negative value specifies a zero-terminated string. +

+

+If byte_order is NULL, it is assumed that the string starts off in host +byte order. This may be changed by byte-order marks (BOMs) anywhere in the +string (commonly as the first character). +

+

+If byte_order is not NULL, a non-zero value of the integer to which it +points means that the input starts off in host byte order, otherwise the +opposite order is assumed. Again, BOMs in the string can change this. The final +byte order is passed back at the end of processing. +

+

+If keep_boms is not zero, byte-order mark characters (0xfeff) are copied +into the output string. Otherwise they are discarded. +

+

+The result of the function is the number of 16-bit units placed into the output +buffer, including the zero terminator if the string was zero-terminated. +

+
SUBJECT STRING OFFSETS
+

+The offsets within subject strings that are returned by the matching functions +are in 16-bit units rather than bytes. +

+
NAMED SUBPATTERNS
+

+The name-to-number translation table that is maintained for named subpatterns +uses 16-bit characters. The pcre16_get_stringtable_entries() function +returns the length of each entry in the table as the number of 16-bit data +units. +

+
OPTION NAMES
+

+There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK, +which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In +fact, these new options define the same bits in the options word. There is a +discussion about the +validity of UTF-16 strings +in the +pcreunicode +page. +

+

+For the pcre16_config() function there is an option PCRE_CONFIG_UTF16 +that returns 1 if UTF-16 support is configured, otherwise 0. If this option is +given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is given to +pcre16_config(), the result is the PCRE_ERROR_BADOPTION error. +

+
CHARACTER CODES
+

+In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the +same way as in 8-bit, non UTF-8 mode, except, of course, that they can range +from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than +0xff can therefore be influenced by the locale in the same way as before. +Characters greater than 0xff have only one case, and no "type" (such as letter +or digit). +

+

+In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with +the exception of values in the range 0xd800 to 0xdfff because those are +"surrogate" values that are used in pairs to encode values greater than 0xffff. +

+

+A UTF-16 string can indicate its endianness by special code knows as a +byte-order mark (BOM). The PCRE functions do not handle this, expecting strings +to be in host byte order. A utility function called +pcre16_utf16_to_host_byte_order() is provided to help with this (see +above). +

+
ERROR NAMES
+

+The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to +their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled +pattern is passed to a function that processes patterns in the other +mode, for example, if a pattern compiled with pcre_compile() is passed to +pcre16_exec(). +

+

+There are new error codes whose names begin with PCRE_UTF16_ERR for invalid +UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that +are described in the section entitled +"Reason codes for invalid UTF-8 strings" +in the main +pcreapi +page. The UTF-16 errors are: +

+  PCRE_UTF16_ERR1  Missing low surrogate at end of string
+  PCRE_UTF16_ERR2  Invalid low surrogate follows high surrogate
+  PCRE_UTF16_ERR3  Isolated low surrogate
+  PCRE_UTF16_ERR4  Invalid character 0xfffe
+
+

+
ERROR TEXTS
+

+If there is an error while compiling a pattern, the error text that is passed +back by pcre16_compile() or pcre16_compile2() is still an 8-bit +character string, zero-terminated. +

+
CALLOUTS
+

+The subject and mark fields in the callout block that is passed to +a callout function point to 16-bit vectors. +

+
TESTING
+

+The pcretest program continues to operate with 8-bit input and output +files, but it can be used for testing the 16-bit library. If it is run with the +command line option -16, patterns and subject strings are converted from +8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions +are used instead of the 8-bit ones. Returned 16-bit strings are converted to +8-bit for output. If the 8-bit library was not compiled, pcretest +defaults to 16-bit and the -16 option is ignored. +

+

+When PCRE is being built, the RunTest script that is called by "make +check" uses the pcretest -C option to discover which of the 8-bit +and 16-bit libraries has been built, and runs the tests appropriately. +

+
NOT SUPPORTED IN 16-BIT MODE
+

+Not all the features of the 8-bit library are available with the 16-bit +library. The C++ and POSIX wrapper functions support only the 8-bit library, +and the pcregrep program is at present 8-bit only. +

+
AUTHOR
+

+Philip Hazel +
+University Computing Service +
+Cambridge CB2 3QH, England. +
+

+
REVISION
+

+Last updated: 14 April 2012 +
+Copyright © 1997-2012 University of Cambridge. +
+

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_assign_jit_stack.html pcre3-8.31/doc/html/pcre_assign_jit_stack.html --- pcre3-8.12/doc/html/pcre_assign_jit_stack.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_assign_jit_stack.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,72 @@ + + +pcre_assign_jit_stack specification + + +

pcre_assign_jit_stack man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+void pcre_assign_jit_stack(pcre_extra *extra, +pcre_jit_callback callback, void *data); +

+

+void pcre16_assign_jit_stack(pcre16_extra *extra, +pcre16_jit_callback callback, void *data); +

+
+DESCRIPTION +
+

+This function provides control over the memory used as a stack at run-time by a +call to pcre[16]_exec() with a pattern that has been successfully +compiled with JIT optimization. The arguments are: +

+  extra     the data pointer returned by pcre[16]_study()
+  callback  a callback function
+  data      a JIT stack or a value to be passed to the callback
+              function
+
+

+

+If callback is NULL and data is NULL, an internal 32K block on +the machine stack is used. +

+

+If callback is NULL and data is not NULL, data must +be a valid JIT stack, the result of calling pcre[16]_jit_stack_alloc(). +

+

+If callback not NULL, it is called with data as an argument at +the start of matching, in order to set up a JIT stack. If the result is NULL, +the internal 32K stack is used; otherwise the return value must be a valid JIT +stack, the result of calling pcre[16]_jit_stack_alloc(). +

+

+You may safely assign the same JIT stack to multiple patterns, as long as they +are all matched in the same thread. In a multithread application, each thread +must use its own JIT stack. For more details, see the +pcrejit +page. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_compile.html pcre3-8.31/doc/html/pcre_compile.html --- pcre3-8.12/doc/html/pcre_compile.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_compile.html 2012-07-06 09:55:27.000000000 +0000 @@ -23,13 +23,18 @@ const char **errptr, int *erroffset, const unsigned char *tableptr);

+

+pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +


DESCRIPTION

This function compiles a regular expression into an internal form. It is the -same as pcre_compile2(), except for the absence of the errorcodeptr -argument. Its arguments are: +same as pcre[16]_compile2(), except for the absence of the +errorcodeptr argument. Its arguments are:

   pattern       A zero-terminated string containing the
                   regular expression to be compiled
@@ -49,7 +54,7 @@
   PCRE_DOLLAR_ENDONLY     $ not to match newline at end
   PCRE_DOTALL             . matches anything including NL
   PCRE_DUPNAMES           Allow duplicate names for subpatterns
-  PCRE_EXTENDED           Ignore whitespace and # comments
+  PCRE_EXTENDED           Ignore white space and # comments
   PCRE_EXTRA              PCRE extra features
                             (not much use currently)
   PCRE_FIRSTLINE          Force matching to be before newline
@@ -63,15 +68,19 @@
   PCRE_NEWLINE_LF         Set LF as the newline sequence
   PCRE_NO_AUTO_CAPTURE    Disable numbered capturing paren-
                             theses (named ones available)
+  PCRE_NO_UTF16_CHECK     Do not check the pattern for UTF-16
+                            validity (only relevant if
+                            PCRE_UTF16 is set)
   PCRE_NO_UTF8_CHECK      Do not check the pattern for UTF-8
                             validity (only relevant if
                             PCRE_UTF8 is set)
   PCRE_UCP                Use Unicode properties for \d, \w, etc.
   PCRE_UNGREEDY           Invert greediness of quantifiers
-  PCRE_UTF8               Run in UTF-8 mode
+  PCRE_UTF16              Run in pcre16_compile() UTF-16 mode
+  PCRE_UTF8               Run in pcre_compile() UTF-8 mode
 
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and -PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used. +PCRE must be built with UTF support in order to use PCRE_UTF8/16 and +PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.

The yield of the function is a pointer to a private data structure that diff -Nru pcre3-8.12/doc/html/pcre_compile2.html pcre3-8.31/doc/html/pcre_compile2.html --- pcre3-8.12/doc/html/pcre_compile2.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_compile2.html 2012-07-06 09:55:27.000000000 +0000 @@ -24,13 +24,19 @@ const char **errptr, int *erroffset, const unsigned char *tableptr);

+

+pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, +int *errorcodeptr, +const char **errptr, int *erroffset, +const unsigned char *tableptr); +


DESCRIPTION

This function compiles a regular expression into an internal form. It is the -same as pcre_compile(), except for the addition of the errorcodeptr -argument. The arguments are: +same as pcre[16]_compile(), except for the addition of the +errorcodeptr argument. The arguments are:

   pattern       A zero-terminated string containing the
                   regular expression to be compiled
@@ -51,7 +57,7 @@
   PCRE_DOLLAR_ENDONLY     $ not to match newline at end
   PCRE_DOTALL             . matches anything including NL
   PCRE_DUPNAMES           Allow duplicate names for subpatterns
-  PCRE_EXTENDED           Ignore whitespace and # comments
+  PCRE_EXTENDED           Ignore white space and # comments
   PCRE_EXTRA              PCRE extra features
                             (not much use currently)
   PCRE_FIRSTLINE          Force matching to be before newline
@@ -65,15 +71,19 @@
   PCRE_NEWLINE_LF         Set LF as the newline sequence
   PCRE_NO_AUTO_CAPTURE    Disable numbered capturing paren-
                             theses (named ones available)
+  PCRE_NO_UTF16_CHECK     Do not check the pattern for UTF-16
+                            validity (only relevant if
+                            PCRE_UTF16 is set)
   PCRE_NO_UTF8_CHECK      Do not check the pattern for UTF-8
                             validity (only relevant if
                             PCRE_UTF8 is set)
   PCRE_UCP                Use Unicode properties for \d, \w, etc.
   PCRE_UNGREEDY           Invert greediness of quantifiers
-  PCRE_UTF8               Run in UTF-8 mode
+  PCRE_UTF16              Run pcre16_compile() in UTF-16 mode
+  PCRE_UTF8               Run pcre_compile() in UTF-8 mode
 
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and -PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used. +PCRE must be built with UTF support in order to use PCRE_UTF8/16 and +PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.

The yield of the function is a pointer to a private data structure that diff -Nru pcre3-8.12/doc/html/pcre_config.html pcre3-8.31/doc/html/pcre_config.html --- pcre3-8.12/doc/html/pcre_config.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_config.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,19 +21,29 @@

int pcre_config(int what, void *where);

+

+int pcre16_config(int what, void *where); +


DESCRIPTION

This function makes it possible for a client program to find out which optional -features are available in the version of the PCRE library it is using. Its +features are available in the version of the PCRE library it is using. The arguments are as follows:

   what     A code specifying what information is required
   where    Points to where to put the data
 
-The available codes are: +The where argument must point to an integer variable, except for +PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must +point to an unsigned long integer. The available codes are:
+  PCRE_CONFIG_JIT           Availability of just-in-time compiler
+                              support (1=yes 0=no)
+  PCRE_CONFIG_JITTARGET     String containing information about the
+                              target architecture for the JIT compiler,
+                              or NULL if there is no JIT support
   PCRE_CONFIG_LINK_SIZE     Internal link size: 2, 3, or 4
   PCRE_CONFIG_MATCH_LIMIT   Internal resource limit
   PCRE_CONFIG_MATCH_LIMIT_RECURSION
@@ -48,16 +58,20 @@
                                  0             all Unicode line endings
                                  1             CR, LF, or CRLF only
   PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
-                            Threshold of return slots, above
-                              which malloc() is used by
-                              the POSIX API
+                            Threshold of return slots, above which
+                              malloc() is used by the POSIX API
   PCRE_CONFIG_STACKRECURSE  Recursion implementation (1=stack 0=heap)
-  PCRE_CONFIG_UTF8          Availability of UTF-8 support (1=yes 0=no)
+  PCRE_CONFIG_UTF16         Availability of UTF-16 support (1=yes
+                               0=no); option for pcre16_config()
+  PCRE_CONFIG_UTF8          Availability of UTF-8 support (1=yes 0=no);
+                              option for pcre_config()
   PCRE_CONFIG_UNICODE_PROPERTIES
                             Availability of Unicode property support
                               (1=yes 0=no)
 
-The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. +The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error +is also given if PCRE_CONFIG_UTF16 is passed to pcre_config() or if +PCRE_CONFIG_UTF8 is passed to pcre16_config().

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_copy_named_substring.html pcre3-8.31/doc/html/pcre_copy_named_substring.html --- pcre3-8.12/doc/html/pcre_copy_named_substring.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_copy_named_substring.html 2012-07-06 09:55:27.000000000 +0000 @@ -24,6 +24,12 @@ int stringcount, const char *stringname, char *buffer, int buffersize);

+

+int pcre16_copy_named_substring(const pcre16 *code, +PCRE_SPTR16 subject, int *ovector, +int stringcount, PCRE_SPTR16 stringname, +PCRE_UCHAR16 *buffer, int buffersize); +


DESCRIPTION
@@ -33,8 +39,8 @@
   code          Pattern that was successfully matched
   subject       Subject that has been successfully matched
-  ovector       Offset vector that pcre_exec() used
-  stringcount   Value returned by pcre_exec()
+  ovector       Offset vector that pcre[16]_exec() used
+  stringcount   Value returned by pcre[16]_exec()
   stringname    Name of the required substring
   buffer        Buffer to receive the string
   buffersize    Size of buffer
diff -Nru pcre3-8.12/doc/html/pcre_copy_substring.html pcre3-8.31/doc/html/pcre_copy_substring.html
--- pcre3-8.12/doc/html/pcre_copy_substring.html	2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_copy_substring.html	2012-07-06 09:55:27.000000000 +0000
@@ -23,6 +23,11 @@
 int stringcount, int stringnumber, char *buffer,
 int buffersize);
 

+

+int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, +int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, +int buffersize); +


DESCRIPTION
@@ -31,8 +36,8 @@ buffer. The arguments are:
   subject       Subject that has been successfully matched
-  ovector       Offset vector that pcre_exec() used
-  stringcount   Value returned by pcre_exec()
+  ovector       Offset vector that pcre[16]_exec() used
+  stringcount   Value returned by pcre[16]_exec()
   stringnumber  Number of the required substring
   buffer        Buffer to receive the string
   buffersize    Size of buffer
diff -Nru pcre3-8.12/doc/html/pcre_dfa_exec.html pcre3-8.31/doc/html/pcre_dfa_exec.html
--- pcre3-8.12/doc/html/pcre_dfa_exec.html	2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_dfa_exec.html	2012-07-06 09:55:27.000000000 +0000
@@ -24,6 +24,12 @@
 int options, int *ovector, int ovecsize,
 int *workspace, int wscount);
 

+

+int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, +PCRE_SPTR16 subject, int length, int startoffset, +int options, int *ovector, int ovecsize, +int *workspace, int wscount); +


DESCRIPTION
@@ -31,10 +37,11 @@ This function matches a compiled regular expression against a given subject string, using an alternative matching algorithm that scans the subject string just once (not Perl-compatible). Note that the main, Perl-compatible, -matching function is pcre_exec(). The arguments for this function are: +matching function is pcre[16]_exec(). The arguments for this function +are:
   code         Points to the compiled pattern
-  extra        Points to an associated pcre_extra structure,
+  extra        Points to an associated pcre[16]_extra structure,
                  or is NULL
   subject      Points to the subject string
   length       Length of the subject string, in bytes
@@ -62,6 +69,9 @@
   PCRE_NOTEMPTY_ATSTART  An empty string at the start of the subject
                            is not a valid match
   PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+  PCRE_NO_UTF16_CHECK    Do not check the subject for UTF-16
+                           validity (only relevant if PCRE_UTF16
+                           was set at compile time)
   PCRE_NO_UTF8_CHECK     Do not check the subject for UTF-8
                            validity (only relevant if PCRE_UTF8
                            was set at compile time)
@@ -80,19 +90,23 @@
 page.
 

-A pcre_extra structure contains the following fields: +A pcre[16]_extra structure contains the following fields:

-  flags        Bits indicating which fields are set
-  study_data   Opaque data from pcre_study()
-  match_limit  Limit on internal resource use
+  flags            Bits indicating which fields are set
+  study_data       Opaque data from pcre[16]_study()
+  match_limit      Limit on internal resource use
   match_limit_recursion  Limit on internal recursion depth
-  callout_data Opaque data passed back to callouts
-  tables       Points to character tables or is NULL
+  callout_data     Opaque data passed back to callouts
+  tables           Points to character tables or is NULL
+  mark             For passing back a *MARK pointer
+  executable_jit   Opaque data from JIT compilation
 
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, -PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and -PCRE_EXTRA_TABLES. For this matching function, the match_limit and -match_limit_recursion fields are not used, and must not be set. +PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this +matching function, the match_limit and match_limit_recursion fields +are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and +the corresponding variable are ignored.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_exec.html pcre3-8.31/doc/html/pcre_exec.html --- pcre3-8.12/doc/html/pcre_exec.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_exec.html 2012-07-06 09:55:27.000000000 +0000 @@ -23,6 +23,11 @@ const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize);

+

+int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, +PCRE_SPTR16 subject, int length, int startoffset, +int options, int *ovector, int ovecsize); +


DESCRIPTION
@@ -32,7 +37,7 @@ offsets to captured substrings. Its arguments are:
   code         Points to the compiled pattern
-  extra        Points to an associated pcre_extra structure,
+  extra        Points to an associated pcre[16]_extra structure,
                  or is NULL
   subject      Points to the subject string
   length       Length of the subject string, in bytes
@@ -58,6 +63,9 @@
   PCRE_NOTEMPTY_ATSTART  An empty string at the start of the subject
                            is not a valid match
   PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+  PCRE_NO_UTF16_CHECK    Do not check the subject for UTF-16
+                           validity (only relevant if PCRE_UTF16
+                           was set at compile time)
   PCRE_NO_UTF8_CHECK     Do not check the subject for UTF-8
                            validity (only relevant if PCRE_UTF8
                            was set at compile time)
@@ -70,16 +78,18 @@
 pcrepartial
 page. A pcre_extra structure contains the following fields:
 
-  flags        Bits indicating which fields are set
-  study_data   Opaque data from pcre_study()
-  match_limit  Limit on internal resource use
+  flags            Bits indicating which fields are set
+  study_data       Opaque data from pcre[16]_study()
+  match_limit      Limit on internal resource use
   match_limit_recursion  Limit on internal recursion depth
-  callout_data Opaque data passed back to callouts
-  tables       Points to character tables or is NULL
+  callout_data     Opaque data passed back to callouts
+  tables           Points to character tables or is NULL
+  mark             For passing back a *MARK pointer
+  executable_jit   Opaque data from JIT compilation
 
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, -PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and -PCRE_EXTRA_TABLES. +PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_free_study.html pcre3-8.31/doc/html/pcre_free_study.html --- pcre3-8.12/doc/html/pcre_free_study.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_free_study.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,43 @@ + + +pcre_free_study specification + + +

pcre_free_study man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+void pcre_free_study(pcre_extra *extra); +

+

+void pcre16_free_study(pcre16_extra *extra); +

+
+DESCRIPTION +
+

+This function is used to free the memory used for the data generated by a call +to pcre[16]_study() when it is no longer needed. The argument must be the +result of such a call. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_free_substring.html pcre3-8.31/doc/html/pcre_free_substring.html --- pcre3-8.12/doc/html/pcre_free_substring.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_free_substring.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,13 +21,16 @@

void pcre_free_substring(const char *stringptr);

+

+void pcre16_free_substring(PCRE_SPTR16 stringptr); +


DESCRIPTION

This is a convenience function for freeing the store obtained by a previous -call to pcre_get_substring() or pcre_get_named_substring(). Its -only argument is a pointer to the string. +call to pcre[16]_get_substring() or pcre[16]_get_named_substring(). +Its only argument is a pointer to the string.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_free_substring_list.html pcre3-8.31/doc/html/pcre_free_substring_list.html --- pcre3-8.12/doc/html/pcre_free_substring_list.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_free_substring_list.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,13 +21,16 @@

void pcre_free_substring_list(const char **stringptr);

+

+void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); +


DESCRIPTION

This is a convenience function for freeing the store obtained by a previous -call to pcre_get_substring_list(). Its only argument is a pointer to the -list of string pointers. +call to pcre[16]_get_substring_list(). Its only argument is a pointer to +the list of string pointers.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_fullinfo.html pcre3-8.31/doc/html/pcre_fullinfo.html --- pcre3-8.12/doc/html/pcre_fullinfo.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_fullinfo.html 2012-07-06 09:55:27.000000000 +0000 @@ -22,6 +22,10 @@ int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where);

+

+int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, +int what, void *where); +


DESCRIPTION
@@ -29,7 +33,7 @@ This function returns information about a compiled pattern. Its arguments are:
   code                      Compiled regular expression
-  extra                     Result of pcre_study() or NULL
+  extra                     Result of pcre[16]_study() or NULL
   what                      What information is required
   where                     Where to put the information
 
@@ -38,13 +42,16 @@ PCRE_INFO_BACKREFMAX Number of highest back reference PCRE_INFO_CAPTURECOUNT Number of capturing subpatterns PCRE_INFO_DEFAULT_TABLES Pointer to default tables - PCRE_INFO_FIRSTBYTE Fixed first byte for a match, or + PCRE_INFO_FIRSTBYTE Fixed first data unit for a match, or -1 for start of string or after newline, or -2 otherwise - PCRE_INFO_FIRSTTABLE Table of first bytes (after studying) + PCRE_INFO_FIRSTTABLE Table of first data units (after studying) + PCRE_INFO_HASCRORLF Return 1 if explicit CR or LF matches exist PCRE_INFO_JCHANGED Return 1 if (?J) or (?-J) was used - PCRE_INFO_LASTLITERAL Literal last byte required + PCRE_INFO_JIT Return 1 after successful JIT compilation + PCRE_INFO_JITSIZE Size of JIT compiled code + PCRE_INFO_LASTLITERAL Literal last data unit required PCRE_INFO_MINLENGTH Lower bound length of matching strings PCRE_INFO_NAMECOUNT Number of named subpatterns PCRE_INFO_NAMEENTRYSIZE Size of name table entry @@ -55,6 +62,16 @@ PCRE_INFO_SIZE Size of compiled pattern PCRE_INFO_STUDYSIZE Size of study data
+The where argument must point to an integer variable, except for the +following what values: +
+  PCRE_INFO_DEFAULT_TABLES  const unsigned char *
+  PCRE_INFO_FIRSTTABLE      const unsigned char *
+  PCRE_INFO_NAMETABLE       PCRE_SPTR16           (16-bit library)
+  PCRE_INFO_NAMETABLE       const unsigned char * (8-bit library)
+  PCRE_INFO_OPTIONS         unsigned long int
+  PCRE_INFO_SIZE            size_t
+
The yield of the function is zero on success or:
   PCRE_ERROR_NULL           the argument code was NULL
diff -Nru pcre3-8.12/doc/html/pcre_get_named_substring.html pcre3-8.31/doc/html/pcre_get_named_substring.html
--- pcre3-8.12/doc/html/pcre_get_named_substring.html	2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_get_named_substring.html	2012-07-06 09:55:27.000000000 +0000
@@ -24,6 +24,12 @@
 int stringcount, const char *stringname,
 const char **stringptr);
 

+

+int pcre16_get_named_substring(const pcre16 *code, +PCRE_SPTR16 subject, int *ovector, +int stringcount, PCRE_SPTR16 stringname, +PCRE_SPTR16 *stringptr); +


DESCRIPTION
@@ -33,16 +39,17 @@
   code          Compiled pattern
   subject       Subject that has been successfully matched
-  ovector       Offset vector that pcre_exec() used
-  stringcount   Value returned by pcre_exec()
+  ovector       Offset vector that pcre[16]_exec() used
+  stringcount   Value returned by pcre[16]_exec()
   stringname    Name of the required substring
   stringptr     Where to put the string pointer
 
The memory in which the substring is placed is obtained by calling -pcre_malloc(). The convenience function pcre_free_substring() can -be used to free it when it is no longer needed. The yield of the function is -the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory -could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. +pcre[16]_malloc(). The convenience function +pcre[16]_free_substring() can be used to free it when it is no longer +needed. The yield of the function is the length of the extracted substring, +PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or +PCRE_ERROR_NOSUBSTRING if the string name is invalid.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_get_stringnumber.html pcre3-8.31/doc/html/pcre_get_stringnumber.html --- pcre3-8.12/doc/html/pcre_get_stringnumber.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_get_stringnumber.html 2012-07-06 09:55:27.000000000 +0000 @@ -22,6 +22,10 @@ int pcre_get_stringnumber(const pcre *code, const char *name);

+

+int pcre16_get_stringnumber(const pcre16 *code, +PCRE_SPTR16 name); +


DESCRIPTION
@@ -35,8 +39,8 @@ The yield of the function is the number of the parenthesis if the name is found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed (PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by -pcre_get_stringnumber(). You can obtain the complete list by calling -pcre_get_stringtable_entries(). +pcre[16]_get_stringnumber(). You can obtain the complete list by calling +pcre[16]_get_stringtable_entries().

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_get_stringtable_entries.html pcre3-8.31/doc/html/pcre_get_stringtable_entries.html --- pcre3-8.12/doc/html/pcre_get_stringtable_entries.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_get_stringtable_entries.html 2012-07-06 09:55:27.000000000 +0000 @@ -22,6 +22,10 @@ int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last);

+

+int pcre16_get_stringtable_entries(const pcre16 *code, +PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); +


DESCRIPTION
@@ -29,7 +33,7 @@ This convenience function finds, for a compiled pattern, the first and last entries for a given name in the table that translates capturing parenthesis names into numbers. When names are required to be unique (PCRE_DUPNAMES is -not set), it is usually easier to use pcre_get_stringnumber() +not set), it is usually easier to use pcre[16]_get_stringnumber() instead.
   code    Compiled regular expression
diff -Nru pcre3-8.12/doc/html/pcre_get_substring.html pcre3-8.31/doc/html/pcre_get_substring.html
--- pcre3-8.12/doc/html/pcre_get_substring.html	2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_get_substring.html	2012-07-06 09:55:27.000000000 +0000
@@ -23,6 +23,11 @@
 int stringcount, int stringnumber,
 const char **stringptr);
 

+

+int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, +int stringcount, int stringnumber, +PCRE_SPTR16 *stringptr); +


DESCRIPTION
@@ -31,16 +36,17 @@ arguments are:
   subject       Subject that has been successfully matched
-  ovector       Offset vector that pcre_exec() used
-  stringcount   Value returned by pcre_exec()
+  ovector       Offset vector that pcre[16]_exec() used
+  stringcount   Value returned by pcre[16]_exec()
   stringnumber  Number of the required substring
   stringptr     Where to put the string pointer
 
The memory in which the substring is placed is obtained by calling -pcre_malloc(). The convenience function pcre_free_substring() can -be used to free it when it is no longer needed. The yield of the function is -the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not -be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. +pcre[16]_malloc(). The convenience function +pcre[16]_free_substring() can be used to free it when it is no longer +needed. The yield of the function is the length of the substring, +PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or +PCRE_ERROR_NOSUBSTRING if the string number is invalid.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_get_substring_list.html pcre3-8.31/doc/html/pcre_get_substring_list.html --- pcre3-8.12/doc/html/pcre_get_substring_list.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_get_substring_list.html 2012-07-06 09:55:27.000000000 +0000 @@ -22,6 +22,10 @@ int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr);

+

+int pcre16_get_substring_list(PCRE_SPTR16 subject, +int *ovector, int stringcount, PCRE_SPTR16 **listptr); +


DESCRIPTION
@@ -30,17 +34,17 @@ substrings. The arguments are:
   subject       Subject that has been successfully matched
-  ovector       Offset vector that pcre_exec used
-  stringcount   Value returned by pcre_exec
+  ovector       Offset vector that pcre[16]_exec used
+  stringcount   Value returned by pcre[16]_exec
   listptr       Where to put a pointer to the list
 
The memory in which the substrings and the list are placed is obtained by -calling pcre_malloc(). The convenience function -pcre_free_substring_list() can be used to free it when it is no longer -needed. A pointer to a list of pointers is put in the variable whose address is -in listptr. The list is terminated by a NULL pointer. The yield of the -function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could -not be obtained. +calling pcre[16]_malloc(). The convenience function +pcre[16]_free_substring_list() can be used to free it when it is no +longer needed. A pointer to a list of pointers is put in the variable whose +address is in listptr. The list is terminated by a NULL pointer. The +yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient +memory could not be obtained.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_info.html pcre3-8.31/doc/html/pcre_info.html --- pcre3-8.12/doc/html/pcre_info.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_info.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - - -pcre_info specification - - -

pcre_info man page

-

-Return to the PCRE index page. -

-

-This page is part of the PCRE HTML documentation. It was generated automatically -from the original man page. If there is any nonsense in it, please consult the -man page, in case the conversion went wrong. -
-
-SYNOPSIS -
-

-#include <pcre.h> -

-

-int pcre_info(const pcre *code, int *optptr, int -*firstcharptr); -

-
-DESCRIPTION -
-

-This function is obsolete. You should be using pcre_fullinfo() instead. -

-

-There is a complete description of the PCRE native API in the -pcreapi -page and a description of the POSIX API in the -pcreposix -page. -

-Return to the PCRE index page. -

diff -Nru pcre3-8.12/doc/html/pcre_jit_stack_alloc.html pcre3-8.31/doc/html/pcre_jit_stack_alloc.html --- pcre3-8.12/doc/html/pcre_jit_stack_alloc.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_jit_stack_alloc.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,51 @@ + + +pcre_jit_stack_alloc specification + + +

pcre_jit_stack_alloc man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+pcre_jit_stack *pcre_jit_stack_alloc(int startsize, +int maxsize); +

+

+pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, +int maxsize); +

+
+DESCRIPTION +
+

+This function is used to create a stack for use by the code compiled by the JIT +optimization of pcre[16]_study(). The arguments are a starting size for +the stack, and a maximum size to which it is allowed to grow. The result can be +passed to the JIT run-time code by pcre[16]_assign_jit_stack(), or that +function can set up a callback for obtaining a stack. A maximum stack size of +512K to 1M should be more than enough for any pattern. For more details, see +the +pcrejit +page. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_jit_stack_free.html pcre3-8.31/doc/html/pcre_jit_stack_free.html --- pcre3-8.12/doc/html/pcre_jit_stack_free.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_jit_stack_free.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,45 @@ + + +pcre_jit_stack_free specification + + +

pcre_jit_stack_free man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+void pcre_jit_stack_free(pcre_jit_stack *stack); +

+

+void pcre16_jit_stack_free(pcre16_jit_stack *stack); +

+
+DESCRIPTION +
+

+This function is used to free a JIT stack that was created by +pcre[16]_jit_stack_alloc() when it is no longer needed. For more details, +see the +pcrejit +page. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_maketables.html pcre3-8.31/doc/html/pcre_maketables.html --- pcre3-8.12/doc/html/pcre_maketables.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_maketables.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,15 +21,18 @@

const unsigned char *pcre_maketables(void);

+

+const unsigned char *pcre16_maketables(void); +


DESCRIPTION

This function builds a set of character tables for character values less than -256. These can be passed to pcre_compile() to override PCRE's internal, -built-in tables (which were made by pcre_maketables() when PCRE was -compiled). You might want to do this if you are using a non-standard locale. -The function yields a pointer to the tables. +256. These can be passed to pcre[16]_compile() to override PCRE's +internal, built-in tables (which were made by pcre[16]_maketables() when +PCRE was compiled). You might want to do this if you are using a non-standard +locale. The function yields a pointer to the tables.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_pattern_to_host_byte_order.html pcre3-8.31/doc/html/pcre_pattern_to_host_byte_order.html --- pcre3-8.12/doc/html/pcre_pattern_to_host_byte_order.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_pattern_to_host_byte_order.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,54 @@ + + +pcre_pattern_to_host_byte_order specification + + +

pcre_pattern_to_host_byte_order man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+int pcre_pattern_to_host_byte_order(pcre *code, +pcre_extra *extra, const unsigned char *tables); +

+

+int pcre16_pattern_to_host_byte_order(pcre16 *code, +pcre16_extra *extra, const unsigned char *tables); +

+
+DESCRIPTION +
+

+This function ensures that the bytes in 2-byte and 4-byte values in a compiled +pattern are in the correct order for the current host. It is useful when a +pattern that has been compiled on one host is transferred to another that might +have different endianness. The arguments are: +

+  code         A compiled regular expression
+  extra        Points to an associated pcre[16]_extra structure,
+                 or is NULL
+  tables       Pointer to character tables, or NULL to
+                 set the built-in default
+
+The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_refcount.html pcre3-8.31/doc/html/pcre_refcount.html --- pcre3-8.12/doc/html/pcre_refcount.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_refcount.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,6 +21,9 @@

int pcre_refcount(pcre *code, int adjust);

+

+int pcre16_refcount(pcre16 *code, int adjust); +


DESCRIPTION
diff -Nru pcre3-8.12/doc/html/pcre_study.html pcre3-8.31/doc/html/pcre_study.html --- pcre3-8.12/doc/html/pcre_study.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_study.html 2012-07-06 09:55:27.000000000 +0000 @@ -22,6 +22,10 @@ pcre_extra *pcre_study(const pcre *code, int options, const char **errptr);

+

+pcre16_extra *pcre16_study(const pcre16 *code, int options, +const char **errptr); +


DESCRIPTION
@@ -30,11 +34,12 @@ be extracted that might speed up matching. Its arguments are:
   code       A compiled regular expression
-  options    Options for pcre_study()
+  options    Options for pcre[16]_study()
   errptr     Where to put an error message
 
If the function succeeds, it returns a value that can be passed to -pcre_exec() via its extra argument. +pcre[16]_exec() or pcre[16]_dfa_exec() via their extra +arguments.

If the function returns NULL, either it could not find any additional @@ -42,8 +47,11 @@ the error value. It is NULL in first case.

-There are currently no options defined; the value of the second argument should -always be zero. +The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation +if possible. If PCRE has been compiled without JIT support, this option is +ignored. See the +pcrejit +page for further details.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcre_utf16_to_host_byte_order.html pcre3-8.31/doc/html/pcre_utf16_to_host_byte_order.html --- pcre3-8.12/doc/html/pcre_utf16_to_host_byte_order.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_utf16_to_host_byte_order.html 2012-07-06 09:55:27.000000000 +0000 @@ -0,0 +1,57 @@ + + +pcre_utf16_to_host_byte_order specification + + +

pcre_utf16_to_host_byte_order man page

+

+Return to the PCRE index page. +

+

+This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
+
+SYNOPSIS +
+

+#include <pcre.h> +

+

+int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, +PCRE_SPTR16 input, int length, int *host_byte_order, +int keep_boms); +

+
+DESCRIPTION +
+

+This function, which exists only in the 16-bit library, converts a UTF-16 +string to the correct order for the current host, taking account of any byte +order marks (BOMs) within the string. Its arguments are: +

+  output           pointer to output buffer, may be the same as input
+  input            pointer to input buffer
+  length           number of 16-bit units in the input, or negative for
+                     a zero-terminated string
+  host_byte_order  a NULL value or a non-zero value pointed to means
+                     start in host byte order
+  keep_boms        if non-zero, BOMs are copied to the output string
+
+The result of the function is the number of 16-bit units placed into the output +buffer, including the zero terminator if the string was zero-terminated. +

+

+If host_byte_order is not NULL, it is set to indicate the byte order that +is current at the end of the string. +

+

+There is a complete description of the PCRE native API in the +pcreapi +page and a description of the POSIX API in the +pcreposix +page. +

+Return to the PCRE index page. +

diff -Nru pcre3-8.12/doc/html/pcre_version.html pcre3-8.31/doc/html/pcre_version.html --- pcre3-8.12/doc/html/pcre_version.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcre_version.html 2012-07-06 09:55:27.000000000 +0000 @@ -19,14 +19,18 @@ #include <pcre.h>

-char *pcre_version(void); +const char *pcre_version(void); +

+

+const char *pcre16_version(void);


DESCRIPTION

-This function returns a character string that gives the version number of the -PCRE library and the date of its release. +This function (even in the 16-bit library) returns a zero-terminated, 8-bit +character string that gives the version number of the PCRE library and the date +of its release.

There is a complete description of the PCRE native API in the diff -Nru pcre3-8.12/doc/html/pcreapi.html pcre3-8.31/doc/html/pcreapi.html --- pcre3-8.12/doc/html/pcreapi.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcreapi.html 2012-07-06 09:55:27.000000000 +0000 @@ -13,33 +13,37 @@ man page, in case the conversion went wrong.

-
PCRE NATIVE API

#include <pcre.h>

+
PCRE NATIVE API BASIC FUNCTIONS

pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, @@ -56,6 +60,9 @@ const char **errptr);

+void pcre_free_study(pcre_extra *extra); +

+

int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); @@ -66,6 +73,7 @@ int options, int *ovector, int ovecsize, int *workspace, int wscount);

+
PCRE NATIVE API STRING EXTRACTION FUNCTIONS

int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, @@ -106,6 +114,17 @@

void pcre_free_substring_list(const char **stringptr);

+
PCRE NATIVE API AUXILIARY FUNCTIONS
+

+pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize); +

+

+void pcre_jit_stack_free(pcre_jit_stack *stack); +

+

+void pcre_assign_jit_stack(pcre_extra *extra, +pcre_jit_callback callback, void *data); +

const unsigned char *pcre_maketables(void);

@@ -114,19 +133,20 @@ int what, void *where);

-int pcre_info(const pcre *code, int *optptr, int -*firstcharptr); -

-

int pcre_refcount(pcre *code, int adjust);

int pcre_config(int what, void *where);

-char *pcre_version(void); +const char *pcre_version(void);

+int pcre_pattern_to_host_byte_order(pcre *code, +pcre_extra *extra, const unsigned char *tables); +

+
PCRE NATIVE API INDIRECTED FUNCTIONS
+

void *(*pcre_malloc)(size_t);

@@ -141,24 +161,51 @@

int (*pcre_callout)(pcre_callout_block *);

-
PCRE API OVERVIEW
+
PCRE 8-BIT AND 16-BIT LIBRARIES
+

+From release 8.30, PCRE can be compiled as a library for handling 16-bit +character strings as well as, or instead of, the original library that handles +8-bit character strings. To avoid too much complication, this document +describes the 8-bit versions of the functions, with only occasional references +to the 16-bit library. +

+

+The 16-bit functions operate in the same way as their 8-bit counterparts; they +just use different data types for their arguments and results, and their names +start with pcre16_ instead of pcre_. For every option that has UTF8 +in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with +UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit +option names define the same bit values. +

+

+References to bytes and UTF-8 in this document should be read as references to +16-bit data quantities and UTF-16 when using the 16-bit library, unless +specified otherwise. More details of the specific differences for the 16-bit +library are given in the +pcre16 +page. +

+
PCRE API OVERVIEW

PCRE has its own native API, which is described in this document. There are -also some wrapper functions that correspond to the POSIX regular expression -API. These are described in the +also some wrapper functions (for the 8-bit library only) that correspond to the +POSIX regular expression API, but they do not give access to all the +functionality. They are described in the pcreposix documentation. Both of these APIs define a set of C function calls. A C++ -wrapper is distributed with PCRE. It is documented in the +wrapper (again for the 8-bit library only) is also distributed with PCRE. It is +documented in the pcrecpp page.

The native API C function prototypes are defined in the header file -pcre.h, and on Unix systems the library itself is called libpcre. -It can normally be accessed by adding -lpcre to the command for linking -an application that uses PCRE. The header file defines the macros PCRE_MAJOR -and PCRE_MINOR to contain the major and minor release numbers for the library. -Applications can use these to include support for different releases of PCRE. +pcre.h, and on Unix-like systems the (8-bit) library itself is called +libpcre. It can normally be accessed by adding -lpcre to the +command for linking an application that uses PCRE. The header file defines the +macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers +for the library. Applications can use these to include support for different +releases of PCRE.

In a Windows environment, if you want to statically link an application program @@ -179,6 +226,18 @@ documentation describes how to compile and run it.

+Just-in-time compiler support is an optional feature of PCRE that can be built +in appropriate hardware environments. It greatly speeds up the matching +performance of many patterns. Simple programs can easily request that it be +used if available, by setting an option that is ignored when it is not +relevant. More complicated programs might need to make use of the functions +pcre_jit_stack_alloc(), pcre_jit_stack_free(), and +pcre_assign_jit_stack() in order to control the JIT code's memory usage. +These functions are discussed in the +pcrejit +documentation. +

+

A second matching function, pcre_dfa_exec(), which is not Perl-compatible, is also provided. This uses a different algorithm for the matching. The alternative algorithm finds all possible matches (at a given @@ -214,10 +273,8 @@

The function pcre_fullinfo() is used to find out information about a -compiled pattern; pcre_info() is an obsolete version that returns only -some of the available information, but is retained for backwards compatibility. -The function pcre_version() returns a pointer to a string containing the -version of PCRE and its date of release. +compiled pattern. The function pcre_version() returns a pointer to a +string containing the version of PCRE and its date of release.

The function pcre_refcount() maintains a reference count in a data block @@ -254,13 +311,13 @@ pcrecallout documentation.

-
NEWLINES
+
NEWLINES

PCRE supports five different conventions for indicating line breaks in strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The Unicode newline sequences are the three just -mentioned, plus the single characters VT (vertical tab, U+000B), FF (formfeed, +mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029).

@@ -293,7 +350,7 @@ the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options.

-
MULTITHREADING
+
MULTITHREADING

The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by pcre_malloc, @@ -304,17 +361,24 @@ The compiled form of a regular expression is not altered during matching, so the same compiled pattern can safely be used by several threads at once.

-
SAVING PRECOMPILED PATTERNS FOR LATER USE
+

+If the just-in-time optimization feature is being used, it needs separate +memory stack areas for each thread. See the +pcrejit +documentation for more details. +

+
SAVING PRECOMPILED PATTERNS FOR LATER USE

The compiled form of a regular expression can be saved and re-used at a later time, possibly by a different program, and even on a host other than the one on which it was compiled. Details are given in the pcreprecompile -documentation. However, compiling a regular expression with one version of PCRE -for use with a different version is not guaranteed to work and may cause -crashes. +documentation, which includes a description of the +pcre_pattern_to_host_byte_order() function. However, compiling a regular +expression with one version of PCRE for use with a different version is not +guaranteed to work and may cause crashes.

-
CHECKING BUILD-TIME OPTIONS
+
CHECKING BUILD-TIME OPTIONS

int pcre_config(int what, void *where);

@@ -327,18 +391,40 @@

The first argument for pcre_config() is an integer, specifying which information is required; the second argument is a pointer to a variable into -which the information is placed. The following information is available: +which the information is placed. The returned value is zero on success, or the +negative error code PCRE_ERROR_BADOPTION if the value in the first argument is +not recognized. The following information is available:

   PCRE_CONFIG_UTF8
 
The output is an integer that is set to one if UTF-8 support is available; -otherwise it is set to zero. +otherwise it is set to zero. If this option is given to the 16-bit version of +this function, pcre16_config(), the result is PCRE_ERROR_BADOPTION. +
+  PCRE_CONFIG_UTF16
+
+The output is an integer that is set to one if UTF-16 support is available; +otherwise it is set to zero. This value should normally be given to the 16-bit +version of this function, pcre16_config(). If it is given to the 8-bit +version of this function, the result is PCRE_ERROR_BADOPTION.
   PCRE_CONFIG_UNICODE_PROPERTIES
 
The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero.
+  PCRE_CONFIG_JIT
+
+The output is an integer that is set to one if support for just-in-time +compiling is available; otherwise it is set to zero. +
+  PCRE_CONFIG_JITTARGET
+
+The output is a pointer to a zero-terminated "const char *" string. If JIT +support is available, the string contains the name of the architecture for +which the JIT compiler is configured, for example "x86 32bit (little endian + +unaligned)". If JIT support is not available, the result is NULL. +
   PCRE_CONFIG_NEWLINE
 
The output is an integer whose value specifies the default character sequence @@ -358,10 +444,12 @@ PCRE_CONFIG_LINK_SIZE
The output is an integer that contains the number of bytes used for internal -linkage in compiled regular expressions. The value is 2, 3, or 4. Larger values -allow larger regular expressions to be compiled, at the expense of slower -matching. The default value of 2 is sufficient for all but the most massive -patterns, since it allows the compiled pattern to be up to 64K in size. +linkage in compiled regular expressions. For the 8-bit library, the value can +be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still +a number of bytes. The default value of 2 is sufficient for all but the most +massive patterns, since it allows the compiled pattern to be up to 64K in size. +Larger values allow larger regular expressions to be compiled, at the expense +of slower matching.
   PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
 
@@ -393,7 +481,7 @@ pcre_stack_free are called to manage memory blocks on the heap, thus avoiding the use of the stack.

-
COMPILING A PATTERN
+
COMPILING A PATTERN

pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, @@ -436,7 +524,7 @@ the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and -PCRE_NO_START_OPT options can be set at the time of matching as well as at +PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at compile time.

@@ -444,17 +532,17 @@ Otherwise, if compilation of a pattern fails, pcre_compile() returns NULL, and sets the variable pointed to by errptr to point to a textual error message. This is a static string that is part of the library. You must -not try to free it. The offset from the start of the pattern to the byte that -was being processed when the error was discovered is placed in the variable -pointed to by erroffset, which must not be NULL. If it is, an immediate -error is given. Some errors are not detected until checks are carried out when -the whole pattern has been scanned; in this case the offset is set to the end -of the pattern. +not try to free it. Normally, the offset from the start of the pattern to the +byte that was being processed when the error was discovered is placed in the +variable pointed to by erroffset, which must not be NULL (if it is, an +immediate error is given). However, for an invalid UTF-8 string, the offset is +that of the first byte of the failing character.

-Note that the offset is in bytes, not characters, even in UTF-8 mode. It may -point into the middle of a UTF-8 character (for example, when -PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string). +Some errors are not detected until the whole pattern has been scanned; in these +cases, the offset passed back is the length of the pattern. Note that the +offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point +into the middle of a UTF-8 character.

If pcre_compile2() is used instead of pcre_compile(), and the @@ -553,17 +641,17 @@

   PCRE_EXTENDED
 
-If this bit is set, whitespace data characters in the pattern are totally -ignored except when escaped or inside a character class. Whitespace does not +If this bit is set, white space data characters in the pattern are totally +ignored except when escaped or inside a character class. White space does not include the VT character (code 11). In addition, characters between an unescaped # outside a character class and the next newline, inclusive, are also ignored. This is equivalent to Perl's /x option, and it can be changed within a pattern by a (?x) option setting.

-Which characters are interpreted as newlines -is controlled by the options passed to pcre_compile() or by a special -sequence at the start of the pattern, as described in the section entitled +Which characters are interpreted as newlines is controlled by the options +passed to pcre_compile() or by a special sequence at the start of the +pattern, as described in the section entitled "Newline conventions" in the pcrepattern documentation. Note that the end of this type of comment is a literal newline sequence in the pattern; escape sequences that @@ -571,7 +659,7 @@

This option makes it possible to include comments inside complicated patterns. -Note, however, that this applies only to data characters. Whitespace characters +Note, however, that this applies only to data characters. White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that introduces a conditional subpattern.

@@ -608,6 +696,23 @@
 string (by default this causes the current matching alternative to fail). A
 pattern such as (\1)(a) succeeds when this option is set (assuming it can find
 an "a" in the subject), whereas it fails by default, for Perl compatibility.
+

+

+(3) \U matches an upper case "U" character; by default \U causes a compile +time error (Perl uses \U to upper case subsequent characters). +

+

+(4) \u matches a lower case "u" character unless it is followed by four +hexadecimal digits, in which case the hexadecimal number defines the code point +to match. By default, \u causes a compile time error (Perl uses it to upper +case the following character). +

+

+(5) \x matches a lower case "x" character unless it is followed by two +hexadecimal digits, in which case the hexadecimal number defines the code point +to match. By default, as in Perl, a hexadecimal number is always expected after +\x, but it may have zero, one, or two digits (so, for example, \xz matches a +binary zero character followed by z).

   PCRE_MULTILINE
 
@@ -640,9 +745,9 @@ preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical -tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line -separator, U+2028), and PS (paragraph separator, U+2029). The last two are -recognized only in UTF-8 mode. +tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line +separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit +library, the last two are recognized only in UTF-8 mode.

The newline setting in the options word uses three bits that are treated @@ -654,7 +759,7 @@

The only time that a line break in a pattern is specially recognized when -compiling is when PCRE_EXTENDED is set. CR and LF are whitespace characters, +compiling is when PCRE_EXTENDED is set. CR and LF are white space characters, and so are ignored in this mode. Also, an unescaped # outside a character class indicates a comment that lasts until after the next line break sequence. In other circumstances, line break sequences in patterns are treated as literal @@ -702,36 +807,35 @@ PCRE_UTF8

This option causes PCRE to regard both the pattern and the subject as strings -of UTF-8 characters instead of single-byte character strings. However, it is -available only when PCRE is built to include UTF-8 support. If not, the use -of this option provokes an error. Details of how this option changes the -behaviour of PCRE are given in the -section on UTF-8 support -in the main -pcre +of UTF-8 characters instead of single-byte strings. However, it is available +only when PCRE is built to include UTF support. If not, the use of this option +provokes an error. Details of how this option changes the behaviour of PCRE are +given in the +pcreunicode page.
   PCRE_NO_UTF8_CHECK
 
-When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is -automatically checked. There is a discussion about the -validity of UTF-8 strings -in the main -pcre -page. If an invalid UTF-8 sequence of bytes is found, pcre_compile() -returns an error. If you already know that your pattern is valid, and you want -to skip this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK -option. When it is set, the effect of passing an invalid UTF-8 string as a -pattern is undefined. It may cause your program to crash. Note that this option -can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress -the UTF-8 validity checking of subject strings. +When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 +string is automatically checked. There is a discussion about the +validity of UTF-8 strings +in the +pcreunicode +page. If an invalid UTF-8 sequence is found, pcre_compile() returns an +error. If you already know that your pattern is valid, and you want to skip +this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK option. +When it is set, the effect of passing an invalid UTF-8 string as a pattern is +undefined. It may cause your program to crash. Note that this option can also +be passed to pcre_exec() and pcre_dfa_exec(), to suppress the +validity checking of subject strings.

-
COMPILATION ERROR CODES
+
COMPILATION ERROR CODES

The following table lists the error codes than may be returned by pcre_compile2(), along with the error messages that may be returned by -both compiling functions. As PCRE has developed, some error codes have fallen -out of use. To avoid confusion, they have not been re-used. +both compiling functions. Note that error messages are always 8-bit ASCII +strings, even in 16-bit mode. As PCRE has developed, some error codes have +fallen out of use. To avoid confusion, they have not been re-used.

    0  no error
    1  \ at end of pattern
@@ -765,26 +869,26 @@
   29  (?R or (?[+-]digits must be followed by )
   30  unknown POSIX class name
   31  POSIX collating elements are not supported
-  32  this version of PCRE is not compiled with PCRE_UTF8 support
+  32  this version of PCRE is compiled without UTF support
   33  [this code is not in use]
   34  character value in \x{...} sequence is too large
   35  invalid condition (?(0)
   36  \C not allowed in lookbehind assertion
-  37  PCRE does not support \L, \l, \N, \U, or \u
+  37  PCRE does not support \L, \l, \N{name}, \U, or \u
   38  number after (?C is > 255
   39  closing ) for (?C expected
   40  recursive call could loop indefinitely
   41  unrecognized character after (?P
   42  syntax error in subpattern name (missing terminator)
   43  two named subpatterns have the same name
-  44  invalid UTF-8 string
+  44  invalid UTF-8 string (specifically UTF-8)
   45  support for \P, \p, and \X has not been compiled
   46  malformed \P or \p sequence
   47  unknown property name after \P or \p
   48  subpattern name is too long (maximum 32 characters)
   49  too many named subpatterns (maximum 10000)
   50  [this code is not in use]
-  51  octal value is greater than \377 (not in UTF-8 mode)
+  51  octal value is greater than \377 in 8-bit non-UTF-8 mode
   52  internal error: overran compiling workspace
   53  internal error: previously-checked referenced subpattern
         not found
@@ -803,12 +907,22 @@
   65  different names for subpatterns of the same number are
         not allowed
   66  (*MARK) must have an argument
-  67  this version of PCRE is not compiled with PCRE_UCP support
+  67  this version of PCRE is not compiled with Unicode property
+        support
+  68  \c must be followed by an ASCII character
+  69  \k is not followed by a braced, angle-bracketed, or quoted name
+  70  internal error: unknown opcode in find_fixedlength()
+  71  \N is not supported in a class
+  72  too many forward references
+  73  disallowed Unicode code point (>= 0xd800 && <= 0xdfff)
+  74  invalid UTF-16 string (specifically UTF-16)
+  75  name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+  76  character value in \u.... sequence is too large
 
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. -

-
STUDYING A PATTERN
+

+
STUDYING A PATTERN

pcre_extra *pcre_study(const pcre *code, int options const char **errptr); @@ -837,8 +951,28 @@ pcre_dfa_exec(), it must set up its own pcre_extra block.

-The second argument of pcre_study() contains option bits. At present, no -options are defined, and this argument should always be zero. +The second argument of pcre_study() contains option bits. There are three +options: +

+  PCRE_STUDY_JIT_COMPILE
+  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+
+If any of these are set, and the just-in-time compiler is available, the +pattern is further compiled into machine code that executes much faster than +the pcre_exec() interpretive matching function. If the just-in-time +compiler is not available, these options are ignored. All other bits in the +options argument must be zero. +

+

+JIT compilation is a heavyweight optimization. It can take some time for +patterns to be analyzed, and for one-off matches and simple patterns the +benefit of faster execution might be offset by a much slower study time. +Not all patterns can be optimized by the JIT compiler. For those that cannot be +handled, matching automatically falls back to the pcre_exec() +interpreter. For more details, see the +pcrejit +documentation.

The third argument for pcre_study() is a pointer for an error message. If @@ -849,13 +983,30 @@ sure that it has run successfully.

-This is a typical call to pcre_study(): +When you are finished with a pattern, you can free the memory used for the +study data by calling pcre_free_study(). This function was added to the +API for release 8.20. For earlier versions, the memory could be freed with +pcre_free(), just like the pattern itself. This will still work in cases +where JIT optimization is not used, but it is advisable to change to the new +function when convenient. +

+

+This is a typical way in which pcre_study() is used (except that in a +real application there should be tests for errors):

-  pcre_extra *pe;
-  pe = pcre_study(
+  int rc;
+  pcre *re;
+  pcre_extra *sd;
+  re = pcre_compile("pattern", 0, &error, &erroroffset, NULL);
+  sd = pcre_study(
     re,             /* result of pcre_compile() */
-    0,              /* no options exist */
+    0,              /* no options */
     &error);        /* set to NULL or points to a message */
+  rc = pcre_exec(   /* see below for details of pcre_exec() options */
+    re, sd, "subject", 7, 0, 0, ovector, 30);
+  ...
+  pcre_free_study(sd);
+  pcre_free(re);
 
Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not @@ -869,28 +1020,31 @@ Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start -matching. +matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.)

-The two optimizations just described can be disabled by setting the -PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or -pcre_dfa_exec(). You might want to do this if your pattern contains -callouts or (*MARK), and you want to make use of these facilities in cases -where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE +These two optimizations apply to both pcre_exec() and +pcre_dfa_exec(), and the information is also used by the JIT compiler. +The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option +when calling pcre_exec() or pcre_dfa_exec(), but if this is done, +JIT execution is also disabled. You might want to do this if your pattern +contains callouts or (*MARK) and you want to make use of these facilities in +cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE below.

-
LOCALE SUPPORT
+
LOCALE SUPPORT

PCRE handles caseless matching, and determines whether characters are letters, digits, or whatever, by reference to a set of tables, indexed by character -value. When running in UTF-8 mode, this applies only to characters with codes -less than 128. By default, higher-valued codes never match escapes such as \w -or \d, but they can be tested with \p if PCRE is built with Unicode character -property support. Alternatively, the PCRE_UCP option can be set at compile -time; this causes \w and friends to use Unicode property support instead of -built-in tables. The use of locales with Unicode is discouraged. If you are -handling characters with codes greater than 128, you should either use UTF-8 -and Unicode, or use locales, but not try to mix the two. +value. When running in UTF-8 mode, this applies only to characters +with codes less than 128. By default, higher-valued codes never match escapes +such as \w or \d, but they can be tested with \p if PCRE is built with +Unicode character property support. Alternatively, the PCRE_UCP option can be +set at compile time; this causes \w and friends to use Unicode property +support instead of built-in tables. The use of locales with Unicode is +discouraged. If you are handling characters with codes greater than 128, you +should either use UTF-8 and Unicode, or use locales, but not try to mix the +two.

PCRE contains an internal set of tables that are used when the final argument @@ -939,16 +1093,16 @@ this facility could be used to match a pattern in a different locale from the one in which it was compiled. Passing table pointers at run time is discussed below in the section on matching a pattern. -

-
INFORMATION ABOUT A PATTERN
+

+
INFORMATION ABOUT A PATTERN

int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where);

The pcre_fullinfo() function returns information about a compiled -pattern. It replaces the obsolete pcre_info() function, which is -nevertheless retained for backwards compability (and is documented below). +pattern. It replaces the pcre_info() function, which was removed from the +library at version 8.30, after more than 10 years of obsolescence.

The first argument for pcre_fullinfo() is a pointer to the compiled @@ -958,20 +1112,24 @@ to receive the data. The yield of the function is zero for success, or one of the following negative numbers:

-  PCRE_ERROR_NULL       the argument code was NULL
-                        the argument where was NULL
-  PCRE_ERROR_BADMAGIC   the "magic number" was not found
-  PCRE_ERROR_BADOPTION  the value of what was invalid
+  PCRE_ERROR_NULL           the argument code was NULL
+                            the argument where was NULL
+  PCRE_ERROR_BADMAGIC       the "magic number" was not found
+  PCRE_ERROR_BADENDIANNESS  the pattern was compiled with different
+                            endianness
+  PCRE_ERROR_BADOPTION      the value of what was invalid
 
The "magic number" is placed at the start of each compiled pattern as an simple -check against passing an arbitrary memory pointer. Here is a typical call of -pcre_fullinfo(), to obtain the length of the compiled pattern: +check against passing an arbitrary memory pointer. The endianness error can +occur if a compiled pattern is saved and reloaded on a different host. Here is +a typical call of pcre_fullinfo(), to obtain the length of the compiled +pattern:
   int rc;
   size_t length;
   rc = pcre_fullinfo(
     re,               /* result of pcre_compile() */
-    pe,               /* result of pcre_study(), or NULL */
+    sd,               /* result of pcre_study(), or NULL */
     PCRE_INFO_SIZE,   /* what is required */
     &length);         /* where to put the data */
 
@@ -999,14 +1157,19 @@
   PCRE_INFO_FIRSTBYTE
 
-Return information about the first byte of any matched string, for a -non-anchored pattern. The fourth argument should point to an int -variable. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name is -still recognized for backwards compatibility.) +Return information about the first data unit of any matched string, for a +non-anchored pattern. (The name of this option refers to the 8-bit library, +where data units are bytes.) The fourth argument should point to an int +variable. +

+

+If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), its value is returned. In the 8-bit library, the +value is always less than 256; in the 16-bit library the value can be up to +0xffff.

-If there is a fixed first byte, for example, from a pattern such as -(cat|cow|coyote), its value is returned. Otherwise, if either +If there is no fixed first value, and if either

(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch @@ -1024,7 +1187,7 @@ PCRE_INFO_FIRSTTABLE

If the pattern was studied, and this resulted in the construction of a 256-bit -table indicating a fixed set of bytes for the first byte in any matching +table indicating a fixed set of values for the first data unit in any matching string, a pointer to the table is returned. Otherwise NULL is returned. The fourth argument should point to an unsigned char * variable.
@@ -1040,22 +1203,45 @@
 0. The fourth argument should point to an int variable. (?J) and
 (?-J) set and unset the local PCRE_DUPNAMES option, respectively.
 
+  PCRE_INFO_JIT
+
+Return 1 if the pattern was studied with one of the JIT options, and +just-in-time compiling was successful. The fourth argument should point to an +int variable. A return value of 0 means that JIT support is not available +in this version of PCRE, or that the pattern was not studied with a JIT option, +or that the JIT compiler could not handle this particular pattern. See the +pcrejit +documentation for details of what can and cannot be handled. +
+  PCRE_INFO_JITSIZE
+
+If the pattern was successfully studied with a JIT option, return the size of +the JIT compiled code, otherwise return zero. The fourth argument should point +to a size_t variable. +
   PCRE_INFO_LASTLITERAL
 
-Return the value of the rightmost literal byte that must exist in any matched -string, other than at its start, if such a byte has been recorded. The fourth -argument should point to an int variable. If there is no such byte, -1 is -returned. For anchored patterns, a last literal byte is recorded only if it -follows something of variable length. For example, for the pattern +Return the value of the rightmost literal data unit that must exist in any +matched string, other than at its start, if such a value has been recorded. The +fourth argument should point to an int variable. If there is no such +value, -1 is returned. For anchored patterns, a last literal value is recorded +only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1.
+  PCRE_INFO_MAXLOOKBEHIND
+
+Return the number of characters (NB not bytes) in the longest lookbehind +assertion in the pattern. Note that the simple assertions \b and \B require a +one-character lookbehind. This information is useful when doing multi-segment +matching using the partial matching facilities. +
   PCRE_INFO_MINLENGTH
 
If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The -value is a number of characters, not bytes (this may be relevant in UTF-8 -mode). The fourth argument should point to an int variable. A +value is a number of characters, which in UTF-8 mode may be different from the +number of bytes. The fourth argument should point to an int variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at least that long. @@ -1079,9 +1265,11 @@ the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each entry; both of these return an int value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first -entry of the table (a pointer to char). The first two bytes of each entry -are the number of the capturing parenthesis, most significant byte first. The -rest of the entry is the corresponding name, zero terminated. +entry of the table. This is a pointer to char in the 8-bit library, where +the first two bytes of each entry are the number of the capturing parenthesis, +most significant byte first. In the 16-bit library, the pointer points to +16-bit data units, the first of which contains the parenthesis number. The rest +of the entry is the corresponding name, zero terminated.

The names are in alphabetical order. Duplicate names may appear if (?| is used @@ -1097,8 +1285,8 @@

As a simple example of the name/number table, consider the following pattern -(assume PCRE_EXTENDED is set, so white space - including newlines - is -ignored): +after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white +space - including newlines - is ignored):

   (?<date> (?<year>(\d\d)?\d\d) - (?<month>\d\d) - (?<day>\d\d) )
 
@@ -1148,45 +1336,29 @@
   PCRE_INFO_SIZE
 
-Return the size of the compiled pattern, that is, the value that was passed as -the argument to pcre_malloc() when PCRE was getting memory in which to -place the compiled data. The fourth argument should point to a size_t -variable. +Return the size of the compiled pattern in bytes (for both libraries). The +fourth argument should point to a size_t variable. This value does not +include the size of the pcre structure that is returned by +pcre_compile(). The value that is passed as the argument to +pcre_malloc() when pcre_compile() is getting memory in which to +place the compiled data is the value returned by this option plus the size of +the pcre structure. Studying a compiled pattern, with or without JIT, +does not alter the value returned by this option.
   PCRE_INFO_STUDYSIZE
 
-Return the size of the data block pointed to by the study_data field in -a pcre_extra block. That is, it is the value that was passed to -pcre_malloc() when PCRE was getting memory into which to place the data -created by pcre_study(). If pcre_extra is NULL, or there is no +Return the size in bytes of the data block pointed to by the study_data +field in a pcre_extra block. If pcre_extra is NULL, or there is no study data, zero is returned. The fourth argument should point to a -size_t variable. -

-
OBSOLETE INFO FUNCTION
-

-int pcre_info(const pcre *code, int *optptr, int -*firstcharptr); -

-

-The pcre_info() function is now obsolete because its interface is too -restrictive to return all the available data about a compiled pattern. New -programs should use pcre_fullinfo() instead. The yield of -pcre_info() is the number of capturing subpatterns, or one of the -following negative numbers: -

-  PCRE_ERROR_NULL       the argument code was NULL
-  PCRE_ERROR_BADMAGIC   the "magic number" was not found
-
-If the optptr argument is not NULL, a copy of the options with which the -pattern was compiled is placed in the integer it points to (see -PCRE_INFO_OPTIONS above). -

-

-If the pattern is not anchored and the firstcharptr argument is not NULL, -it is used to pass back information about the first character of any matched -string (see PCRE_INFO_FIRSTBYTE above). +size_t variable. The study_data field is set by pcre_study() +to record information that will speed up matching (see the section entitled +"Studying a pattern" +above). The format of the study_data block is private, but its length +is made available via this option so that it can be saved and restored (see the +pcreprecompile +documentation for details).

-
REFERENCE COUNTS
+
REFERENCE COUNTS

int pcre_refcount(pcre *code, int adjust);

@@ -1210,7 +1382,7 @@ pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.)

-
MATCHING A PATTERN: THE TRADITIONAL FUNCTION
+
MATCHING A PATTERN: THE TRADITIONAL FUNCTION

int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, @@ -1220,9 +1392,14 @@ The function pcre_exec() is called to match a subject string against a compiled pattern, which is passed in the code argument. If the pattern was studied, the result of the study should be passed in the -extra argument. This function is the main matching facility of the -library, and it operates in a Perl-like manner. For specialist use there is -also an alternative matching function, which is described +extra argument. You can call pcre_exec() with the same code +and extra arguments as many times as you like, in order to match +different subject strings with the same pattern. +

+

+This function is the main matching facility of the library, and it operates in +a Perl-like manner. For specialist use there is also an alternative matching +function, which is described below in the section about the pcre_dfa_exec() function.

@@ -1263,26 +1440,33 @@
   unsigned long int flags;
   void *study_data;
+  void *executable_jit;
   unsigned long int match_limit;
   unsigned long int match_limit_recursion;
   void *callout_data;
   const unsigned char *tables;
   unsigned char **mark;
 
-The flags field is a bitmap that specifies which of the other fields -are set. The flag bits are: +In the 16-bit version of this structure, the mark field has type +"PCRE_UCHAR16 **". +

+

+The flags field is used to specify which of the other fields are set. The +flag bits are:

-  PCRE_EXTRA_STUDY_DATA
+  PCRE_EXTRA_CALLOUT_DATA
+  PCRE_EXTRA_EXECUTABLE_JIT
+  PCRE_EXTRA_MARK
   PCRE_EXTRA_MATCH_LIMIT
   PCRE_EXTRA_MATCH_LIMIT_RECURSION
-  PCRE_EXTRA_CALLOUT_DATA
+  PCRE_EXTRA_STUDY_DATA
   PCRE_EXTRA_TABLES
-  PCRE_EXTRA_MARK
 
-Other flag bits should be set to zero. The study_data field is set in the -pcre_extra block that is returned by pcre_study(), together with -the appropriate flag bit. You should not set this yourself, but you may add to -the block by setting the other fields and their corresponding flag bits. +Other flag bits should be set to zero. The study_data field and sometimes +the executable_jit field are set in the pcre_extra block that is +returned by pcre_study(), together with the appropriate flag bits. You +should not set these yourself, but you may add to the block by setting other +fields and their corresponding flag bits.

The match_limit field provides a means of preventing PCRE from using up a @@ -1291,12 +1475,19 @@ classic example is a pattern that uses nested unlimited repeats.

-Internally, PCRE uses a function called match() which it calls repeatedly -(sometimes recursively). The limit set by match_limit is imposed on the -number of times this function is called during a match, which has the effect of -limiting the amount of backtracking that can take place. For patterns that are -not anchored, the count restarts from zero for each position in the subject -string. +Internally, pcre_exec() uses a function called match(), which it +calls repeatedly (sometimes recursively). The limit set by match_limit is +imposed on the number of times this function is called during a match, which +has the effect of limiting the amount of backtracking that can take place. For +patterns that are not anchored, the count restarts from zero for each position +in the subject string. +

+

+When pcre_exec() is called with a pattern that was successfully studied +with a JIT option, the way that the matching is executed is entirely different. +However, there is still the possibility of runaway matching that goes on for a +very long time, and so the match_limit value is also used in this case +(but in a different way) to limit how long the matching can continue.

The default value for the limit can be set when PCRE is built; the default @@ -1314,9 +1505,10 @@ This limit is of use only if it is set smaller than match_limit.

-Limiting the recursion depth limits the amount of stack that can be used, or, -when PCRE has been compiled to use memory on the heap instead of the stack, the -amount of heap memory that can be used. +Limiting the recursion depth limits the amount of machine stack that can be +used, or, when PCRE has been compiled to use memory on the heap instead of the +stack, the amount of heap memory that can be used. This limit is not relevant, +and is ignored, when matching is done using JIT compiled code.

The default value for match_limit_recursion can be set when PCRE is @@ -1347,13 +1539,13 @@

If PCRE_EXTRA_MARK is set in the flags field, the mark field must -be set to point to a char * variable. If the pattern contains any +be set to point to a suitable variable. If the pattern contains any backtracking control verbs such as (*MARK:NAME), and the execution ends up with a name to pass back, a pointer to the name string (zero terminated) is placed in the variable pointed to by the mark field. The names are within the compiled pattern; if you wish to retain such a name you must copy it before freeing the memory of a compiled pattern. If there is no name to pass back, the -variable pointed to by the mark field set to NULL. For details of the +variable pointed to by the mark field is set to NULL. For details of the backtracking control verbs, see the section entitled "Backtracking control" in the @@ -1367,8 +1559,16 @@ The unused bits of the options argument for pcre_exec() must be zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, -PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and -PCRE_PARTIAL_HARD. +PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and +PCRE_PARTIAL_SOFT. +

+

+If the pattern was successfully studied with one of the just-in-time (JIT) +compile options, the only supported options for JIT execution are +PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, +PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an +unsupported option is used, JIT execution is disabled and the normal +interpretive code in pcre_exec() is run.

   PCRE_ANCHORED
 
@@ -1491,7 +1691,8 @@ "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching -time. +time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, +matching is always done using interpretively.

Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. @@ -1525,17 +1726,21 @@

When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when pcre_exec() is subsequently called. -The value of startoffset is also checked to ensure that it points to the -start of a UTF-8 character. There is a discussion about the validity of UTF-8 -strings in the -section on UTF-8 support -in the main -pcre -page. If an invalid UTF-8 sequence of bytes is found, pcre_exec() returns -the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is -a truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORTUTF8. If -startoffset contains a value that does not point to the start of a UTF-8 -character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is +The entire string is checked before any other processing takes place. The value +of startoffset is also checked to ensure that it points to the start of a +UTF-8 character. There is a discussion about the +validity of UTF-8 strings +in the +pcreunicode +page. If an invalid sequence of bytes is found, pcre_exec() returns the +error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a +truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both +cases, information about the precise nature of the error may also be returned +(see the descriptions of these errors in the section entitled \fIError return +values from\fP pcre_exec() +below). +If startoffset contains a value that does not point to the start of a +UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned.

@@ -1544,9 +1749,9 @@ calling pcre_exec(). You might want to do this for the second and subsequent calls to pcre_exec() if you are making repeated calls to find all the matches in a single subject string. However, you should be sure that -the value of startoffset points to the start of a UTF-8 character (or the -end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an -invalid UTF-8 string as a subject or an invalid value of startoffset is +the value of startoffset points to the start of a character (or the end +of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an +invalid string as a subject or an invalid value of startoffset is undefined. Your program may crash.

   PCRE_PARTIAL_HARD
@@ -1581,7 +1786,7 @@
 

The subject string is passed to pcre_exec() as a pointer in -subject, a length (in bytes) in length, and a starting byte offset +subject, a length in bytes in length, and a starting byte offset in startoffset. If this is negative or greater than the length of the subject, pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is zero, the search for a match starts at the beginning of the subject, @@ -1676,12 +1881,28 @@

If the vector is too small to hold all the captured substring offsets, it is used as far as possible (up to two-thirds of its length), and the function -returns a value of zero. If the substring offsets are not of interest, -pcre_exec() may be called with ovector passed as NULL and -ovecsize as zero. However, if the pattern contains back references and -the ovector is not big enough to remember the related substrings, PCRE -has to get additional memory for use during matching. Thus it is usually -advisable to supply an ovector. +returns a value of zero. If neither the actual string matched nor any captured +substrings are of interest, pcre_exec() may be called with ovector +passed as NULL and ovecsize as zero. However, if the pattern contains +back references and the ovector is not big enough to remember the related +substrings, PCRE has to get additional memory for use during matching. Thus it +is usually advisable to supply an ovector of reasonable size. +

+

+There are some cases where zero is returned (indicating vector overflow) when +in fact the vector is exactly the right size for the final match. For example, +consider the pattern +

+  (a)(?:(b)c|bd)
+
+If a vector of 6 elements (allowing for only 1 captured substring) is given +with subject string "abd", pcre_exec() will try to set the second +captured string, thereby recording a vector overflow, before failing to match +"c" and backing up to try the second alternative. The zero return, however, +does correctly indicate that the maximum number of slots (namely 2) have been +filled. In similar cases where there is temporary overflow, but the final +number of used slots is actually less than the maximum, a non-zero value is +returned.

The pcre_fullinfo() function can be used to find out how many capturing @@ -1706,11 +1927,11 @@ (assuming the vector is large enough, of course) are set to -1.

-Note: Elements of ovector that do not correspond to capturing -parentheses in the pattern are never changed. That is, if a pattern contains -n capturing parentheses, no more than ovector[0] to -ovector[2n+1] are set by pcre_exec(). The other elements retain -whatever values they previously had. +Note: Elements in the first two-thirds of ovector that do not +correspond to capturing parentheses in the pattern are never changed. That is, +if a pattern contains n capturing parentheses, no more than +ovector[0] to ovector[2n+1] are set by pcre_exec(). The other +elements (in the first two-thirds) retain whatever values they previously had.

Some convenience functions are provided for extracting the captured substrings @@ -1784,14 +2005,21 @@

   PCRE_ERROR_BADUTF8        (-10)
 
-A string that contains an invalid UTF-8 byte sequence was passed as a subject. -However, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 -character at the end of the subject, PCRE_ERROR_SHORTUTF8 is used instead. +A string that contains an invalid UTF-8 byte sequence was passed as a subject, +and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector +(ovecsize) is at least 2, the byte offset to the start of the the invalid +UTF-8 character is placed in the first element, and a reason code is placed in +the second element. The reason codes are listed in the +following section. +For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a +truncated UTF-8 character at the end of the subject (reason codes 1 to 5), +PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
   PCRE_ERROR_BADUTF8_OFFSET (-11)
 
-The UTF-8 byte sequence that was passed as a subject was valid, but the value -of startoffset did not point to the beginning of a UTF-8 character or the +The UTF-8 byte sequence that was passed as a subject was checked and found to +be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of +startoffset did not point to the beginning of a UTF-8 character or the end of the subject.
   PCRE_ERROR_PARTIAL        (-12)
@@ -1833,14 +2061,126 @@
 
   PCRE_ERROR_SHORTUTF8      (-25)
 
-The subject string ended with an incomplete (truncated) UTF-8 character, and -the PCRE_PARTIAL_HARD option was set. Without this option, PCRE_ERROR_BADUTF8 -is returned in this situation. +This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string +ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. +Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in +fact sufficient to detect this case, but this special error code for +PCRE_PARTIAL_HARD precedes the implementation of returned information; it is +retained for backwards compatibility. +
+  PCRE_ERROR_RECURSELOOP    (-26)
+
+This error is returned when pcre_exec() detects a recursion loop within +the pattern. Specifically, it means that either the whole pattern or a +subpattern has been called recursively for the second time at the same position +in the subject string. Some simple patterns that might do this are detected and +faulted at compile time, but more complicated cases, in particular mutual +recursions between two different subpatterns, cannot be detected until run +time. +
+  PCRE_ERROR_JIT_STACKLIMIT (-27)
+
+This error is returned when a pattern that was successfully studied using a +JIT compile option is being matched, but the memory available for the +just-in-time processing stack is not large enough. See the +pcrejit +documentation for more details. +
+  PCRE_ERROR_BADMODE        (-28)
+
+This error is given if a pattern that was compiled by the 8-bit library is +passed to a 16-bit library function, or vice versa. +
+  PCRE_ERROR_BADENDIANNESS  (-29)
+
+This error is given if a pattern that was compiled and saved is reloaded on a +host with different endianness. The utility function +pcre_pattern_to_host_byte_order() can be used to convert such a pattern +so that it runs on the new host. +

+

+Error numbers -16 to -20, -22, and -30 are not used by pcre_exec(). +

+
+Reason codes for invalid UTF-8 strings +
+

+This section applies only to the 8-bit library. The corresponding information +for the 16-bit library is given in the +pcre16 +page.

-Error numbers -16 to -20 and -22 are not used by pcre_exec(). +When pcre_exec() returns either PCRE_ERROR_BADUTF8 or +PCRE_ERROR_SHORTUTF8, and the size of the output vector (ovecsize) is at +least 2, the offset of the start of the invalid UTF-8 character is placed in +the first output vector element (ovector[0]) and a reason code is placed +in the second element (ovector[1]). The reason codes are given names in +the pcre.h header file: +

+  PCRE_UTF8_ERR1
+  PCRE_UTF8_ERR2
+  PCRE_UTF8_ERR3
+  PCRE_UTF8_ERR4
+  PCRE_UTF8_ERR5
+
+The string ends with a truncated UTF-8 character; the code specifies how many +bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be +no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279) +allows for up to 6 bytes, and this is checked first; hence the possibility of +4 or 5 missing bytes. +
+  PCRE_UTF8_ERR6
+  PCRE_UTF8_ERR7
+  PCRE_UTF8_ERR8
+  PCRE_UTF8_ERR9
+  PCRE_UTF8_ERR10
+
+The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the +character do not have the binary value 0b10 (that is, either the most +significant bit is 0, or the next bit is 1). +
+  PCRE_UTF8_ERR11
+  PCRE_UTF8_ERR12
+
+A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; +these code points are excluded by RFC 3629. +
+  PCRE_UTF8_ERR13
+
+A 4-byte character has a value greater than 0x10fff; these code points are +excluded by RFC 3629. +
+  PCRE_UTF8_ERR14
+
+A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of +code points are reserved by RFC 3629 for use with UTF-16, and so are excluded +from UTF-8. +
+  PCRE_UTF8_ERR15
+  PCRE_UTF8_ERR16
+  PCRE_UTF8_ERR17
+  PCRE_UTF8_ERR18
+  PCRE_UTF8_ERR19
+
+A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a +value that can be represented by fewer bytes, which is invalid. For example, +the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just +one byte. +
+  PCRE_UTF8_ERR20
+
+The two most significant bits of the first byte of a character have the binary +value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a +byte can only validly occur as the second or subsequent byte of a multi-byte +character. +
+  PCRE_UTF8_ERR21
+
+The first byte of a character has the value 0xfe or 0xff. These values can +never occur in a valid UTF-8 string.

-
EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
+
EXTRACTING CAPTURED SUBSTRINGS BY NUMBER

int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, @@ -1935,7 +2275,7 @@ pcre_free directly; it is for these cases that the functions are provided.

-
EXTRACTING CAPTURED SUBSTRINGS BY NAME
+
EXTRACTING CAPTURED SUBSTRINGS BY NAME

int pcre_get_stringnumber(const pcre *code, const char *name); @@ -1999,7 +2339,7 @@ numbers. For this reason, the use of different names for subpatterns of the same number causes an error at compile time.

-
DUPLICATE SUBPATTERN NAMES
+
DUPLICATE SUBPATTERN NAMES

int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last); @@ -2032,11 +2372,12 @@ has run, they point to the first and last entries in the name-to-number table for the given name. The function itself returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if there are none. The format of the table is -described above in the section entitled Information about a pattern. +described above in the section entitled Information about a pattern +above. Given all the relevant entries for the name, you can extract each of their numbers, and hence the captured data, if any.

-
FINDING ALL POSSIBLE MATCHES
+
FINDING ALL POSSIBLE MATCHES

The traditional matching function uses a similar algorithm to Perl, which stops when it finds the first match, starting at a given point in the subject. If you @@ -2054,8 +2395,32 @@ substring. Then return 1, which forces pcre_exec() to backtrack and try other alternatives. Ultimately, when it runs out of matches, pcre_exec() will yield PCRE_ERROR_NOMATCH. +

+
OBTAINING AN ESTIMATE OF STACK USAGE
+

+Matching certain patterns using pcre_exec() can use a lot of process +stack, which in certain environments can be rather limited in size. Some users +find it helpful to have an estimate of the amount of stack that is used by +pcre_exec(), to help them set recursion limits, as described in the +pcrestack +documentation. The estimate that is output by pcretest when called with +the -m and -C options is obtained by calling pcre_exec with +the values NULL, NULL, NULL, -999, and -999 for its first five arguments. +

+

+Normally, if its first argument is NULL, pcre_exec() immediately returns +the negative error code PCRE_ERROR_NULL, but with this special combination of +arguments, it returns instead a negative number whose absolute value is the +approximate stack frame size in bytes. (A negative number is used so that it is +clear that no match has happened.) The value is approximate because in some +cases, recursive calls to pcre_exec() occur when there are one or two +additional variables on the stack. +

+

+If PCRE has been compiled to use the heap instead of the stack for recursion, +the value returned is the size of each block that is obtained from the heap.

-
MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
+
MATCHING A PATTERN: THE ALTERNATIVE FUNCTION

int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, @@ -2186,7 +2551,8 @@ The strings are returned in reverse order of length; that is, the longest matching string is given first. If there were too many matches to fit into ovector, the yield of the function is zero, and the vector is filled with -the longest matches. +the longest matches. Unlike pcre_exec(), pcre_dfa_exec() can use +the entire ovector for returning matched strings.


Error returns from pcre_dfa_exec() @@ -2213,8 +2579,9 @@ PCRE_ERROR_DFA_UMLIMIT (-18)
This return is given if pcre_dfa_exec() is called with an extra -block that contains a setting of the match_limit field. This is not -supported (it is meaningless). +block that contains a setting of the match_limit or +match_limit_recursion fields. This is not supported (these fields are +meaningless for DFA matching).
   PCRE_ERROR_DFA_WSSIZE     (-19)
 
@@ -2227,14 +2594,21 @@ recursively, using private vectors for ovector and workspace. This error is given if the output vector is not large enough. This should be extremely rare, as a vector of size 1000 is used. +
+  PCRE_ERROR_DFA_BADRESTART (-30)
+
+When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, +some plausibility checks are made on the contents of the workspace, which +should contain data about the previous partial match. If any of these checks +fail, this error is given.

-
SEE ALSO
+
SEE ALSO

-pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), +pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3).

-
AUTHOR
+
AUTHOR

Philip Hazel
@@ -2243,11 +2617,11 @@ Cambridge CB2 3QH, England.

-
REVISION
+
REVISION

-Last updated: 21 November 2010 +Last updated: 17 June 2012
-Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrebuild.html pcre3-8.31/doc/html/pcrebuild.html --- pcre3-8.12/doc/html/pcrebuild.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrebuild.html 2012-07-06 09:55:27.000000000 +0000 @@ -14,23 +14,26 @@


PCRE BUILD-TIME OPTIONS

@@ -61,45 +64,85 @@ --enable and --disable always come in pairs, so the complementary option always exists as well, but as it specifies the default, it is not described.

-
C++ SUPPORT
+
BUILDING 8-BIT and 16-BIT LIBRARIES

-By default, the configure script will search for a C++ compiler and C++ -header files. If it finds them, it automatically builds the C++ wrapper library -for PCRE. You can disable this by adding +By default, a library called libpcre is built, containing functions that +take string arguments contained in vectors of bytes, either as single-byte +characters, or interpreted as UTF-8 strings. You can also build a separate +library, called libpcre16, in which strings are contained in vectors of +16-bit data units and interpreted either as single-unit characters or UTF-16 +strings, by adding +

+  --enable-pcre16
+
+to the configure command. If you do not want the 8-bit library, add +
+  --disable-pcre8
+
+as well. At least one of the two libraries must be built. Note that the C++ and +POSIX wrappers are for the 8-bit library only, and that pcregrep is an +8-bit program. None of these are built if you select only the 16-bit library. +

+
BUILDING SHARED AND STATIC LIBRARIES
+

+The PCRE building process uses libtool to build both shared and static +Unix libraries by default. You can suppress one of these by adding one of +

+  --disable-shared
+  --disable-static
+
+to the configure command, as required. +

+
C++ SUPPORT
+

+By default, if the 8-bit library is being built, the configure script +will search for a C++ compiler and C++ header files. If it finds them, it +automatically builds the C++ wrapper library (which supports only 8-bit +strings). You can disable this by adding

   --disable-cpp
 
to the configure command.

-
UTF-8 SUPPORT
+
UTF-8 and UTF-16 SUPPORT

-To build PCRE with support for UTF-8 Unicode character strings, add +To build PCRE with support for UTF Unicode character strings, add

-  --enable-utf8
+  --enable-utf
 
-to the configure command. Of itself, this does not make PCRE treat -strings as UTF-8. As well as compiling PCRE with this option, you also have -have to set the PCRE_UTF8 option when you call the pcre_compile() -or pcre_compile2() functions. +to the configure command. This setting applies to both libraries, adding +support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit +library. There are no separate options for enabling UTF-8 and UTF-16 +independently because that would allow ridiculous settings such as requesting +UTF-16 support while building only the 8-bit library. It is not possible to +build one library with UTF support and the other without in the same +configuration. (For backwards compatibility, --enable-utf8 is a synonym of +--enable-utf.) +

+

+Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As +well as compiling PCRE with this option, you also have have to set the +PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling +functions.

-If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE expects -its input to be either ASCII or UTF-8 (depending on the runtime option). It is +If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects +its input to be either ASCII or UTF-8 (depending on the run-time option). It is not possible to support both EBCDIC and UTF-8 codes in the same version of the -library. Consequently, --enable-utf8 and --enable-ebcdic are mutually +library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive.

-
UNICODE CHARACTER PROPERTY SUPPORT
+
UNICODE CHARACTER PROPERTY SUPPORT

-UTF-8 support allows PCRE to process character values greater than 255 in the -strings that it handles. On its own, however, it does not provide any +UTF support allows the libraries to process character codepoints up to 0x10ffff +in the strings that they handle. On its own, however, it does not provide any facilities for accessing the properties of such characters. If you want to be able to use the pattern escapes \P, \p, and \X, which refer to Unicode character properties, you must add

   --enable-unicode-properties
 
-to the configure command. This implies UTF-8 support, even if you have +to the configure command. This implies UTF support, even if you have not explicitly requested it.

@@ -109,7 +152,24 @@ pcrepattern documentation.

-
CODE VALUE OF NEWLINE
+
JUST-IN-TIME COMPILER SUPPORT
+

+Just-in-time compiler support is included in the build by specifying +

+  --enable-jit
+
+This support is available only for certain hardware architectures. If this +option is set for an unsupported architecture, a compile time error occurs. +See the +pcrejit +documentation for a discussion of JIT usage. When JIT support is enabled, +pcregrep automatically makes use of it, unless you add +
+  --disable-pcregrep-jit
+
+to the "configure" command. +

+
CODE VALUE OF NEWLINE

By default, PCRE interprets the linefeed (LF) character as indicating the end of a line. This is the normal newline character on Unix-like systems. You can @@ -142,7 +202,7 @@ overridden when the library functions are called. At build time it is conventional to use the standard for your operating system.

-
WHAT \R MATCHES
+
WHAT \R MATCHES

By default, the sequence \R in a pattern matches any Unicode newline sequence, whatever has been selected as the line ending sequence. If you specify @@ -153,19 +213,9 @@ selected when PCRE is built can be overridden when the library functions are called.

-
BUILDING SHARED AND STATIC LIBRARIES
-

-The PCRE building process uses libtool to build both shared and static -Unix libraries by default. You can suppress one of these by adding one of -

-  --disable-shared
-  --disable-static
-
-to the configure command, as required. -

-
POSIX MALLOC USAGE
+
POSIX MALLOC USAGE

-When PCRE is called through the POSIX interface (see the +When the 8-bit library is called through the POSIX interface (see the pcreposix documentation), additional working storage is required for holding the pointers to capturing substrings, because PCRE requires three integers per substring, @@ -179,23 +229,24 @@

to the configure command.

-
HANDLING VERY LARGE PATTERNS
+
HANDLING VERY LARGE PATTERNS

Within a compiled pattern, offset values are used to point from one part to another (for example, from an opening parenthesis to an alternation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. Nevertheless, some people do want to -process truyl enormous patterns, so it is possible to compile PCRE to use +process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte offsets by adding a setting such as

   --with-link-size=3
 
-to the configure command. The value given must be 2, 3, or 4. Using -longer offsets slows down the operation of PCRE because it has to load -additional bytes when handling them. +to the configure command. The value given must be 2, 3, or 4. For the +16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows +down the operation of PCRE because it has to load additional data when handling +them.

-
AVOIDING EXCESSIVE STACK USAGE
+
AVOIDING EXCESSIVE STACK USAGE

When matching with the pcre_exec() function, PCRE implements backtracking by making recursive calls to an internal function called match(). In @@ -226,7 +277,7 @@ slowly when built in this way. This option affects only the pcre_exec() function; it is not relevant for pcre_dfa_exec().

-
LIMITING PCRE RESOURCE USAGE
+
LIMITING PCRE RESOURCE USAGE

Internally, PCRE has a function called match(), which it calls repeatedly (sometimes recursively) when matching a pattern with the pcre_exec() @@ -255,7 +306,7 @@

to the configure command. This value can also be overridden at run time.

-
CREATING CHARACTER TABLES AT BUILD TIME
+
CREATING CHARACTER TABLES AT BUILD TIME

PCRE uses fixed tables for processing characters whose code values are less than 256. By default, PCRE is built with a set of tables that are distributed @@ -266,13 +317,13 @@

to the configure command, the distributed tables are no longer used. Instead, a program called dftables is compiled and run. This outputs the -source for new set of tables, created in the default locale of your C runtime +source for new set of tables, created in the default locale of your C run-time system. (This method of replacing the tables does not work if you are cross compiling, because dftables is run on the local host. If you need to create alternative tables when cross compiling, you will have to do so "by hand".)

-
USING EBCDIC CODE
+
USING EBCDIC CODE

PCRE assumes by default that it will run in an environment where the character code is ASCII (or Unicode, which is a superset of ASCII). This is the case for @@ -284,9 +335,9 @@ to the configure command. This setting implies --enable-rebuild-chartables. You should only use it if you know that you are in an EBCDIC environment (for example, an IBM mainframe operating system). The ---enable-ebcdic option is incompatible with --enable-utf8. +--enable-ebcdic option is incompatible with --enable-utf.

-
PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT
+
PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT

By default, pcregrep reads all files as plain text. You can build it so that it recognizes files whose names end in .gz or .bz2, and reads @@ -299,7 +350,22 @@ relevant libraries are installed on your system. Configuration will fail if they are not.

-
PCRETEST OPTION FOR LIBREADLINE SUPPORT
+
PCREGREP BUFFER SIZE
+

+pcregrep uses an internal buffer to hold a "window" on the file it is +scanning, in order to be able to output "before" and "after" lines when it +finds a match. The size of the buffer is controlled by a parameter whose +default value is 20K. The buffer itself is three times this size, but because +of the way it is used for holding "before" lines, the longest line that is +guaranteed to be processable is the parameter size. You can change the default +parameter value by adding, for example, +

+  --with-pcregrep-bufsize=50K
+
+to the configure command. The caller of \fPpcregrep\fP can, however, +override this value by specifying a run-time option. +

+
PCRETEST OPTION FOR LIBREADLINE SUPPORT

If you add

@@ -330,11 +396,11 @@
 
immediately before the configure command.

-
SEE ALSO
+
SEE ALSO

-pcreapi(3), pcre_config(3). +pcreapi(3), pcre16, pcre_config(3).

-
AUTHOR
+
AUTHOR

Philip Hazel
@@ -343,11 +409,11 @@ Cambridge CB2 3QH, England.

-
REVISION
+
REVISION

-Last updated: 29 September 2009 +Last updated: 07 January 2012
-Copyright © 1997-2009 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrecallout.html pcre3-8.31/doc/html/pcrecallout.html --- pcre3-8.12/doc/html/pcrecallout.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrecallout.html 2012-07-06 09:55:27.000000000 +0000 @@ -25,11 +25,15 @@ int (*pcre_callout)(pcre_callout_block *);

+int (*pcre16_callout)(pcre16_callout_block *); +

+

PCRE provides a feature called "callout", which is a means of temporarily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting its entry point in the -global variable pcre_callout. By default, this variable contains NULL, -which disables all calling out. +global variable pcre_callout (pcre16_callout for the 16-bit +library). By default, this variable contains NULL, which disables all calling +out.

Within a regular expression, (?C) indicates the points at which the external @@ -39,10 +43,9 @@

   (?C1)abc(?C2)def
 
-If the PCRE_AUTO_CALLOUT option bit is set when pcre_compile() or -pcre_compile2() is called, PCRE automatically inserts callouts, all with -number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT -is used with the pattern +If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE +automatically inserts callouts, all with number 255, before each item in the +pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern
   A(\d{2}|--)
 
@@ -60,6 +63,11 @@ indicates how the pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern.

+

+The use of callouts in a pattern makes it ineligible for optimization by the +just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE +option always fails. +


MISSING CALLOUTS

You should be aware that, because of optimizations in the way PCRE matches @@ -81,33 +89,36 @@

You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE -option to pcre_compile(), pcre_exec(), or pcre_dfa_exec(), -or by starting the pattern with (*NO_START_OPT). This slows down the matching -process, but does ensure that callouts such as the example above are obeyed. +option to the matching function, or by starting the pattern with +(*NO_START_OPT). This slows down the matching process, but does ensure that +callouts such as the example above are obeyed.


THE CALLOUT INTERFACE

During matching, when PCRE reaches a callout point, the external function -defined by pcre_callout is called (if it is set). This applies to both -the pcre_exec() and the pcre_dfa_exec() matching functions. The -only argument to the callout function is a pointer to a pcre_callout -block. This structure contains the following fields: +defined by pcre_callout or pcre16_callout is called (if it is set). +This applies to both normal and DFA matching. The only argument to the callout +function is a pointer to a pcre_callout or pcre16_callout block. +These structures contains the following fields:

-  int          version;
-  int          callout_number;
-  int         *offset_vector;
-  const char  *subject;
-  int          subject_length;
-  int          start_match;
-  int          current_position;
-  int          capture_top;
-  int          capture_last;
-  void        *callout_data;
-  int          pattern_position;
-  int          next_item_length;
+  int           version;
+  int           callout_number;
+  int          *offset_vector;
+  const char   *subject;           (8-bit version)
+  PCRE_SPTR16   subject;           (16-bit version)
+  int           subject_length;
+  int           start_match;
+  int           current_position;
+  int           capture_top;
+  int           capture_last;
+  void         *callout_data;
+  int           pattern_position;
+  int           next_item_length;
+  const unsigned char *mark;       (8-bit version)
+  const PCRE_UCHAR16  *mark;       (16-bit version)
 
The version field is an integer containing the version number of the -block format. The initial version was 0; the current version is 1. The version +block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields.

@@ -118,15 +129,15 @@

The offset_vector field is a pointer to the vector of offsets that was -passed by the caller to pcre_exec() or pcre_dfa_exec(). When -pcre_exec() is used, the contents can be inspected in order to extract +passed by the caller to the matching function. When pcre_exec() or +pcre16_exec() is used, the contents can be inspected, in order to extract substrings that have been matched so far, in the same way as for extracting -substrings after a match has completed. For pcre_dfa_exec() this field is -not useful. +substrings after a match has completed. For the DFA matching functions, this +field is not useful.

The subject and subject_length fields contain copies of the values -that were passed to pcre_exec(). +that were passed to the matching function.

The start_match field normally contains the offset within the subject at @@ -141,53 +152,59 @@ current match pointer.

-When the pcre_exec() function is used, the capture_top field -contains one more than the number of the highest numbered captured substring so -far. If no substrings have been captured, the value of capture_top is -one. This is always the case when pcre_dfa_exec() is used, because it -does not support captured substrings. +When the pcre_exec() or pcre16_exec() is used, the +capture_top field contains one more than the number of the highest +numbered captured substring so far. If no substrings have been captured, the +value of capture_top is one. This is always the case when the DFA +functions are used, because they do not support captured substrings.

The capture_last field contains the number of the most recently captured substring. If no substrings have been captured, its value is -1. This is always -the case when pcre_dfa_exec() is used. +the case for the DFA matching functions.

-The callout_data field contains a value that is passed to -pcre_exec() or pcre_dfa_exec() specifically so that it can be -passed back in callouts. It is passed in the pcre_callout field of the -pcre_extra data structure. If no such data was passed, the value of -callout_data in a pcre_callout block is NULL. There is a -description of the pcre_extra structure in the +The callout_data field contains a value that is passed to a matching +function specifically so that it can be passed back in callouts. It is passed +in the callout_data field of a pcre_extra or pcre16_extra +data structure. If no such data was passed, the value of callout_data in +a callout block is NULL. There is a description of the pcre_extra +structure in the pcreapi documentation.

-The pattern_position field is present from version 1 of the -pcre_callout structure. It contains the offset to the next item to be -matched in the pattern string. +The pattern_position field is present from version 1 of the callout +structure. It contains the offset to the next item to be matched in the pattern +string.

-The next_item_length field is present from version 1 of the -pcre_callout structure. It contains the length of the next item to be -matched in the pattern string. When the callout immediately precedes an -alternation bar, a closing parenthesis, or the end of the pattern, the length -is zero. When the callout precedes an opening parenthesis, the length is that -of the entire subpattern. +The next_item_length field is present from version 1 of the callout +structure. It contains the length of the next item to be matched in the pattern +string. When the callout immediately precedes an alternation bar, a closing +parenthesis, or the end of the pattern, the length is zero. When the callout +precedes an opening parenthesis, the length is that of the entire subpattern.

The pattern_position and next_item_length fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts.

+

+The mark field is present from version 2 of the callout structure. In +callouts from pcre_exec() or pcre16_exec() it contains a pointer to +the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or +(*THEN) item in the match, or NULL if no such items have been passed. Instances +of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In +callouts from the DFA matching functions this field always contains NULL. +


RETURN VALUES

The external callout function returns an integer to PCRE. If the value is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had failed. If the value is less than -zero, the match is abandoned, and pcre_exec() or pcre_dfa_exec() -returns the negative value. +zero, the match is abandoned, the matching function returns the negative value.

Negative values should normally be chosen from the set of PCRE_ERROR_xxx @@ -206,9 +223,9 @@


REVISION

-Last updated: 21 November 2010 +Last updated: 08 Janurary 2012
-Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrecompat.html pcre3-8.31/doc/html/pcrecompat.html --- pcre3-8.12/doc/html/pcrecompat.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrecompat.html 2012-07-06 09:55:27.000000000 +0000 @@ -21,18 +21,18 @@ versions 5.10 and above.

-1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details of what -it does have are given in the -section on UTF-8 support -in the main -pcre +1. PCRE has only a subset of Perl's Unicode support. Details of what it does +have are given in the +pcreunicode page.

-2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits -them, but they do not mean what you might think. For example, (?!a){3} does -not assert that the next three characters are not "a". It just asserts that the -next character is not "a" three times. +2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do +not mean what you might think. For example, (?!a){3} does not assert that the +next three characters are not "a". It just asserts that the next character is +not "a" three times (in principle: PCRE optimizes this to run the assertion +just once). Perl allows repeat quantifiers on other assertions such as \b, but +these do not seem to have any use.

3. Capturing subpatterns that occur inside negative lookahead assertions are @@ -49,9 +49,12 @@

5. The following Perl escape sequences are not supported: \l, \u, \L, -\U, and \N. In fact these are implemented by Perl's general string-handling -and are not part of its pattern matching engine. If any of these are -encountered by PCRE, an error is generated. +\U, and \N when followed by a character name or Unicode value. (\N on its +own, matching a non-newline character, is supported.) In fact these are +implemented by Perl's general string-handling and are not part of its pattern +matching engine. If any of these are encountered by PCRE, an error is +generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, +\U and \u are interpreted as JavaScript interprets them.

6. The Perl escape sequences \p, \P, and \X are supported only if PCRE is @@ -64,7 +67,12 @@ implement the somewhat messy concept of surrogates."

-7. PCRE does support the \Q...\E escape for quoting substrings. Characters in +7. PCRE implements a simpler version of \X than Perl, which changed to make +\X match what Unicode calls an "extended grapheme cluster". This is more +complicated than an extended Unicode sequence, which is what PCRE matches. +

+

+8. PCRE does support the \Q...\E escape for quoting substrings. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE does not have variables). Note the @@ -79,7 +87,7 @@ The \Q...\E sequence is recognized both inside and outside character classes.

-8. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) +9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pattern matching. See @@ -88,21 +96,35 @@ documentation for details.

-9. Subpatterns that are called recursively or as "subroutines" are always -treated as atomic groups in PCRE. This is like Python, but unlike Perl. There -is a discussion of an example that explains this in more detail in the +10. Subpatterns that are called as subroutines (whether or not recursively) are +always treated as atomic groups in PCRE. This is like Python, but unlike Perl. +Captured values that are set outside a subroutine call can be reference from +inside in PCRE, but not in Perl. There is a discussion that explains these +differences in more detail in the section on recursion differences from Perl in the pcrepattern page.

-10. There are some differences that are concerned with the settings of captured +11. If any of the backtracking control verbs are used in an assertion or in a +subpattern that is called as a subroutine (whether or not recursively), their +effect is confined to that subpattern; it does not extend to the surrounding +pattern. This is not always the case in Perl. In particular, if (*THEN) is +present in a group that is called as a subroutine, its action is limited to +that group, even if the group does not contain any | characters. There is one +exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is +encountered in a successful positive assertion is passed back when a +match succeeds (compare capturing parentheses in assertions). Note that such +subpatterns are processed as anchored at the point where they are tested. +

+

+12. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b".

-11. PCRE's handling of duplicate subpattern numbers and duplicate subpattern +13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external table to translate between numbers and names. In particular, a pattern such as (?|(?<a>A)|(?<b)B), @@ -113,11 +135,13 @@ an error is given at compile time.

-12. Perl recognizes comments in some places that PCRE doesn't, for example, -between the ( and ? at the start of a subpattern. +14. Perl recognizes comments in some places that PCRE does not, for example, +between the ( and ? at the start of a subpattern. If the /x modifier is set, +Perl allows white space between ( and ? but PCRE never does, even if the +PCRE_EXTENDED option is set.

-13. PCRE provides some extensions to the Perl regular expression facilities. +15. PCRE provides some extensions to the Perl regular expression facilities. Perl 5.10 includes new features that are not in earlier versions of Perl, some of which (such as named parentheses) have been in PCRE for some time. This list is with respect to Perl 5.10: @@ -161,11 +185,12 @@

(j) Patterns compiled by PCRE can be saved and re-used at a later time, even on -different hosts that have the other endianness. +different hosts that have the other endianness. However, this does not apply to +optimized data created by the just-in-time compiler.

-(k) The alternative matching function (pcre_dfa_exec()) matches in a -different way and is not Perl-compatible. +(k) The alternative matching functions (pcre_dfa_exec() and +pcre16_dfa_exec()) match in a different way and are not Perl-compatible.

(l) PCRE recognizes some special sequences such as (*CR) at the start of @@ -186,9 +211,9 @@ REVISION

-Last updated: 31 October 2010 +Last updated: 01 June 2012
-Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrecpp.html pcre3-8.31/doc/html/pcrecpp.html --- pcre3-8.12/doc/html/pcrecpp.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrecpp.html 2012-07-06 09:55:28.000000000 +0000 @@ -35,7 +35,8 @@ The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was constructed from the notes in the pcrecpp.h file, which should be consulted for -further details. +further details. Note that the C++ wrapper supports only the original 8-bit +PCRE library. There is no 16-bit support at present.


MATCHING INTERFACE

@@ -191,7 +192,7 @@ PCRE_DOTALL dot matches newlines /s PCRE_DOLLAR_ENDONLY $ matches only at end N/A PCRE_EXTRA strict escape parsing N/A - PCRE_EXTENDED ignore whitespaces /x + PCRE_EXTENDED ignore white spaces /x PCRE_UTF8 handles UTF8 chars built-in PCRE_UNGREEDY reverses * and *? N/A PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*) @@ -232,7 +233,7 @@ a RE_Options object, set the appropriate options, and pass this object to a RE constructor. Example:

-   RE_options opt;
+   RE_Options opt;
    opt.set_caseless(true);
    if (RE("HELLO", opt).PartialMatch("hello world")) ...
 
@@ -360,7 +361,7 @@


REVISION

-Last updated: 17 March 2009 +Last updated: 08 January 2012

Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcredemo.html pcre3-8.31/doc/html/pcredemo.html --- pcre3-8.12/doc/html/pcredemo.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcredemo.html 2012-07-06 09:55:28.000000000 +0000 @@ -265,7 +265,7 @@ * more than one byte. * * * * However, there is a complication concerned with newlines. When the * -* newline convention is such that CRLF is a valid newline, we want must * +* newline convention is such that CRLF is a valid newline, we must * * advance by two characters rather than one. The newline convention can * * be set in the regex by (*CR), etc.; if not, we must find the default. * *************************************************************************/ diff -Nru pcre3-8.12/doc/html/pcregrep.html pcre3-8.31/doc/html/pcregrep.html --- pcre3-8.12/doc/html/pcregrep.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcregrep.html 2012-07-06 09:55:27.000000000 +0000 @@ -16,16 +16,17 @@

  • SYNOPSIS
  • DESCRIPTION
  • SUPPORT FOR COMPRESSED FILES -
  • OPTIONS -
  • ENVIRONMENT VARIABLES -
  • NEWLINES -
  • OPTIONS COMPATIBILITY -
  • OPTIONS WITH DATA -
  • MATCHING ERRORS -
  • DIAGNOSTICS -
  • SEE ALSO -
  • AUTHOR -
  • REVISION +
  • BINARY FILES +
  • OPTIONS +
  • ENVIRONMENT VARIABLES +
  • NEWLINES +
  • OPTIONS COMPATIBILITY +
  • OPTIONS WITH DATA +
  • MATCHING ERRORS +
  • DIAGNOSTICS +
  • SEE ALSO +
  • AUTHOR +
  • REVISION
    SYNOPSIS

    @@ -74,11 +75,19 @@ boundary is controlled by the -N (--newline) option.

    -Patterns are limited to 8K or BUFSIZ characters, whichever is the greater. -BUFSIZ is defined in <stdio.h>. When there is more than one pattern -(specified by the use of -e and/or -f), each pattern is applied to -each line in the order in which they are defined, except that all the -e -patterns are tried before the -f patterns. +The amount of memory used for buffering files that are being scanned is +controlled by a parameter that can be set by the --buffer-size option. +The default value for this parameter is specified when pcregrep is built, +with the default default being 20K. A block of memory three times this size is +used (to allow for buffering "before" and "after" lines). An error occurs if a +line overflows the buffer. +

    +

    +Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is +defined in <stdio.h>. When there is more than one pattern (specified by +the use of -e and/or -f), each pattern is applied to each line in +the order in which they are defined, except that all the -e patterns are +tried before the -f patterns.

    By default, as soon as one pattern matches (or fails to match when -v is @@ -117,16 +126,24 @@ appropriate support is not present, files are treated as plain text. The standard input is always so treated.

    -
    OPTIONS
    +
    BINARY FILES
    +

    +By default, a file that contains a binary zero byte within the first 1024 bytes +is identified as a binary file, and is processed specially. (GNU grep also +identifies binary files in this manner.) See the --binary-files option +for a means of changing the way binary files are handled. +

    +
    OPTIONS

    The order in which some of the options appear can affect the output. For example, both the -h and -l options affect the printing of file names. Whichever comes later in the command line will be the one that takes -effect. +effect. Numerical values for options may be followed by K or M, to signify +multiplication by 1024 or 1024*1024 respectively.

    -- -This terminate the list of options. It is useful if the next item on the +This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and filenames that start with hyphens.

    @@ -140,6 +157,11 @@ guarantees to have up to 8K of following text available for context output.

    +-a, --text +Treat binary files as text. This is equivalent to +--binary-files=text. +

    +

    -B number, --before-context=number Output number lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a @@ -149,6 +171,23 @@ guarantees to have up to 8K of preceding text available for context output.

    +--binary-files=word +Specify how binary files are to be processed. If the word is "binary" (the +default), pattern matching is performed on binary files, but the only output is +"Binary file <name> matches" when a match succeeds. If the word is "text", +which is equivalent to the -a or --text option, binary files are +processed in the same way as any other file. In this case, when a match +succeeds, the output may be binary garbage, which can have nasty effects if +sent to a terminal. If the word is "without-match", which is equivalent to the +-I option, binary files are not processed at all; they are assumed not to +be of interest. +

    +

    +--buffer-size=number +Set the parameter that controls how much memory is used for buffering files +that are being scanned. +

    +

    -C number, --context=number Output number lines of context both before and after each matching line. This is equivalent to setting both -A and -B to the same value. @@ -255,11 +294,22 @@ filename can be given as "-" to refer to the standard input. When -f is used, patterns specified on the command line using -e may also be present; they are tested before the file's patterns. However, no other pattern -is taken from the command line; all arguments are treated as file names. There -is an overall maximum of 100 patterns. Trailing white space is removed from -each line, and blank lines are ignored. An empty file contains no patterns and -therefore matches nothing. See also the comments about multiple patterns versus -a single pattern with alternatives in the description of -e above. +is taken from the command line; all arguments are treated as the names of paths +to be searched. There is an overall maximum of 100 patterns. Trailing white +space is removed from each line, and blank lines are ignored. An empty file +contains no patterns and therefore matches nothing. See also the comments about +multiple patterns versus a single pattern with alternatives in the description +of -e above. +

    +

    +--file-list=filename +Read a list of files to be searched from the given file, one per line. Trailing +white space is removed from each line, and blank lines are ignored. These files +are searched before any others that may be listed on the command line. The +filename can be given as "-" to refer to the standard input. If --file +and --file-list are both specified as "-", patterns are read first. This +is useful only when the standard input is a terminal, from which further lines +(the list of files) can be read after an end-of-file indication.

    --file-offsets @@ -291,6 +341,11 @@ type support, and then exit.

    +-I +Treat binary files as never matching. This is equivalent to +--binary-files=without-match. +

    +

    -i, --ignore-case Ignore upper/lower case distinctions during comparisons.

    @@ -421,7 +476,7 @@ which recognizes any of the preceding three types, and an "any" convention, in which any Unicode line ending sequence is assumed to end a line. The Unicode sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF -(formfeed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and +(form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029).

    @@ -442,6 +497,14 @@ --line-offsets is used.

    +--no-jit +If the PCRE library is built with support for just-in-time compiling (which +speeds up matching), pcregrep automatically makes use of this, unless it +was explicitly disabled at build time. This option can be used to disable the +use of JIT at run time. It is provided for testing and working round problems. +It should never be needed in normal use. +

    +

    -o, --only-matching Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That is, the -A, -B, and @@ -515,14 +578,14 @@ equivalent to having ^ and $ characters at the start and end of each alternative branch in every pattern.

    -
    ENVIRONMENT VARIABLES
    +
    ENVIRONMENT VARIABLES

    The environment variables LC_ALL and LC_CTYPE are examined, in that order, for a locale. The first one that is set is used. This can be overridden by the --locale option. If no locale is set, the PCRE library's default (usually the "C" locale) is used.

    -
    NEWLINES
    +
    NEWLINES

    The -N (--newline) option allows pcregrep to scan files with different newline conventions from the default. However, the setting of this @@ -531,16 +594,17 @@ printf() calls to indicate newlines, relying on the C I/O library to convert this to an appropriate sequence if the output is sent to a file.

    -
    OPTIONS COMPATIBILITY
    +
    OPTIONS COMPATIBILITY

    Many of the short and long forms of pcregrep's options are the same -as in the GNU grep program (version 2.5.4). Any long option of the form +as in the GNU grep program. Any long option of the form --xxx-regexp (GNU terminology) is also available as --xxx-regex -(PCRE terminology). However, the --file-offsets, --include-dir, ---line-offsets, --locale, --match-limit, -M, ---multiline, -N, --newline, --recursion-limit, --u, and --utf-8 options are specific to pcregrep, as is the -use of the --only-matching option with a capturing parentheses number. +(PCRE terminology). However, the --file-list, --file-offsets, +--include-dir, --line-offsets, --locale, --match-limit, +-M, --multiline, -N, --newline, +--recursion-limit, -u, and --utf-8 options are specific to +pcregrep, as is the use of the --only-matching option with a +capturing parentheses number.

    Although most of the common options work the same way, a few are different in @@ -549,7 +613,7 @@ -c and -l options are given, GNU grep lists only file names, without counts, but pcregrep gives the counts.

    -
    OPTIONS WITH DATA
    +
    OPTIONS WITH DATA

    There are four different ways in which an option with data can be specified. If a short form option is used, the data may follow immediately, or (with one @@ -581,7 +645,7 @@ options does have data, it must be given in the first form, using an equals character. Otherwise pcregrep will assume that it has no data.

    -
    MATCHING ERRORS
    +
    MATCHING ERRORS

    It is possible to supply a regular expression that takes a very long time to fail to match certain lines. Such patterns normally involve nested indefinite @@ -597,19 +661,19 @@ sets a limit on the amount of memory (usually stack) that is used (see the discussion of these options above).

    -
    DIAGNOSTICS
    +
    DIAGNOSTICS

    Exit status is 0 if any matches were found, 1 if no matches were found, and 2 -for syntax errors and non-existent or inacessible files (even if matches were -found in other files) or too many matching errors. Using the -s option to -suppress error messages about inaccessble files does not affect the return -code. +for syntax errors, overlong lines, non-existent or inaccessible files (even if +matches were found in other files) or too many matching errors. Using the +-s option to suppress error messages about inaccessible files does not +affect the return code.

    -
    SEE ALSO
    +
    SEE ALSO

    pcrepattern(3), pcretest(1).

    -
    AUTHOR
    +
    AUTHOR

    Philip Hazel
    @@ -618,11 +682,11 @@ Cambridge CB2 3QH, England.

    -
    REVISION
    +
    REVISION

    -Last updated: 14 January 2011 +Last updated: 04 March 2012
    -Copyright © 1997-2011 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrejit.html pcre3-8.31/doc/html/pcrejit.html --- pcre3-8.12/doc/html/pcrejit.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcrejit.html 2012-07-06 09:55:28.000000000 +0000 @@ -0,0 +1,422 @@ + + +pcrejit specification + + +

    pcrejit man page

    +

    +Return to the PCRE index page. +

    +

    +This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
    +

    +
    PCRE JUST-IN-TIME COMPILER SUPPORT
    +

    +Just-in-time compiling is a heavyweight optimization that can greatly speed up +pattern matching. However, it comes at the cost of extra processing before the +match is performed. Therefore, it is of most benefit when the same pattern is +going to be matched many times. This does not necessarily mean many calls of a +matching function; if the pattern is not anchored, matching attempts may take +place many times at various positions in the subject, even for a single call. +Therefore, if the subject string is very long, it may still pay to use JIT for +one-off matches. +

    +

    +JIT support applies only to the traditional Perl-compatible matching function. +It does not apply when the DFA matching function is being used. The code for +this support was written by Zoltan Herczeg. +

    +
    8-BIT and 16-BIT SUPPORT
    +

    +JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep +this documentation simple, only the 8-bit interface is described in what +follows. If you are using the 16-bit library, substitute the 16-bit functions +and 16-bit structures (for example, pcre16_jit_stack instead of +pcre_jit_stack). +

    +
    AVAILABILITY OF JIT SUPPORT
    +

    +JIT support is an optional feature of PCRE. The "configure" option --enable-jit +(or equivalent CMake option) must be set when PCRE is built if you want to use +JIT. The support is limited to the following hardware platforms: +

    +  ARM v5, v7, and Thumb2
    +  Intel x86 32-bit and 64-bit
    +  MIPS 32-bit
    +  Power PC 32-bit and 64-bit
    +
    +If --enable-jit is set on an unsupported platform, compilation fails. +

    +

    +A program that is linked with PCRE 8.20 or later can tell if JIT support is +available by calling pcre_config() with the PCRE_CONFIG_JIT option. The +result is 1 when JIT is available, and 0 otherwise. However, a simple program +does not need to check this in order to use JIT. The API is implemented in a +way that falls back to the interpretive code if JIT is not available. +

    +

    +If your program may sometimes be linked with versions of PCRE that are older +than 8.20, but you want to use JIT when it is available, you can test +the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such +as PCRE_CONFIG_JIT, for compile-time control of your code. +

    +
    SIMPLE USE OF JIT
    +

    +You have to do two things to make use of the JIT support in the simplest way: +

    +  (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for
    +      each compiled pattern, and pass the resulting pcre_extra block to
    +      pcre_exec().
    +
    +  (2) Use pcre_free_study() to free the pcre_extra block when it is
    +      no longer needed, instead of just freeing it yourself. This
    +      ensures that any JIT data is also freed.
    +
    +For a program that may be linked with pre-8.20 versions of PCRE, you can insert +
    +  #ifndef PCRE_STUDY_JIT_COMPILE
    +  #define PCRE_STUDY_JIT_COMPILE 0
    +  #endif
    +
    +so that no option is passed to pcre_study(), and then use something like +this to free the study data: +
    +  #ifdef PCRE_CONFIG_JIT
    +      pcre_free_study(study_ptr);
    +  #else
    +      pcre_free(study_ptr);
    +  #endif
    +
    +PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete +matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or +PCRE_PARTIAL_SOFT options of pcre_exec(), you should set one or both of +the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE +when you call pcre_study(): +
    +  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
    +  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
    +
    +The JIT compiler generates different optimized code for each of the three +modes (normal, soft partial, hard partial). When pcre_exec() is called, +the appropriate code is run if it is available. Otherwise, the pattern is +matched using interpretive code. +

    +

    +In some circumstances you may need to call additional functions. These are +described in the section entitled +"Controlling the JIT stack" +below. +

    +

    +If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and +no JIT data is created. Otherwise, the compiled pattern is passed to the JIT +compiler, which turns it into machine code that executes much faster than the +normal interpretive code. When pcre_exec() is passed a pcre_extra +block containing a pointer to JIT code of the appropriate mode (normal or +hard/soft partial), it obeys that code instead of running the interpreter. The +result is identical, but the compiled JIT code runs much faster. +

    +

    +There are some pcre_exec() options that are not supported for JIT +execution. There are also some pattern items that JIT cannot handle. Details +are given below. In both cases, execution automatically falls back to the +interpretive code. If you want to know whether JIT was actually used for a +particular match, you should arrange for a JIT callback function to be set up +as described in the section entitled +"Controlling the JIT stack" +below, even if you do not need to supply a non-default JIT stack. Such a +callback function is called whenever JIT code is about to be obeyed. If the +execution options are not right for JIT execution, the callback function is not +obeyed. +

    +

    +If the JIT compiler finds an unsupported item, no JIT data is generated. You +can find out if JIT execution is available after studying a pattern by calling +pcre_fullinfo() with the PCRE_INFO_JIT option. A result of 1 means that +JIT compilation was successful. A result of 0 means that JIT support is not +available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or +the JIT compiler was not able to handle the pattern. +

    +

    +Once a pattern has been studied, with or without JIT, it can be used as many +times as you like for matching different subject strings. +

    +
    UNSUPPORTED OPTIONS AND PATTERN ITEMS
    +

    +The only pcre_exec() options that are supported for JIT execution are +PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, +PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. +

    +

    +The unsupported pattern items are: +

    +  \C             match a single byte; not supported in UTF-8 mode
    +  (?Cn)          callouts
    +  (*PRUNE)       )
    +  (*SKIP)        ) backtracking control verbs
    +  (*THEN)        )
    +
    +Support for some of these may be added in future. +

    +
    RETURN VALUES FROM JIT EXECUTION
    +

    +When a pattern is matched using JIT execution, the return values are the same +as those given by the interpretive pcre_exec() code, with the addition of +one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used +for the JIT stack was insufficient. See +"Controlling the JIT stack" +below for a discussion of JIT stack usage. For compatibility with the +interpretive pcre_exec() code, no more than two-thirds of the +ovector argument is used for passing back captured substrings. +

    +

    +The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a +very large pattern tree goes on for too long, as it is in the same circumstance +when JIT is not used, but the details of exactly what is counted are not the +same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT +execution. +

    +
    SAVING AND RESTORING COMPILED PATTERNS
    +

    +The code that is generated by the JIT compiler is architecture-specific, and is +also position dependent. For those reasons it cannot be saved (in a file or +database) and restored later like the bytecode and other data of a compiled +pattern. Saving and restoring compiled patterns is not something many people +do. More detail about this facility is given in the +pcreprecompile +documentation. It should be possible to run pcre_study() on a saved and +restored pattern, and thereby recreate the JIT data, but because JIT +compilation uses significant resources, it is probably not worth doing this; +you might as well recompile the original pattern. +

    +
    CONTROLLING THE JIT STACK
    +

    +When the compiled JIT code runs, it needs a block of memory to use as a stack. +By default, it uses 32K on the machine stack. However, some large or +complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT +is given when there is not enough stack. Three functions are provided for +managing blocks of memory for use as JIT stacks. There is further discussion +about the use of JIT stacks in the section entitled +"JIT stack FAQ" +below. +

    +

    +The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments +are a starting size and a maximum size, and it returns a pointer to an opaque +structure of type pcre_jit_stack, or NULL if there is an error. The +pcre_jit_stack_free() function can be used to free a stack that is no +longer needed. (For the technically minded: the address space is allocated by +mmap or VirtualAlloc.) +

    +

    +JIT uses far less memory for recursion than the interpretive code, +and a maximum stack size of 512K to 1M should be more than enough for any +pattern. +

    +

    +The pcre_assign_jit_stack() function specifies which stack JIT code +should use. Its arguments are as follows: +

    +  pcre_extra         *extra
    +  pcre_jit_callback  callback
    +  void               *data
    +
    +The extra argument must be the result of studying a pattern with +PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other +two options: +
    +  (1) If callback is NULL and data is NULL, an internal 32K block
    +      on the machine stack is used.
    +
    +  (2) If callback is NULL and data is not NULL, data must be
    +      a valid JIT stack, the result of calling pcre_jit_stack_alloc().
    +
    +  (3) If callback is not NULL, it must point to a function that is
    +      called with data as an argument at the start of matching, in
    +      order to set up a JIT stack. If the return from the callback
    +      function is NULL, the internal 32K stack is used; otherwise the
    +      return value must be a valid JIT stack, the result of calling
    +      pcre_jit_stack_alloc().
    +
    +A callback function is obeyed whenever JIT code is about to be run; it is not +obeyed when pcre_exec() is called with options that are incompatible for +JIT execution. A callback function can therefore be used to determine whether a +match operation was executed by JIT or by the interpreter. +

    +

    +You may safely use the same JIT stack for more than one pattern (either by +assigning directly or by callback), as long as the patterns are all matched +sequentially in the same thread. In a multithread application, if you do not +specify a JIT stack, or if you assign or pass back NULL from a callback, that +is thread-safe, because each thread has its own machine stack. However, if you +assign or pass back a non-NULL JIT stack, this must be a different stack for +each thread so that the application is thread-safe. +

    +

    +Strictly speaking, even more is allowed. You can assign the same non-NULL stack +to any number of patterns as long as they are not used for matching by multiple +threads at the same time. For example, you can assign the same stack to all +compiled patterns, and use a global mutex in the callback to wait until the +stack is available for use. However, this is an inefficient solution, and not +recommended. +

    +

    +This is a suggestion for how a multithreaded program that needs to set up +non-default JIT stacks might operate: +

    +  During thread initalization
    +    thread_local_var = pcre_jit_stack_alloc(...)
    +
    +  During thread exit
    +    pcre_jit_stack_free(thread_local_var)
    +
    +  Use a one-line callback function
    +    return thread_local_var
    +
    +All the functions described in this section do nothing if JIT is not available, +and pcre_assign_jit_stack() does nothing unless the extra argument +is non-NULL and points to a pcre_extra block that is the result of a +successful study with PCRE_STUDY_JIT_COMPILE etc. +

    +
    JIT STACK FAQ
    +

    +(1) Why do we need JIT stacks? +
    +
    +PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where +the local data of the current node is pushed before checking its child nodes. +Allocating real machine stack on some platforms is difficult. For example, the +stack chain needs to be updated every time if we extend the stack on PowerPC. +Although it is possible, its updating time overhead decreases performance. So +we do the recursion in memory. +

    +

    +(2) Why don't we simply allocate blocks of memory with malloc()? +
    +
    +Modern operating systems have a nice feature: they can reserve an address space +instead of allocating memory. We can safely allocate memory pages inside this +address space, so the stack could grow without moving memory data (this is +important because of pointers). Thus we can allocate 1M address space, and use +only a single memory page (usually 4K) if that is enough. However, we can still +grow up to 1M anytime if needed. +

    +

    +(3) Who "owns" a JIT stack? +
    +
    +The owner of the stack is the user program, not the JIT studied pattern or +anything else. The user program must ensure that if a stack is used by +pcre_exec(), (that is, it is assigned to the pattern currently running), +that stack must not be used by any other threads (to avoid overwriting the same +memory area). The best practice for multithreaded programs is to allocate a +stack for each thread, and return this stack through the JIT callback function. +

    +

    +(4) When should a JIT stack be freed? +
    +
    +You can free a JIT stack at any time, as long as it will not be used by +pcre_exec() again. When you assign the stack to a pattern, only a pointer +is set. There is no reference counting or any other magic. You can free the +patterns and stacks in any order, anytime. Just do not call +pcre_exec() with a pattern pointing to an already freed stack, as that +will cause SEGFAULT. (Also, do not free a stack currently used by +pcre_exec() in another thread). You can also replace the stack for a +pattern at any time. You can even free the previous stack before assigning a +replacement. +

    +

    +(5) Should I allocate/free a stack every time before/after calling +pcre_exec()? +
    +
    +No, because this is too costly in terms of resources. However, you could +implement some clever idea which release the stack if it is not used in let's +say two minutes. The JIT callback can help to achive this without keeping a +list of the currently JIT studied patterns. +

    +

    +(6) OK, the stack is for long term memory allocation. But what happens if a +pattern causes stack overflow with a stack of 1M? Is that 1M kept until the +stack is freed? +
    +
    +Especially on embedded sytems, it might be a good idea to release memory +sometimes without freeing the stack. There is no API for this at the moment. +Probably a function call which returns with the currently allocated memory for +any stack and another which allows releasing memory (shrinking the stack) would +be a good idea if someone needs this. +

    +

    +(7) This is too much of a headache. Isn't there any better solution for JIT +stack handling? +
    +
    +No, thanks to Windows. If POSIX threads were used everywhere, we could throw +out this complicated API. +

    +
    EXAMPLE CODE
    +

    +This is a single-threaded example that specifies a JIT stack without using a +callback. +

    +  int rc;
    +  int ovector[30];
    +  pcre *re;
    +  pcre_extra *extra;
    +  pcre_jit_stack *jit_stack;
    +
    +  re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
    +  /* Check for errors */
    +  extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error);
    +  jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024);
    +  /* Check for error (NULL) */
    +  pcre_assign_jit_stack(extra, NULL, jit_stack);
    +  rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30);
    +  /* Check results */
    +  pcre_free(re);
    +  pcre_free_study(extra);
    +  pcre_jit_stack_free(jit_stack);
    +
    +
    +

    +
    SEE ALSO
    +

    +pcreapi(3) +

    +
    AUTHOR
    +

    +Philip Hazel (FAQ by Zoltan Herczeg) +
    +University Computing Service +
    +Cambridge CB2 3QH, England. +
    +

    +
    REVISION
    +

    +Last updated: 04 May 2012 +
    +Copyright © 1997-2012 University of Cambridge. +
    +

    +Return to the PCRE index page. +

    diff -Nru pcre3-8.12/doc/html/pcrelimits.html pcre3-8.31/doc/html/pcrelimits.html --- pcre3-8.12/doc/html/pcrelimits.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcrelimits.html 2012-07-06 09:55:28.000000000 +0000 @@ -0,0 +1,85 @@ + + +pcrelimits specification + + +

    pcrelimits man page

    +

    +Return to the PCRE index page. +

    +

    +This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
    +
    +SIZE AND OTHER LIMITATIONS +
    +

    +There are some size limitations in PCRE but it is hoped that they will never in +practice be relevant. +

    +

    +The maximum length of a compiled pattern is approximately 64K data units (bytes +for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled +with the default internal linkage size of 2 bytes. If you want to process +regular expressions that are truly enormous, you can compile PCRE with an +internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded +up to 4). See the README file in the source distribution and the +pcrebuild +documentation for details. In these cases the limit is substantially larger. +However, the speed of execution is slower. +

    +

    +All values in repeating quantifiers must be less than 65536. +

    +

    +There is no limit to the number of parenthesized subpatterns, but there can be +no more than 65535 capturing subpatterns. +

    +

    +There is a limit to the number of forward references to subsequent subpatterns +of around 200,000. Repeated forward references with fixed upper limits, for +example, (?2){0,100} when subpattern number 2 is to the right, are included in +the count. There is no limit to the number of backward references. +

    +

    +The maximum length of name for a named subpattern is 32 characters, and the +maximum number of named subpatterns is 10000. +

    +

    +The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb +is 255 for the 8-bit library and 65535 for the 16-bit library. +

    +

    +The maximum length of a subject string is the largest positive number that an +integer variable can hold. However, when using the traditional matching +function, PCRE uses recursion to handle subpatterns and indefinite repetition. +This means that the available stack space may limit the size of a subject +string that can be processed by certain patterns. For a discussion of stack +issues, see the +pcrestack +documentation. +

    +
    +AUTHOR +
    +

    +Philip Hazel +
    +University Computing Service +
    +Cambridge CB2 3QH, England. +
    +

    +
    +REVISION +
    +

    +Last updated: 04 May 2012 +
    +Copyright © 1997-2012 University of Cambridge. +
    +

    +Return to the PCRE index page. +

    diff -Nru pcre3-8.12/doc/html/pcrematching.html pcre3-8.31/doc/html/pcrematching.html --- pcre3-8.12/doc/html/pcrematching.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrematching.html 2012-07-06 09:55:28.000000000 +0000 @@ -26,15 +26,18 @@

    This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given subject string. The -"standard" algorithm is the one provided by the pcre_exec() function. -This works in the same was as Perl's matching function, and provides a -Perl-compatible matching operation. +"standard" algorithm is the one provided by the pcre_exec() and +pcre16_exec() functions. These work in the same was as Perl's matching +function, and provide a Perl-compatible matching operation. The just-in-time +(JIT) optimization that is described in the +pcrejit +documentation is compatible with these functions.

    -An alternative algorithm is provided by the pcre_dfa_exec() function; -this operates in a different way, and is not Perl-compatible. It has advantages -and disadvantages compared with the standard algorithm, and these are described -below. +An alternative algorithm is provided by the pcre_dfa_exec() and +pcre16_dfa_exec() functions; they operate in a different way, and are not +Perl-compatible. This alternative has advantages and disadvantages compared +with the standard algorithm, and these are described below.

    When there is only one possible way in which a given subject string can match a @@ -163,10 +166,10 @@ always 1, and the value of the capture_last field is always -1.

    -7. The \C escape sequence, which (in the standard algorithm) matches a single -byte, even in UTF-8 mode, is not supported because the alternative algorithm -moves through the subject string one character at a time, for all active paths -through the tree. +7. The \C escape sequence, which (in the standard algorithm) always matches a +single data unit, even in UTF-8 or UTF-16 modes, is not supported in these +modes, because the alternative algorithm moves through the subject string one +character (not data unit) at a time, for all active paths through the tree.

    8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not @@ -184,11 +187,11 @@

    2. Because the alternative algorithm scans the subject string just once, and -never needs to backtrack, it is possible to pass very long subject strings to -the matching function in several pieces, checking for partial matching each -time. Although it is possible to do multi-segment matching using the standard -algorithm (pcre_exec()), by retaining partially matched substrings, it is -more complicated. The +never needs to backtrack (except for lookbehinds), it is possible to pass very +long subject strings to the matching function in several pieces, checking for +partial matching each time. Although it is possible to do multi-segment +matching using the standard algorithm by retaining partially matched +substrings, it is more complicated. The pcrepartial documentation gives details of partial matching and discusses multi-segment matching. @@ -220,9 +223,9 @@


    REVISION

    -Last updated: 17 November 2010 +Last updated: 08 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrepartial.html pcre3-8.31/doc/html/pcrepartial.html --- pcre3-8.12/doc/html/pcrepartial.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcrepartial.html 2012-07-06 09:55:28.000000000 +0000 @@ -14,24 +14,24 @@


    PARTIAL MATCHING IN PCRE

    -In normal use of PCRE, if the subject string that is passed to -pcre_exec() or pcre_dfa_exec() matches as far as it goes, but is -too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There -are circumstances where it might be helpful to distinguish this case from other -cases in which there is no match. +In normal use of PCRE, if the subject string that is passed to a matching +function matches as far as it goes, but is too short to match the entire +pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might +be helpful to distinguish this case from other cases in which there is no +match.

    Consider, for example, an application where a human is required to type in data @@ -50,40 +50,51 @@

    PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and -PCRE_PARTIAL_HARD options, which can be set when calling pcre_exec() or -pcre_dfa_exec(). For backwards compatibility, PCRE_PARTIAL is a synonym -for PCRE_PARTIAL_SOFT. The essential difference between the two options is -whether or not a partial match is preferred to an alternative complete match, -though the details differ between the two matching functions. If both options +PCRE_PARTIAL_HARD options, which can be set when calling any of the matching +functions. For backwards compatibility, PCRE_PARTIAL is a synonym for +PCRE_PARTIAL_SOFT. The essential difference between the two options is whether +or not a partial match is preferred to an alternative complete match, though +the details differ between the two types of matching function. If both options are set, PCRE_PARTIAL_HARD takes precedence.

    -Setting a partial matching option disables two of PCRE's optimizations. PCRE -remembers the last literal byte in a pattern, and abandons matching immediately -if such a byte is not present in the subject string. This optimization cannot -be used for a subject string that might match only partially. If the pattern -was studied, PCRE knows the minimum length of a matching string, and does not -bother to run the matching function on shorter strings. This optimization is -also disabled for partial matching. -

    -
    PARTIAL MATCHING USING pcre_exec()
    -

    -A partial match occurs during a call to pcre_exec() when the end of the -subject string is reached successfully, but matching cannot continue because -more characters are needed. However, at least one character in the subject must -have been inspected. This character need not form part of the final matched -string; lookbehind assertions and the \K escape sequence provide ways of -inspecting characters before the start of a matched substring. The requirement -for inspecting at least one character exists because an empty string can always -be matched; without such a restriction there would always be a partial match of -an empty string at the end of the subject. -

    -

    -If there are at least two slots in the offsets vector when pcre_exec() -returns with a partial match, the first slot is set to the offset of the -earliest character that was inspected when the partial match was found. For -convenience, the second offset points to the end of the subject so that a -substring can easily be identified. +If you want to use partial matching with just-in-time optimized code, you must +call pcre_study() or pcre16_study() with one or both of these +options: +

    +  PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
    +  PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
    +
    +PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial +matches on the same pattern. If the appropriate JIT study mode has not been set +for a match, the interpretive matching code is used. +

    +

    +Setting a partial matching option disables two of PCRE's standard +optimizations. PCRE remembers the last literal data unit in a pattern, and +abandons matching immediately if it is not present in the subject string. This +optimization cannot be used for a subject string that might match only +partially. If the pattern was studied, PCRE knows the minimum length of a +matching string, and does not bother to run the matching function on shorter +strings. This optimization is also disabled for partial matching. +

    +
    PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()
    +

    +A partial match occurs during a call to pcre_exec() or +pcre16_exec() when the end of the subject string is reached successfully, +but matching cannot continue because more characters are needed. However, at +least one character in the subject must have been inspected. This character +need not form part of the final matched string; lookbehind assertions and the +\K escape sequence provide ways of inspecting characters before the start of a +matched substring. The requirement for inspecting at least one character exists +because an empty string can always be matched; without such a restriction there +would always be a partial match of an empty string at the end of the subject. +

    +

    +If there are at least two slots in the offsets vector when a partial match is +returned, the first slot is set to the offset of the earliest character that +was inspected. For convenience, the second offset points to the end of the +subject so that a substring can easily be identified.

    For the majority of patterns, the first offset identifies the start of the @@ -103,13 +114,14 @@ partial matching options are set.


    -PCRE_PARTIAL_SOFT with pcre_exec() +PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()

    -If PCRE_PARTIAL_SOFT is set when pcre_exec() identifies a partial match, -the partial match is remembered, but matching continues as normal, and other -alternatives in the pattern are tried. If no complete match can be found, -pcre_exec() returns PCRE_ERROR_PARTIAL instead of PCRE_ERROR_NOMATCH. +If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() +identifies a partial match, the partial match is remembered, but matching +continues as normal, and other alternatives in the pattern are tried. If no +complete match can be found, PCRE_ERROR_PARTIAL is returned instead of +PCRE_ERROR_NOMATCH.

    This option is "soft" because it prefers a complete match over a partial match. @@ -132,22 +144,25 @@ matches the second alternative.)


    -PCRE_PARTIAL_HARD with pcre_exec() +PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()

    -If PCRE_PARTIAL_HARD is set for pcre_exec(), it returns -PCRE_ERROR_PARTIAL as soon as a partial match is found, without continuing to -search for possible complete matches. This option is "hard" because it prefers -an earlier partial match over a later complete match. For this reason, the -assumption is made that the end of the supplied subject string may not be the -true end of the available data, and so, if \z, \Z, \b, \B, or $ are -encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL. -

    -

    -Setting PCRE_PARTIAL_HARD also affects the way pcre_exec() checks UTF-8 -subject strings for validity. Normally, an invalid UTF-8 sequence causes the -error PCRE_ERROR_BADUTF8. However, in the special case of a truncated UTF-8 -character at the end of the subject, PCRE_ERROR_SHORTUTF8 is returned when +If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(), +PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without +continuing to search for possible complete matches. This option is "hard" +because it prefers an earlier partial match over a later complete match. For +this reason, the assumption is made that the end of the supplied subject string +may not be the true end of the available data, and so, if \z, \Z, \b, \B, +or $ are encountered at the end of the subject, the result is +PCRE_ERROR_PARTIAL, provided that at least one character in the subject has +been inspected. +

    +

    +Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 +subject strings are checked for validity. Normally, an invalid sequence +causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the +special case of a truncated character at the end of the subject, +PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when PCRE_PARTIAL_HARD is set.


    @@ -167,23 +182,23 @@
       /dog(sbody)??/
     
    -In this case the result is always a complete match because pcre_exec() -finds that first, and it never continues after finding a match. It might be -easier to follow this explanation by thinking of the two patterns like this: +In this case the result is always a complete match because that is found first, +and matching never continues after finding a complete match. It might be easier +to follow this explanation by thinking of the two patterns like this:
       /dog(sbody)?/    is the same as  /dogsbody|dog/
       /dog(sbody)??/   is the same as  /dog|dogsbody/
     
    -The second pattern will never match "dogsbody" when pcre_exec() is -used, because it will always find the shorter match first. +The second pattern will never match "dogsbody", because it will always find the +shorter match first.

    -
    PARTIAL MATCHING USING pcre_dfa_exec()
    +
    PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()

    -The pcre_dfa_exec() function moves along the subject string character by -character, without backtracking, searching for all possible matches -simultaneously. If the end of the subject is reached before the end of the -pattern, there is the possibility of a partial match, again provided that at -least one character has been inspected. +The DFA functions move along the subject string character by character, without +backtracking, searching for all possible matches simultaneously. If the end of +the subject is reached before the end of the pattern, there is the possibility +of a partial match, again provided that at least one character has been +inspected.

    When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there @@ -194,16 +209,16 @@ at least two slots in the offsets vector.

    -Because pcre_dfa_exec() always searches for all possible matches, and -there is no difference between greedy and ungreedy repetition, its behaviour is -different from pcre_exec when PCRE_PARTIAL_HARD is set. Consider the -string "dog" matched against the ungreedy pattern shown above: +Because the DFA functions always search for all possible matches, and there is +no difference between greedy and ungreedy repetition, their behaviour is +different from the standard functions when PCRE_PARTIAL_HARD is set. Consider +the string "dog" matched against the ungreedy pattern shown above:

       /dog(sbody)??/
     
    -Whereas pcre_exec() stops as soon as it finds the complete match for -"dog", pcre_dfa_exec() also finds the partial match for "dogsbody", and -so returns that when PCRE_PARTIAL_HARD is set. +Whereas the standard functions stop as soon as they find the complete match for +"dog", the DFA functions also find the partial match for "dogsbody", and so +return that when PCRE_PARTIAL_HARD is set.


    PARTIAL MATCHING AND WORD BOUNDARIES

    @@ -215,15 +230,11 @@

  • This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following -character cannot take place, so a partial match is found. However, -pcre_exec() carries on with normal matching, which matches \b at the end -of the subject when the last character is a letter, thus finding a complete -match. The result, therefore, is not PCRE_ERROR_PARTIAL. The same thing -happens with pcre_dfa_exec(), because it also finds the complete match. -

    -

    -Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because -then the partial match takes precedence. +character cannot take place, so a partial match is found. However, normal +matching carries on, and \b matches at the end of the subject when the last +character is a letter, so a complete match is found. The result, therefore, is +not PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield +PCRE_ERROR_PARTIAL, because then the partial match takes precedence.


    FORMERLY RESTRICTED PATTERNS

    @@ -231,7 +242,7 @@ optimizations were implemented in the pcre_exec() function, the PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with all patterns. From release 8.00 onwards, the restrictions no longer apply, and -partial matching with pcre_exec() can be requested for any pattern. +partial matching with can be requested for any pattern.

    Items that were formerly restricted were repeated single characters and @@ -263,22 +274,21 @@ The first data string is matched completely, so pcretest shows the matched substrings. The remaining four strings do not match the complete pattern, but the first two are partial matches. Similar output is obtained -when pcre_dfa_exec() is used. +if DFA matching is used.

    If the escape sequence \P is present more than once in a pcretest data line, the PCRE_PARTIAL_HARD option is set for the match.

    -
    MULTI-SEGMENT MATCHING WITH pcre_dfa_exec()
    +
    MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()

    -When a partial match has been found using pcre_dfa_exec(), it is possible -to continue the match by providing additional subject data and calling -pcre_dfa_exec() again with the same compiled regular expression, this -time setting the PCRE_DFA_RESTART option. You must pass the same working -space as before, because this is where details of the previous partial match -are stored. Here is an example using pcretest, using the \R escape -sequence to set the PCRE_DFA_RESTART option (\D specifies the use of -pcre_dfa_exec()): +When a partial match has been found using a DFA matching function, it is +possible to continue the match by providing additional subject data and calling +the function again with the same compiled regular expression, this time setting +the PCRE_DFA_RESTART option. You must pass the same working space as before, +because this is where details of the previous partial match are stored. Here is +an example using pcretest, using the \R escape sequence to set the +PCRE_DFA_RESTART option (\D specifies the use of the DFA matching function):

         re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
       data> 23ja\P\D
    @@ -295,35 +305,39 @@
     

    You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This -facility can be used to pass very long subject strings to -pcre_dfa_exec(). +facility can be used to pass very long subject strings to the DFA matching +functions.

    -
    MULTI-SEGMENT MATCHING WITH pcre_exec()
    +
    MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()

    -From release 8.00, pcre_exec() can also be used to do multi-segment -matching. Unlike pcre_dfa_exec(), it is not possible to restart the -previous match with a new segment of data. Instead, new data must be added to -the previous subject string, and the entire match re-run, starting from the -point where the partial match occurred. Earlier data can be discarded. It is -best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the -end of a segment as the end of the subject when matching \z, \Z, \b, \B, -and $. Consider an unanchored pattern that matches dates: +From release 8.00, the standard matching functions can also be used to do +multi-segment matching. Unlike the DFA functions, it is not possible to +restart the previous match with a new segment of data. Instead, new data must +be added to the previous subject string, and the entire match re-run, starting +from the point where the partial match occurred. Earlier data can be discarded. +

    +

    +It is best to use PCRE_PARTIAL_HARD in this situation, because it does not +treat the end of a segment as the end of the subject when matching \z, \Z, +\b, \B, and $. Consider an unanchored pattern that matches dates:

         re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/
       data> The date is 23ja\P\P
       Partial match: 23ja
     
    At this stage, an application could discard the text preceding "23ja", add on -text from the next segment, and call pcre_exec() again. Unlike -pcre_dfa_exec(), the entire matching string must always be available, and -the complete matching process occurs for each call, so more memory and more +text from the next segment, and call the matching function again. Unlike the +DFA matching functions, the entire matching string must always be available, +and the complete matching process occurs for each call, so more memory and more processing time is needed.

    Note: If the pattern contains lookbehind assertions, or \K, or starts -with \b or \B, the string that is returned for a partial match will include +with \b or \B, the string that is returned for a partial match includes characters that precede the partially matched string itself, because these must be retained when adding on more characters for a subsequent matching attempt. +However, in some cases you may need to retain even earlier characters, as +discussed in the next section.


    ISSUES WITH MULTI-SEGMENT MATCHING

    @@ -338,15 +352,33 @@ includes the effect of PCRE_NOTEOL.

    -2. Lookbehind assertions at the start of a pattern are catered for in the -offsets that are returned for a partial match. However, in theory, a lookbehind -assertion later in the pattern could require even earlier characters to be -inspected, and it might not have been reached when a partial match occurs. This -is probably an extremely unlikely case; you could guard against it to a certain -extent by always including extra characters at the start. +2. Lookbehind assertions that have already been obeyed are catered for in the +offsets that are returned for a partial match. However a lookbehind assertion +later in the pattern could require even earlier characters to be inspected. You +can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the +pcre_fullinfo() or pcre16_fullinfo() functions to obtain the length +of the largest lookbehind in the pattern. This length is given in characters, +not bytes. If you always retain at least that many characters before the +partially matched string, all should be well. (Of course, near the start of the +subject, fewer characters may be present; in that case all characters should be +retained.) +

    +

    +3. Because a partial match must always contain at least one character, what +might be considered a partial match of an empty string actually gives a "no +match" result. For example: +

    +    re> /c(?<=abc)x/
    +  data> ab\P
    +  No match
    +
    +If the next segment begins "cx", a match should be found, but this will only +happen if characters from the previous segment are retained. For this reason, a +"no match" result should be interpreted as "partial match of an empty string" +when the pattern contains lookbehinds.

    -3. Matching a subject string that is split into multiple segments may not +4. Matching a subject string that is split into multiple segments may not always produce exactly the same result as matching over one single long string, especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and Word Boundaries" above describes an issue that arises if the pattern ends with @@ -367,14 +399,14 @@ 0: dogsbody 1: dog

    -The first data line passes the string "dogsb" to pcre_exec(), setting the -PCRE_PARTIAL_SOFT option. Although the string is a partial match for -"dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string -"dog" is a complete match. Similarly, when the subject is presented to -pcre_dfa_exec() in several parts ("do" and "gsb" being the first two) the -match stops when "dog" has been found, and it is not possible to continue. On -the other hand, if "dogsbody" is presented as a single string, -pcre_dfa_exec() finds both matches. +The first data line passes the string "dogsb" to a standard matching function, +setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match +for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter +string "dog" is a complete match. Similarly, when the subject is presented to +a DFA matching function in several parts ("do" and "gsb" being the first two) +the match stops when "dog" has been found, and it is not possible to continue. +On the other hand, if "dogsbody" is presented as a single string, a DFA +matching function finds both matches.

    Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching @@ -388,10 +420,9 @@ data> gsb\R\P\P\D Partial match: gsb -4. Patterns that contain alternatives at the top level which do not all -start with the same pattern item may not work as expected when -PCRE_DFA_RESTART is used with pcre_dfa_exec(). For example, consider this -pattern: +5. Patterns that contain alternatives at the top level which do not all start +with the same pattern item may not work as expected when PCRE_DFA_RESTART is +used. For example, consider this pattern:

       1234|3789
     
    @@ -407,8 +438,8 @@ 1234|ABCD where no string can be a partial match for both alternatives. This is not a -problem if pcre_exec() is used, because the entire match has to be rerun -each time: +problem if a standard matching function is used, because the entire match has +to be rerun each time:
         re> /1234|3789/
       data> ABC123\P\P
    @@ -417,7 +448,7 @@
        0: 3789
     
    Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running -the entire match can also be used with pcre_dfa_exec(). Another +the entire match can also be used with the DFA matching functions. Another possibility is to work with two buffers. If a partial match at offset n in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on the second buffer, you can then try a new match starting at offset n+1 in @@ -434,9 +465,9 @@


    REVISION

    -Last updated: 07 November 2010 +Last updated: 24 February 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrepattern.html pcre3-8.31/doc/html/pcrepattern.html --- pcre3-8.12/doc/html/pcrepattern.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcrepattern.html 2012-07-06 09:55:28.000000000 +0000 @@ -19,7 +19,7 @@

  • BACKSLASH
  • CIRCUMFLEX AND DOLLAR
  • FULL STOP (PERIOD, DOT) AND \N -
  • MATCHING A SINGLE BYTE +
  • MATCHING A SINGLE DATA UNIT
  • SQUARE BRACKETS AND CHARACTER CLASSES
  • POSIX CHARACTER CLASSES
  • VERTICAL BAR @@ -61,25 +61,26 @@

    The original operation of PCRE was on strings of one-byte characters. However, -there is now also support for UTF-8 character strings. To use this, -PCRE must be built to include UTF-8 support, and you must call -pcre_compile() or pcre_compile2() with the PCRE_UTF8 option. There -is also a special sequence that can be given at the start of a pattern: +there is now also support for UTF-8 strings in the original library, and a +second library that supports 16-bit and UTF-16 character strings. To use these +features, PCRE must be built to include appropriate support. When using UTF +strings you must either call the compiling function with the PCRE_UTF8 or +PCRE_UTF16 option, or the pattern must start with one of these special +sequences:

       (*UTF8)
    +  (*UTF16)
     
    -Starting a pattern with this sequence is equivalent to setting the PCRE_UTF8 -option. This feature is not Perl-compatible. How setting UTF-8 mode affects +Starting a pattern with such a sequence is equivalent to setting the relevant +option. This feature is not Perl-compatible. How setting a UTF mode affects pattern matching is mentioned in several places below. There is also a summary -of UTF-8 features in the -section on UTF-8 support -in the main -pcre +of features in the +pcreunicode page.

    Another special sequence that may appear at the start of a pattern or in -combination with (*UTF8) is: +combination with (*UTF8) or (*UTF16) is:

       (*UCP)
     
    @@ -96,13 +97,13 @@

    The remainder of this document discusses the patterns that are supported by -PCRE when its main matching function, pcre_exec(), is used. -From release 6.0, PCRE offers a second matching function, -pcre_dfa_exec(), which matches using a different algorithm that is not -Perl-compatible. Some of the features discussed below are not available when -pcre_dfa_exec() is used. The advantages and disadvantages of the -alternative function, and how it differs from the normal function, are -discussed in the +PCRE when one its main matching functions, pcre_exec() (8-bit) or +pcre16_exec() (16-bit), is used. PCRE also has alternative matching +functions, pcre_dfa_exec() and pcre16_dfa_exec(), which match using +a different algorithm that is not Perl-compatible. Some of the features +discussed below are not available when DFA matching is used. The advantages and +disadvantages of the alternative functions, and how they differ from the normal +functions, are discussed in the pcrematching page.

    @@ -128,9 +129,8 @@ (*ANYCRLF) any of the three above (*ANY) all Unicode newline sequences -These override the default and the options given to pcre_compile() or -pcre_compile2(). For example, on a Unix system where LF is the default -newline sequence, the pattern +These override the default and the options given to the compiling function. For +example, on a Unix system where LF is the default newline sequence, the pattern
       (*CR)a.b
     
    @@ -160,13 +160,13 @@ matches a portion of a subject string that is identical to itself. When caseless matching is specified (the PCRE_CASELESS option), letters are matched -independently of case. In UTF-8 mode, PCRE always understands the concept of +independently of case. In a UTF mode, PCRE always understands the concept of case for characters whose values are less than 128, so caseless matching is always possible. For characters with higher values, the concept of case is supported if PCRE is compiled with Unicode property support, but not otherwise. If you want to use caseless matching for characters 128 and above, you must ensure that PCRE is compiled with Unicode property support as well as with -UTF-8 support. +UTF support.

    The power of regular expressions comes from the ability to include alternatives @@ -222,15 +222,15 @@ particular, if you want to match a backslash, you write \\.

    -In UTF-8 mode, only ASCII numbers and letters have any special meaning after a +In a UTF mode, only ASCII numbers and letters have any special meaning after a backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals.

    -If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the +If a pattern is compiled with the PCRE_EXTENDED option, white space in the pattern (other than in a character class) and characters between a # outside a character class and the next newline are ignored. An escaping backslash can -be used to include a whitespace or # character as part of the pattern. +be used to include a white space or # character as part of the pattern.

    If you want to remove the special meaning from a sequence of characters, you @@ -245,7 +245,11 @@ \Qabc\E\$\Qxyz\E abc$xyz abc$xyz The \Q...\E sequence is recognized both inside and outside character classes. -An isolated \E that is not preceded by \Q is ignored. +An isolated \E that is not preceded by \Q is ignored. If \Q is not followed +by \E later in the pattern, the literal interpretation continues to the end of +the pattern (that is, \E is assumed at the end). If the isolated \Q is inside +a character class, this causes an error, because the character class is not +terminated.


    Non-printing characters @@ -260,30 +264,36 @@ \a alarm, that is, the BEL character (hex 07) \cx "control-x", where x is any ASCII character \e escape (hex 1B) - \f formfeed (hex 0C) + \f form feed (hex 0C) \n linefeed (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) \ddd character with octal code ddd, or back reference \xhh character with hex code hh - \x{hhh..} character with hex code hhh.. + \x{hhh..} character with hex code hhh.. (non-JavaScript mode) + \uhhhh character with hex code hhhh (JavaScript mode only) The precise effect of \cx is as follows: if x is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. Thus \cz becomes hex 1A (z is 7A), but \c{ becomes hex 3B ({ is 7B), while \c; becomes hex 7B (; is 3B). If the byte following \c has a value greater than 127, a compile-time error occurs. This locks out non-ASCII characters in -both byte mode and UTF-8 mode. (When PCRE is compiled in EBCDIC mode, all byte -values are valid. A lower case letter is converted to upper case, and then the -0xc0 bits are flipped.) -

    -

    -After \x, from zero to two hexadecimal digits are read (letters can be in -upper or lower case). Any number of hexadecimal digits may appear between \x{ -and }, but the value of the character code must be less than 256 in non-UTF-8 -mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in -hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code -point, which is 10FFFF. +all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A +lower case letter is converted to upper case, and then the 0xc0 bits are +flipped.) +

    +

    +By default, after \x, from zero to two hexadecimal digits are read (letters +can be in upper or lower case). Any number of hexadecimal digits may appear +between \x{ and }, but the character code is constrained as follows: +

    +  8-bit non-UTF mode    less than 0x100
    +  8-bit UTF-8 mode      less than 0x10ffff and a valid codepoint
    +  16-bit non-UTF mode   less than 0x10000
    +  16-bit UTF-16 mode    less than 0x10ffff and a valid codepoint
    +
    +Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called +"surrogate" codepoints).

    If characters other than hexadecimal digits appear between \x{ and }, or if @@ -292,9 +302,19 @@ following digits, giving a character whose value is zero.

    +If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is +as just described only when it is followed by two hexadecimal digits. +Otherwise, it matches a literal "x" character. In JavaScript mode, support for +code points greater than 256 is provided by \u, which must be followed by +four hexadecimal digits; otherwise it matches a literal "u" character. +Character codes specified by \u in JavaScript mode are constrained in the same +was as those specified by \x in non-JavaScript mode. +

    +

    Characters whose value is less than 256 can be defined by either of the two -syntaxes for \x. There is no difference in the way they are handled. For -example, \xdc is exactly the same as \x{dc}. +syntaxes for \x (or by \u in JavaScript mode). There is no difference in the +way they are handled. For example, \xdc is exactly the same as \x{dc} (or +\u00dc in JavaScript mode).

    After \0 up to two further octal digits are read. If there are fewer than two @@ -317,9 +337,9 @@ Inside a character class, or if the decimal number is greater than 9 and there have not been that many capturing subpatterns, PCRE re-reads up to three octal digits following the backslash, and uses them to generate a data character. Any -subsequent digits stand for themselves. In non-UTF-8 mode, the value of a -character specified in octal must be less than \400. In UTF-8 mode, values up -to \777 are permitted. For example: +subsequent digits stand for themselves. The value of the character is +constrained in the same way as characters specified in hexadecimal. +For example:

       \040   is another way of writing a space
       \40    is the same, provided there are fewer than 40 previous capturing subpatterns
    @@ -328,7 +348,7 @@
       \011   is always a tab
       \0113  is a tab followed by the character "3"
       \113   might be a back reference, otherwise the character with octal code 113
    -  \377   might be a back reference, otherwise the byte consisting entirely of 1 bits
    +  \377   might be a back reference, otherwise the value 255 (decimal)
       \81    is either a back reference, or a binary zero followed by the two characters "8" and "1"
     
    Note that octal values of 100 or greater must not be introduced by a leading @@ -336,12 +356,25 @@

    All the sequences that define a single character value can be used both inside -and outside character classes. In addition, inside a character class, the -sequence \b is interpreted as the backspace character (hex 08). The sequences -\B, \N, \R, and \X are not special inside a character class. Like any other -unrecognized escape sequences, they are treated as the literal characters "B", -"N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is -set. Outside a character class, these sequences have different meanings. +and outside character classes. In addition, inside a character class, \b is +interpreted as the backspace character (hex 08). +

    +

    +\N is not allowed in a character class. \B, \R, and \X are not special +inside a character class. Like other unrecognized escape sequences, they are +treated as the literal characters "B", "R", and "X" by default, but cause an +error if the PCRE_EXTRA option is set. Outside a character class, these +sequences have different meanings. +

    +
    +Unsupported escape sequences +
    +

    +In Perl, the sequences \l, \L, \u, and \U are recognized by its string +handler and used to modify the case of following characters. By default, PCRE +does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT +option is set, \U matches a "U" character, and \u can be used to define a +character by code point, as described in the previous section.


    Absolute and relative back references @@ -375,19 +408,20 @@
       \d     any decimal digit
       \D     any character that is not a decimal digit
    -  \h     any horizontal whitespace character
    -  \H     any character that is not a horizontal whitespace character
    -  \s     any whitespace character
    -  \S     any character that is not a whitespace character
    -  \v     any vertical whitespace character
    -  \V     any character that is not a vertical whitespace character
    +  \h     any horizontal white space character
    +  \H     any character that is not a horizontal white space character
    +  \s     any white space character
    +  \S     any character that is not a white space character
    +  \v     any vertical white space character
    +  \V     any character that is not a vertical white space character
       \w     any "word" character
       \W     any "non-word" character
     
    There is also the single sequence \N, which matches a non-newline character. This is the same as the "." metacharacter -when PCRE_DOTALL is not set. +when PCRE_DOTALL is not set. Perl also uses \N to match characters by name; +PCRE does not support this.

    Each pair of lower and upper case escape sequences partitions the complete set @@ -418,9 +452,9 @@ Unicode is discouraged.

    -By default, in UTF-8 mode, characters with values greater than 128 never match +By default, in a UTF mode, characters with values greater than 128 never match \d, \s, or \w, and always match \D, \S, and \W. These sequences retain -their original meanings from before UTF-8 support was available, mainly for +their original meanings from before UTF support was available, mainly for efficiency reasons. However, if PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows: @@ -438,9 +472,8 @@

    The sequences \h, \H, \v, and \V are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII -characters by default, these always match certain high-valued codepoints in -UTF-8 mode, whether or not PCRE_UCP is set. The horizontal space characters -are: +characters by default, these always match certain high-valued codepoints, +whether or not PCRE_UCP is set. The horizontal space characters are:

       U+0009     Horizontal tab
       U+0020     Space
    @@ -466,19 +499,22 @@
     
       U+000A     Linefeed
       U+000B     Vertical tab
    -  U+000C     Formfeed
    +  U+000C     Form feed
       U+000D     Carriage return
       U+0085     Next line
       U+2028     Line separator
       U+2029     Paragraph separator
    -
    -

    +
    +In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are +relevant. +


    Newline sequences

    Outside a character class, by default, the escape sequence \R matches any -Unicode newline sequence. In non-UTF-8 mode \R is equivalent to the following: +Unicode newline sequence. In 8-bit non-UTF-8 mode \R is equivalent to the +following:

       (?>\r\n|\n|\x0b|\f|\r|\x85)
     
    @@ -486,12 +522,12 @@ below. This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, -U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), or NEL (next +U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next line, U+0085). The two-character sequence is treated as a single unit that cannot be split.

    -In UTF-8 mode, two additional characters whose codepoints are greater than 255 +In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029). Unicode character property support is not needed for these characters to be recognized. @@ -508,19 +544,19 @@ (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence -These override the default and the options given to pcre_compile() or -pcre_compile2(), but they can be overridden by options given to -pcre_exec() or pcre_dfa_exec(). Note that these special settings, -which are not Perl-compatible, are recognized only at the very start of a -pattern, and that they must be in upper case. If more than one of them is -present, the last one is used. They can be combined with a change of newline -convention; for example, a pattern can start with: +These override the default and the options given to the compiling function, but +they can themselves be overridden by options given to a matching function. Note +that these special settings, which are not Perl-compatible, are recognized only +at the very start of a pattern, and that they must be in upper case. If more +than one of them is present, the last one is used. They can be combined with a +change of newline convention; for example, a pattern can start with:

       (*ANY)(*BSR_ANYCRLF)
     
    -They can also be combined with the (*UTF8) or (*UCP) special sequences. Inside -a character class, \R is treated as an unrecognized escape sequence, and so -matches the letter "R" by default, but causes an error if PCRE_EXTRA is set. +They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special +sequences. Inside a character class, \R is treated as an unrecognized escape +sequence, and so matches the letter "R" by default, but causes an error if +PCRE_EXTRA is set.


    Unicode character properties @@ -528,7 +564,7 @@

    When PCRE is built with Unicode character property support, three additional escape sequences that match characters with specific properties are available. -When not in UTF-8 mode, these sequences are of course limited to testing +When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are:

    @@ -562,13 +598,16 @@
     Avestan,
     Balinese,
     Bamum,
    +Batak,
     Bengali,
     Bopomofo,
    +Brahmi,
     Braille,
     Buginese,
     Buhid,
     Canadian_Aboriginal,
     Carian,
    +Chakma,
     Cham,
     Cherokee,
     Common,
    @@ -611,7 +650,11 @@
     Lycian,
     Lydian,
     Malayalam,
    +Mandaic,
     Meetei_Mayek,
    +Meroitic_Cursive,
    +Meroitic_Hieroglyphs,
    +Miao,
     Mongolian,
     Myanmar,
     New_Tai_Lue,
    @@ -630,8 +673,10 @@
     Runic,
     Samaritan,
     Saurashtra,
    +Sharada,
     Shavian,
     Sinhala,
    +Sora_Sompeng,
     Sundanese,
     Syloti_Nagri,
     Syriac,
    @@ -640,6 +685,7 @@
     Tai_Le,
     Tai_Tham,
     Tai_Viet,
    +Takri,
     Tamil,
     Telugu,
     Thaana,
    @@ -717,9 +763,9 @@
     

    The Cs (Surrogate) property applies only to characters in the range U+D800 to -U+DFFF. Such characters are not valid in UTF-8 strings (see RFC 3629) and so -cannot be tested by PCRE, unless UTF-8 validity checking has been turned off -(see the discussion of PCRE_NO_UTF8_CHECK in the +U+DFFF. Such characters are not valid in Unicode strings and so +cannot be tested by PCRE, unless UTF validity checking has been turned off +(see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs property.

    @@ -749,15 +795,18 @@ (see below). Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in -non-UTF-8 mode \X matches any one character. +8-bit non-UTF-8 mode \X matches any one character. +

    +

    +Note that recent versions of Perl have changed \X to match what Unicode calls +an "extended grapheme cluster", which has a more complicated definition.

    Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE by default, though you can make them do so by setting the -PCRE_UCP option for pcre_compile() or by starting the pattern with -(*UCP). +PCRE_UCP option or by starting the pattern with (*UCP).


    PCRE's additional properties @@ -775,7 +824,7 @@ Xwd Any Perl "word" character
    Xan matches characters that have either the L (letter) or the N (number) -property. Xps matches the characters tab, linefeed, vertical tab, formfeed, or +property. Xps matches the characters tab, linefeed, vertical tab, form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. @@ -836,7 +885,7 @@ A word boundary is a position in the subject string where the current character and the previous character do not both match \w or \W (i.e. one matches \w and the other matches \W), or the start or end of the string if the -first or last character matches \w, respectively. In UTF-8 mode, the meanings +first or last character matches \w, respectively. In a UTF mode, the meanings of \w and \W can be changed by setting the PCRE_UCP option. When this is done, it also affects \b and \B. Neither PCRE nor Perl has a separate "start of word" or "end of word" metasequence. However, whatever follows \b normally @@ -933,7 +982,7 @@

    Outside a character class, a dot in the pattern matches any one character in the subject string except (by default) a character that signifies the end of a -line. In UTF-8 mode, the matched character may be more than one byte long. +line.

    When a line ending is defined as a single character, dot never matches that @@ -957,22 +1006,47 @@

    The escape sequence \N behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any character except one -that signifies the end of a line. +that signifies the end of a line. Perl also uses \N to match characters by +name; PCRE does not support this.

    -
    MATCHING A SINGLE BYTE
    +
    MATCHING A SINGLE DATA UNIT

    -Outside a character class, the escape sequence \C matches any one byte, both -in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending -characters. The feature is provided in Perl in order to match individual bytes -in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes, the -rest of the string may start with a malformed UTF-8 character. For this reason, -the \C escape sequence is best avoided. +Outside a character class, the escape sequence \C matches any one data unit, +whether or not a UTF mode is set. In the 8-bit library, one data unit is one +byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \C always +matches line-ending characters. The feature is provided in Perl in order to +match individual bytes in UTF-8 mode, but it is unclear how it can usefully be +used. Because \C breaks up characters into individual data units, matching one +unit with \C in a UTF mode means that the rest of the string may start with a +malformed UTF character. This has undefined results, because PCRE assumes that +it is dealing with valid UTF strings (and by default it checks this at the +start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option +is used).

    PCRE does not allow \C to appear in lookbehind assertions -(described below), -because in UTF-8 mode this would make it impossible to calculate the length of +(described below) +in a UTF mode, because this would make it impossible to calculate the length of the lookbehind. +

    +

    +In general, the \C escape sequence is best avoided. However, one +way of using it that avoids the problem of malformed UTF characters is to use a +lookahead to check the length of the next character, as in this pattern, which +could be used with a UTF-8 string (ignore white space and line breaks): +

    +  (?| (?=[\x00-\x7f])(\C) |
    +      (?=[\x80-\x{7ff}])(\C)(\C) |
    +      (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) |
    +      (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
    +
    +A group that starts with (?| resets the capturing parentheses numbers in each +alternative (see +"Duplicate Subpattern Numbers" +below). The assertions at the start of each branch check the next UTF-8 +character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The +character's individual bytes are then captured by the appropriate number of +groups.


    SQUARE BRACKETS AND CHARACTER CLASSES

    @@ -984,12 +1058,12 @@ (after an initial circumflex, if present) or escaped with a backslash.

    -A character class matches a single character in the subject. In UTF-8 mode, the -character may be more than one byte long. A matched character must be in the -set of characters defined by the class, unless the first character in the class -definition is a circumflex, in which case the subject character must not be in -the set defined by the class. If a circumflex is actually required as a member -of the class, ensure it is not the first character, or escape it with a +A character class matches a single character in the subject. In a UTF mode, the +character may be more than one data unit long. A matched character must be in +the set of characters defined by the class, unless the first character in the +class definition is a circumflex, in which case the subject character must not +be in the set defined by the class. If a circumflex is actually required as a +member of the class, ensure it is not the first character, or escape it with a backslash.

    @@ -1002,20 +1076,21 @@ string.

    -In UTF-8 mode, characters with values greater than 255 can be included in a -class as a literal string of bytes, or by using the \x{ escaping mechanism. +In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be +included in a class as a literal string of data units, or by using the \x{ +escaping mechanism.

    When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a -caseful version would. In UTF-8 mode, PCRE always understands the concept of +caseful version would. In a UTF mode, PCRE always understands the concept of case for characters whose values are less than 128, so caseless matching is always possible. For characters with higher values, the concept of case is supported if PCRE is compiled with Unicode property support, but not otherwise. -If you want to use caseless matching in UTF8-mode for characters 128 and above, -you must ensure that PCRE is compiled with Unicode property support as well as -with UTF-8 support. +If you want to use caseless matching in a UTF mode for characters 128 and +above, you must ensure that PCRE is compiled with Unicode property support as +well as with UTF support.

    Characters that might indicate line breaks are never treated in any special way @@ -1041,16 +1116,15 @@

    Ranges operate in the collating sequence of character values. They can also be -used for characters specified numerically, for example [\000-\037]. In UTF-8 -mode, ranges can include characters whose values are greater than 255, for -example [\x{100}-\x{2ff}]. +used for characters specified numerically, for example [\000-\037]. Ranges +can include any characters that are valid for the current mode.

    If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to -[][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if character +[][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\xc8-\xcb] matches accented E -characters in both cases. In UTF-8 mode, PCRE supports the concept of case for +characters in both cases. In UTF modes, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support.

    @@ -1058,7 +1132,7 @@ The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, \w, and \W may appear in a character class, and add the characters that they match to the class. For example, [\dABCDEF] matches any hexadecimal -digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of \d, \s, \w +digit. In UTF modes, the PCRE_UCP option affects the meanings of \d, \s, \w and their upper case partners, just as it does when they appear outside a character class, as described in the section entitled "Generic character types" @@ -1127,7 +1201,7 @@ supported, and an error is given if they are encountered.

    -By default, in UTF-8 mode, characters with values greater than 128 do not match +By default, in UTF modes, characters with values greater than 128 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to pcre_compile(), some of the classes are changed so that Unicode character properties are used. This is achieved by replacing the POSIX classes @@ -1212,14 +1286,14 @@

    Note: There are other PCRE-specific options that can be set by the -application when the compile or match functions are called. In some cases the -pattern can contain special leading sequences such as (*CRLF) to override what -the application has set or what has been defaulted. Details are given in the -section entitled +application when the compiling or matching functions are called. In some cases +the pattern can contain special leading sequences such as (*CRLF) to override +what the application has set or what has been defaulted. Details are given in +the section entitled "Newline sequences" -above. There are also the (*UTF8) and (*UCP) leading sequences that can be used -to set UTF-8 and Unicode property modes; they are equivalent to setting the -PCRE_UTF8 and the PCRE_UCP options, respectively. +above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that +can be used to set UTF and Unicode property modes; they are equivalent to +setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively.


    SUBPATTERNS

    @@ -1237,10 +1311,14 @@
    2. It sets up the subpattern as a capturing subpattern. This means that, when the whole pattern matches, that portion of the subject string that matched the -subpattern is passed back to the caller via the ovector argument of -pcre_exec(). Opening parentheses are counted from left to right (starting -from 1) to obtain numbers for the capturing subpatterns. For example, if the -string "the red king" is matched against the pattern +subpattern is passed back to the caller via the ovector argument of the +matching function. (This applies only to the traditional matching functions; +the DFA matching functions do not support capturing.) +

    +

    +Opening parentheses are counted from left to right (starting from 1) to obtain +numbers for the capturing subpatterns. For example, if the string "the red +king" is matched against the pattern

       the ((red|white) (king|queen))
     
    @@ -1302,9 +1380,9 @@
       /(?|(abc)|(def))\1/
     
    -In contrast, a recursive or "subroutine" call to a numbered subpattern always -refers to the first one in the pattern with the given number. The following -pattern matches "abcabc" or "defabc": +In contrast, a subroutine call to a numbered subpattern always refers to the +first one in the pattern with the given number. The following pattern matches +"abcabc" or "defabc":
       /(?|(abc)|(def))(?1)/
     
    @@ -1400,13 +1478,13 @@ a literal data character the dot metacharacter the \C escape sequence - the \X escape sequence (in UTF-8 mode with Unicode properties) + the \X escape sequence the \R escape sequence an escape such as \d or \pL that matches a single character a character class a back reference (see next section) - a parenthesized subpattern (unless it is an assertion) - a recursive or "subroutine" call to a subpattern + a parenthesized subpattern (including assertions) + a subroutine call to a subpattern (recursive or otherwise) The general repetition quantifier specifies a minimum and maximum number of permitted matches, by giving the two numbers in curly brackets (braces), @@ -1432,11 +1510,11 @@ quantifier, but a literal string of four characters.

    -In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual -bytes. Thus, for example, \x{100}{2} matches two UTF-8 characters, each of -which is represented by a two-byte sequence. Similarly, when Unicode property -support is available, \X{3} matches three Unicode extended sequences, each of -which may be several bytes long (and they may be of different lengths). +In UTF modes, quantifiers apply to characters rather than to individual data +units. Thus, for example, \x{100}{2} matches two characters, each of +which is represented by a two-byte sequence in a UTF-8 string. Similarly, +\X{3} matches three Unicode extended sequences, each of which may be several +data units long (and they may be of different lengths).

    The quantifier {0} is permitted, causing the expression to behave as if the @@ -1753,7 +1831,7 @@ following a backslash are taken as part of a potential back reference number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the PCRE_EXTENDED option is set, this can be -whitespace. Otherwise, the \g{ syntax or an empty comment (see +white space. Otherwise, the \g{ syntax or an empty comment (see "Comments" below) can be used.

    @@ -1796,12 +1874,32 @@ except that it does not cause the current matching position to be changed.

    -Assertion subpatterns are not capturing subpatterns, and may not be repeated, -because it makes no sense to assert the same thing several times. If any kind -of assertion contains capturing subpatterns within it, these are counted for -the purposes of numbering the capturing subpatterns in the whole pattern. -However, substring capturing is carried out only for positive assertions, -because it does not make sense for negative assertions. +Assertion subpatterns are not capturing subpatterns. If such an assertion +contains capturing subpatterns within it, these are counted for the purposes of +numbering the capturing subpatterns in the whole pattern. However, substring +capturing is carried out only for positive assertions, because it does not make +sense for negative assertions. +

    +

    +For compatibility with Perl, assertion subpatterns may be repeated; though +it makes no sense to assert the same thing several times, the side effect of +capturing parentheses may occasionally be useful. In practice, there only three +cases: +
    +
    +(1) If the quantifier is {0}, the assertion is never obeyed during matching. +However, it may contain internal capturing parenthesized groups that are called +from elsewhere via the +subroutine mechanism. +
    +
    +(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it +were {0,1}. At run time, the rest of the pattern match is tried with and +without the assertion, the order depending on the greediness of the quantifier. +
    +
    +(3) If the minimum repetition is greater than zero, the quantifier is ignored. +The assertion is obeyed just once when encountered during matching.


    Lookahead assertions @@ -1878,10 +1976,11 @@ assertion fails.

    -PCRE does not allow the \C escape (which matches a single byte in UTF-8 mode) -to appear in lookbehind assertions, because it makes it impossible to calculate -the length of the lookbehind. The \X and \R escapes, which can match -different numbers of bytes, are also not permitted. +In a UTF mode, PCRE does not allow the \C escape (which matches a single data +unit even in a UTF mode) to appear in lookbehind assertions, because it makes +it impossible to calculate the length of the lookbehind. The \X and \R +escapes, which can match different numbers of data units, are also not +permitted.

    "Subroutine" @@ -2071,10 +2170,10 @@ name DEFINE, the condition is always false. In this case, there may be only one alternative in the subpattern. It is always skipped if control reaches this point in the pattern; the idea of DEFINE is that it can be used to define -"subroutines" that can be referenced from elsewhere. (The use of -"subroutines" +subroutines that can be referenced from elsewhere. (The use of +subroutines is described below.) For example, a pattern to match an IPv4 address such as -"192.168.23.245" could be written like this (ignore whitespace and line +"192.168.23.245" could be written like this (ignore white space and line breaks):

       (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
    @@ -2120,7 +2219,7 @@
     option is set, an unescaped # character also introduces a comment, which in
     this case continues to immediately after the next newline character or
     character sequence in the pattern. Which characters are interpreted as newlines
    -is controlled by the options passed to pcre_compile() or by a special
    +is controlled by the options passed to a compiling function or by a special
     sequence at the start of the pattern, as described in the section entitled
     "Newline conventions"
     above. Note that the end of this type of comment is a literal newline sequence
    @@ -2162,9 +2261,9 @@
     

    A special item that consists of (? followed by a number greater than zero and a -closing parenthesis is a recursive call of the subpattern of the given number, -provided that it occurs inside that subpattern. (If not, it is a -"subroutine" +closing parenthesis is a recursive subroutine call of the subpattern of the +given number, provided that it occurs inside that subpattern. (If not, it is a +non-recursive subroutine call, which is described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression.

    @@ -2200,7 +2299,7 @@ It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are referenced. They are always -"subroutine" +non-recursive subroutine calls, as described in the next section.

    @@ -2237,8 +2336,8 @@

    the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing subpattern is not -matched at the top level, its final value is unset, even if it is (temporarily) -set at a deeper level. +matched at the top level, its final captured value is unset, even if it was +(temporarily) set at a deeper level during the matching process.

    If there are more than 15 capturing parentheses in a pattern, PCRE has to @@ -2259,15 +2358,16 @@ is the actual recursive call.


    -Recursion difference from Perl +Differences in recursion processing between PCRE and Perl

    -In PCRE (like Python, but unlike Perl), a recursive subpattern call is always -treated as an atomic group. That is, once it has matched some of the subject -string, it is never re-entered, even if it contains untried alternatives and -there is a subsequent matching failure. This can be illustrated by the -following pattern, which purports to match a palindromic string that contains -an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"): +Recursion processing in PCRE differs from Perl in two important ways. In PCRE +(like Python, but unlike Perl), a recursive subpattern call is always treated +as an atomic group. That is, once it has matched some of the subject string, it +is never re-entered, even if it contains untried alternatives and there is a +subsequent matching failure. This can be illustrated by the following pattern, +which purports to match a palindromic string that contains an odd number of +characters (for example, "a", "aba", "abcba", "abcdcba"):

       ^(.|(.)(?1)\2)$
     
    @@ -2332,12 +2432,28 @@ PCRE finds the palindrome "aba" at the start, then fails at top level because the end of the string does not follow. Once again, it cannot jump back into the recursion to try other alternatives, so the entire match fails. +

    +

    +The second way in which PCRE and Perl differ in their recursion processing is +in the handling of captured values. In Perl, when a subpattern is called +recursively or as a subpattern (see the next section), it has no access to any +values that were captured outside the recursion, whereas in PCRE these values +can be referenced. Consider this pattern: +

    +  ^(.)(\1|a(?2))
    +
    +In PCRE, this pattern matches "bab". The first capturing parentheses match "b", +then in the second group, when the back reference \1 fails to match "b", the +second alternative matches "a" and then recurses. In the recursion, \1 does +now match "b" and so the whole match succeeds. In Perl, the pattern fails to +match because inside the recursive call \1 cannot access the externally set +value.


    SUBPATTERNS AS SUBROUTINES

    -If the syntax for a recursive subpattern reference (either by number or by +If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a -subroutine in a programming language. The "called" subpattern may be defined +subroutine in a programming language. The called subpattern may be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples:

    @@ -2358,16 +2474,16 @@
     strings. Another example is given in the discussion of DEFINE above.
     

    -Like recursive subpatterns, a subroutine call is always treated as an atomic -group. That is, once it has matched some of the subject string, it is never -re-entered, even if it contains untried alternatives and there is a subsequent -matching failure. Any capturing parentheses that are set during the subroutine -call revert to their previous values afterwards. +All subroutine calls, whether recursive or not, are always treated as atomic +groups. That is, once a subroutine has matched some of the subject string, it +is never re-entered, even if it contains untried alternatives and there is a +subsequent matching failure. Any capturing parentheses that are set during the +subroutine call revert to their previous values afterwards.

    -When a subpattern is used as a subroutine, processing options such as -case-independence are fixed when the subpattern is defined. They cannot be -changed for different calls. For example, consider this pattern: +Processing options such as case-independence are fixed when a subpattern is +defined, so if it is used as a subroutine, such options cannot be changed for +different calls. For example, consider this pattern:

       (abc)(?i:(?-1))
     
    @@ -2402,8 +2518,9 @@

    PCRE provides a similar feature, but of course it cannot obey arbitrary Perl code. The feature is called "callout". The caller of PCRE provides an external -function by putting its entry point in the global variable pcre_callout. -By default, this variable contains NULL, which disables all calling out. +function by putting its entry point in the global variable pcre_callout +(8-bit library) or pcre16_callout (16-bit library). By default, this +variable contains NULL, which disables all calling out.

    Within a regular expression, (?C) indicates the points at which the external @@ -2413,17 +2530,17 @@

       (?C1)abc(?C2)def
     
    -If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are +If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are automatically installed before each item in the pattern. They are all numbered 255.

    -During matching, when PCRE reaches a callout point (and pcre_callout is -set), the external function is called. It is provided with the number of the -callout, the position in the pattern, and, optionally, one item of data -originally supplied by the caller of pcre_exec(). The callout function -may cause matching to proceed, to backtrack, or to fail altogether. A complete -description of the interface to the callout function is given in the +During matching, when PCRE reaches a callout point, the external function is +called. It is provided with the number of the callout, the position in the +pattern, and, optionally, one item of data originally supplied by the caller of +the matching function. The callout function may cause matching to proceed, to +backtrack, or to fail altogether. A complete description of the interface to +the callout function is given in the pcrecallout documentation.

    @@ -2437,26 +2554,35 @@

    Since these verbs are specifically related to backtracking, most of them can be -used only when the pattern is to be matched using pcre_exec(), which uses -a backtracking algorithm. With the exception of (*FAIL), which behaves like a -failing negative assertion, they cause an error if encountered by -pcre_dfa_exec(). +used only when the pattern is to be matched using one of the traditional +matching functions, which use a backtracking algorithm. With the exception of +(*FAIL), which behaves like a failing negative assertion, they cause an error +if encountered by a DFA matching function.

    -If any of these verbs are used in an assertion or subroutine subpattern -(including recursive subpatterns), their effect is confined to that subpattern; -it does not extend to the surrounding pattern. Note that such subpatterns are -processed as anchored at the point where they are tested. +If any of these verbs are used in an assertion or in a subpattern that is +called as a subroutine (whether or not recursively), their effect is confined +to that subpattern; it does not extend to the surrounding pattern, with one +exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in +a successful positive assertion is passed back when a match succeeds +(compare capturing parentheses in assertions). Note that such subpatterns are +processed as anchored at the point where they are tested. Note also that Perl's +treatment of subroutines and assertions is different in some cases.

    The new verbs make use of what was previously invalid syntax: an opening parenthesis followed by an asterisk. They are generally of the form (*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour, -depending on whether or not an argument is present. An name is a sequence of -letters, digits, and underscores. If the name is empty, that is, if the closing -parenthesis immediately follows the colon, the effect is as if the colon were -not there. Any number of these verbs may occur in a pattern. -

    +depending on whether or not an argument is present. A name is any sequence of +characters that does not include a closing parenthesis. The maximum length of +name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name +is empty, that is, if the closing parenthesis immediately follows the colon, +the effect is as if the colon were not there. Any number of these verbs may +occur in a pattern. +

    +
    +Optimizations that affect backtracking verbs +

    PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the @@ -2465,7 +2591,16 @@ included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_compile() or pcre_exec(), or by starting the -pattern with (*NO_START_OPT). +pattern with (*NO_START_OPT). There is more discussion of this option in the +section entitled +"Option bits for pcre_exec()" +in the +pcreapi +documentation. +

    +

    +Experiments with Perl suggest that it too has similar optimizations, sometimes +leading to anomalous results.


    Verbs that act immediately @@ -2477,9 +2612,10 @@ (*ACCEPT)
    This verb causes the match to end successfully, skipping the remainder of the -pattern. When inside a recursion, only the innermost pattern is ended -immediately. If (*ACCEPT) is inside capturing parentheses, the data so far is -captured. (This feature was added to PCRE at release 8.00.) For example: +pattern. However, when it is inside a subpattern that is called as a +subroutine, only that subpattern is ended successfully. Matching then continues +at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so +far is captured. For example:
       A((?:A|B(*ACCEPT)|C)D)
     
    @@ -2488,7 +2624,7 @@
       (*FAIL) or (*F)
     
    -This verb causes the match to fail, forcing backtracking to occur. It is +This verb causes a matching failure, forcing backtracking to occur. It is equivalent to (?!) but easier to read. The Perl documentation notes that it is probably useful only when combined with (?{}) or (??{}). Those are, of course, Perl features that are not present in PCRE. The nearest equivalent is the @@ -2513,17 +2649,16 @@ (*MARK) as you like in a pattern, and their names do not have to be unique.

    -When a match succeeds, the name of the last-encountered (*MARK) is passed back -to the caller via the pcre_extra data structure, as described in the -section on pcre_extra +When a match succeeds, the name of the last-encountered (*MARK) on the matching +path is passed back to the caller as described in the section entitled +"Extra data for pcre_exec()" in the pcreapi -documentation. No data is returned for a partial match. Here is an example of -pcretest output, where the /K modifier requests the retrieval and -outputting of (*MARK) data: +documentation. Here is an example of pcretest output, where the /K +modifier requests the retrieval and outputting of (*MARK) data:

    -  /X(*MARK:A)Y|X(*MARK:B)Z/K
    -  XY
    +    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
    +  data> XY
        0: XY
       MK: A
       XZ
    @@ -2536,32 +2671,28 @@
     capturing parentheses.
     

    -A name may also be returned after a failed match if the final path through the -pattern involves (*MARK). However, unless (*MARK) used in conjunction with -(*COMMIT), this is unlikely to happen for an unanchored pattern because, as the -starting point for matching is advanced, the final check is often with an empty -string, causing a failure before (*MARK) is reached. For example: -

    -  /X(*MARK:A)Y|X(*MARK:B)Z/K
    -  XP
    -  No match
    -
    -There are three potential starting points for this match (starting with X, -starting with P, and with an empty string). If the pattern is anchored, the -result is different: +If (*MARK) is encountered in a positive assertion, its name is recorded and +passed back if it is the last-encountered. This does not happen for negative +assertions. +

    +

    +After a partial match or a failed match, the name of the last encountered +(*MARK) in the entire match process is returned. For example:

    -  /^X(*MARK:A)Y|^X(*MARK:B)Z/K
    -  XP
    +    re> /X(*MARK:A)Y|X(*MARK:B)Z/K
    +  data> XP
       No match, mark = B
     
    -PCRE's start-of-match optimizations can also interfere with this. For example, -if, as a result of a call to pcre_study(), it knows the minimum -subject length for a match, a shorter subject will not be scanned at all. +Note that in this unanchored example the mark is retained from the match +attempt that started at the letter "X" in the subject. Subsequent match +attempts starting at "P" and then with an empty string do not get as far as the +(*MARK) item, but nevertheless do not reset it.

    -Note that similar anomalies (though different in detail) exist in Perl, no -doubt for the same reasons. The use of (*MARK) data after a failed match of an -unanchored pattern is not recommended, unless (*COMMIT) is involved. +If you are interested in (*MARK) values after failed matches, you should +probably set the PCRE_NO_START_OPTIMIZE option +(see above) +to ensure that the match is always attempted.


    Verbs that act after backtracking @@ -2600,8 +2731,8 @@ unless PCRE's start-of-match optimizations are turned off, as shown in this pcretest example:
    -  /(*COMMIT)abc/
    -  xyzabc
    +    re> /(*COMMIT)abc/
    +  data> xyzabc
        0: abc
       xyzabc\Y
       No match
    @@ -2622,10 +2753,8 @@
     the right, backtracking cannot cross (*PRUNE). In simple cases, the use of
     (*PRUNE) is just an alternative to an atomic group or possessive quantifier,
     but there are some uses of (*PRUNE) that cannot be expressed in any other way.
    -The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the
    -match fails completely; the name is passed back if this is the final attempt.
    -(*PRUNE:NAME) does not pass back a name if the match succeeds. In an anchored
    -pattern (*PRUNE) has the same effect as (*COMMIT).
    +The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
    +anchored pattern (*PRUNE) has the same effect as (*COMMIT).
     
       (*SKIP)
     
    @@ -2651,48 +2780,85 @@ searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that corresponds to that (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a -matching name is found, normal "bumpalong" of one character happens (the -(*SKIP) is ignored). +matching name is found, the (*SKIP) is ignored.
       (*THEN) or (*THEN:NAME)
     
    -This verb causes a skip to the next alternation in the innermost enclosing -group if the rest of the pattern does not match. That is, it cancels pending -backtracking, but only within the current alternation. Its name comes from the -observation that it can be used for a pattern-based if-then-else block: +This verb causes a skip to the next innermost alternative if the rest of the +pattern does not match. That is, it cancels pending backtracking, but only +within the current alternative. Its name comes from the observation that it can +be used for a pattern-based if-then-else block:
       ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
     
    If the COND1 pattern matches, FOO is tried (and possibly further items after -the end of the group if FOO succeeds); on failure the matcher skips to the +the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The -behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN) if the -overall match fails. If (*THEN) is not directly inside an alternation, it acts -like (*PRUNE). +behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). +If (*THEN) is not inside an alternation, it acts like (*PRUNE). +

    +

    +Note that a subpattern that does not contain a | character is just a part of +the enclosing alternative; it is not a nested alternation with only one +alternative. The effect of (*THEN) extends beyond such a subpattern to the +enclosing alternative. Consider this pattern, where A, B, etc. are complex +pattern fragments that do not contain any | characters at this level: +

    +  A (B(*THEN)C) | D
    +
    +If A and B are matched, but there is a failure in C, matching does not +backtrack into A; instead it moves to the next alternative, that is, D. +However, if the subpattern containing (*THEN) is given an alternative, it +behaves differently: +
    +  A (B(*THEN)C | (*FAIL)) | D
    +
    +The effect of (*THEN) is now confined to the inner subpattern. After a failure +in C, matching moves to (*FAIL), which causes the whole subpattern to fail +because there are no more alternatives to try. In this case, matching does now +backtrack into A. +

    +

    +Note also that a conditional subpattern is not considered as having two +alternatives, because only one is ever used. In other words, the | character in +a conditional subpattern has a different meaning. Ignoring white space, +consider: +

    +  ^.*? (?(?=a) a | b(*THEN)c )
    +
    +If the subject is "ba", this pattern does not match. Because .*? is ungreedy, +it initially matches zero characters. The condition (?=a) then fails, the +character "b" is matched, but "c" is not. At this point, matching does not +backtrack to .*? as might perhaps be expected from the presence of the | +character. The conditional subpattern is part of the single alternative that +comprises the whole pattern, and so the match fails. (If there was a backtrack +into .*?, allowing it to match "b", the match would succeed.)

    -The above verbs provide four different "strengths" of control when subsequent -matching fails. (*THEN) is the weakest, carrying on the match at the next -alternation. (*PRUNE) comes next, failing the match at the current starting -position, but allowing an advance to the next character (for an unanchored -pattern). (*SKIP) is similar, except that the advance may be more than one -character. (*COMMIT) is the strongest, causing the entire match to fail. +The verbs just described provide four different "strengths" of control when +subsequent matching fails. (*THEN) is the weakest, carrying on the match at the +next alternative. (*PRUNE) comes next, failing the match at the current +starting position, but allowing an advance to the next character (for an +unanchored pattern). (*SKIP) is similar, except that the advance may be more +than one character. (*COMMIT) is the strongest, causing the entire match to +fail.

    -If more than one is present in a pattern, the "stongest" one wins. For example, -consider this pattern, where A, B, etc. are complex pattern fragments: +If more than one such verb is present in a pattern, the "strongest" one wins. +For example, consider this pattern, where A, B, etc. are complex pattern +fragments:

       (A(*COMMIT)B(*THEN)C|D)
     
    Once A has matched, PCRE is committed to this match, at the current starting position. If subsequently B matches, but C does not, the normal (*THEN) action -of trying the next alternation (that is, D) does not happen because (*COMMIT) +of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides.


    SEE ALSO

    pcreapi(3), pcrecallout(3), pcrematching(3), -pcresyntax(3), pcre(3). +pcresyntax(3), pcre(3), pcre16(3).


    AUTHOR

    @@ -2705,9 +2871,9 @@


    REVISION

    -Last updated: 21 November 2010 +Last updated: 17 June 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcreperform.html pcre3-8.31/doc/html/pcreperform.html --- pcre3-8.12/doc/html/pcreperform.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcreperform.html 2012-07-06 09:55:28.000000000 +0000 @@ -24,9 +24,9 @@ COMPILED PATTERN MEMORY USAGE

    -Patterns are compiled by PCRE into a reasonably efficient byte code, so that -most simple patterns do not use much memory. However, there is one case where -the memory usage of a compiled pattern can be unexpectedly large. If a +Patterns are compiled by PCRE into a reasonably efficient interpretive code, so +that most simple patterns do not use much memory. However, there is one case +where the memory usage of a compiled pattern can be unexpectedly large. If a parenthesized subpattern has a quantifier with a minimum greater than 1 and/or a limited maximum, the whole subpattern is repeated in the compiled code. For example, the pattern @@ -48,12 +48,12 @@

       ((ab){1,1000}c){1,3}
     
    -uses 51K bytes when compiled. When PCRE is compiled with its default internal -pointer size of two bytes, the size limit on a compiled pattern is 64K, and -this is reached with the above pattern if the outer repetition is increased -from 3 to 4. PCRE can be compiled to use larger internal pointers and thus -handle larger compiled patterns, but it is better to try to rewrite your -pattern to use less memory if you can. +uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled +with its default internal pointer size of two bytes, the size limit on a +compiled pattern is 64K data units, and this is reached with the above pattern +if the outer repetition is increased from 3 to 4. PCRE can be compiled to use +larger internal pointers and thus handle larger compiled patterns, but it is +better to try to rewrite your pattern to use less memory if you can.

    One way of reducing the memory usage for such patterns is to make use of PCRE's @@ -77,11 +77,11 @@ STACK USAGE AT RUN TIME

    -When pcre_exec() is used for matching, certain kinds of pattern can cause -it to use large amounts of the process stack. In some environments the default -process stack is quite small, and if it runs out the result is often SIGSEGV. -This issue is probably the most frequently raised problem with PCRE. Rewriting -your pattern can often help. The +When pcre_exec() or pcre16_exec() is used for matching, certain +kinds of pattern can cause it to use large amounts of the process stack. In +some environments the default process stack is quite small, and if it runs out +the result is often SIGSEGV. This issue is probably the most frequently raised +problem with PCRE. Rewriting your pattern can often help. The pcrestack documentation discusses this issue in detail.

    @@ -110,8 +110,9 @@ backwards compatibility, and partly for performance reasons. However, you can set PCRE_UCP if you want Unicode character properties to be used. This can double the matching time for items such as \d, when matched with -pcre_exec(); the performance loss is less with pcre_dfa_exec(), and -in both cases there is not much difference for \b. +a traditional matching function; the performance loss is less with +a DFA matching function, and in both cases there is not much difference for +\b.

    When a pattern begins with .* not in parentheses, or in parentheses that are @@ -186,9 +187,9 @@ REVISION

    -Last updated: 16 May 2010 +Last updated: 09 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcreposix.html pcre3-8.31/doc/html/pcreposix.html --- pcre3-8.12/doc/html/pcreposix.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcreposix.html 2012-07-06 09:55:28.000000000 +0000 @@ -44,11 +44,12 @@


    DESCRIPTION

    -This set of functions provides a POSIX-style API to the PCRE regular expression -package. See the +This set of functions provides a POSIX-style API for the PCRE regular +expression 8-bit library. See the pcreapi documentation for a description of PCRE's native API, which contains much -additional functionality. +additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit +library.

    The functions described here are just wrapper functions that ultimately call @@ -282,9 +283,9 @@


    REVISION

    -Last updated: 16 May 2010 +Last updated: 09 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcreprecompile.html pcre3-8.31/doc/html/pcreprecompile.html --- pcre3-8.12/doc/html/pcreprecompile.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcreprecompile.html 2012-07-06 09:55:28.000000000 +0000 @@ -28,24 +28,31 @@ If you are not using any private character tables (see the pcre_maketables() documentation), this is relatively straightforward. If you are using private -tables, it is a little bit more complicated. +tables, it is a little bit more complicated. However, if you are using the +just-in-time optimization feature, it is not possible to save and reload the +JIT data.

    If you save compiled patterns to a file, you can copy them to a different host -and run them there. This works even if the new host has the opposite endianness -to the one on which the patterns were compiled. There may be a small -performance penalty, but it should be insignificant. However, compiling regular -expressions with one version of PCRE for use with a different version is not -guaranteed to work and may cause crashes. +and run them there. If the two hosts have different endianness (byte order), +you should run the pcre[16]_pattern_to_host_byte_order() function on the +new host before trying to match the pattern. The matching functions return +PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness. +

    +

    +Compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes, and saving and +restoring a compiled pattern loses any JIT optimization data.


    SAVING A COMPILED PATTERN

    -The value returned by pcre_compile() points to a single block of memory -that holds the compiled pattern and associated data. You can find the length of -this block in bytes by calling pcre_fullinfo() with an argument of -PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is -sample code that compiles a pattern and writes it to a file. It assumes that -the variable fd refers to a file that is open for output: +The value returned by pcre[16]_compile() points to a single block of +memory that holds the compiled pattern and associated data. You can find the +length of this block in bytes by calling pcre[16]_fullinfo() with an +argument of PCRE_INFO_SIZE. You can then save the data in any appropriate +manner. Here is sample code for the 8-bit library that compiles a pattern and +writes it to a file. It assumes that the variable fd refers to a file +that is open for output:

       int erroroffset, rc, size;
       char *error;
    @@ -76,33 +83,36 @@
     them.
     

    -If the pattern has been studied, it is also possible to save the study data in -a similar way to the compiled pattern itself. When studying generates -additional information, pcre_study() returns a pointer to a -pcre_extra data block. Its format is defined in the +If the pattern has been studied, it is also possible to save the normal study +data in a similar way to the compiled pattern itself. However, if the +PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot +be saved because it is too dependent on the current environment. When studying +generates additional information, pcre[16]_study() returns a pointer to a +pcre[16]_extra data block. Its format is defined in the section on matching a pattern in the pcreapi documentation. The study_data field points to the binary study data, and -this is what you must save (not the pcre_extra block itself). The length -of the study data can be obtained by calling pcre_fullinfo() with an -argument of PCRE_INFO_STUDYSIZE. Remember to check that pcre_study() did -return a non-NULL value before trying to save the study data. +this is what you must save (not the pcre[16]_extra block itself). The +length of the study data can be obtained by calling pcre[16]_fullinfo() +with an argument of PCRE_INFO_STUDYSIZE. Remember to check that +pcre[16]_study() did return a non-NULL value before trying to save the +study data.


    RE-USING A PRECOMPILED PATTERN

    Re-using a precompiled pattern is straightforward. Having reloaded it into main -memory, you pass its pointer to pcre_exec() or pcre_dfa_exec() in -the usual way. This should work even on another host, and even if that host has -the opposite endianness to the one where the pattern was compiled. +memory, called pcre[16]_pattern_to_host_byte_order() if necessary, +you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() in +the usual way.

    However, if you passed a pointer to custom character tables when the pattern -was compiled (the tableptr argument of pcre_compile()), you must -now pass a similar pointer to pcre_exec() or pcre_dfa_exec(), -because the value saved with the compiled pattern will obviously be nonsense. A -field in a pcre_extra() block is used to pass this data, as described in -the +was compiled (the tableptr argument of pcre[16]_compile()), you +must now pass a similar pointer to pcre[16]_exec() or +pcre[16]_dfa_exec(), because the value saved with the compiled pattern +will obviously be nonsense. A field in a pcre[16]_extra() block is used +to pass this data, as described in the section on matching a pattern in the pcreapi @@ -110,17 +120,18 @@

    If you did not provide custom character tables when the pattern was compiled, -the pointer in the compiled pattern is NULL, which causes pcre_exec() to -use PCRE's internal tables. Thus, you do not need to take any special action at -run time in this case. +the pointer in the compiled pattern is NULL, which causes the matching +functions to use PCRE's internal tables. Thus, you do not need to take any +special action at run time in this case.

    If you saved study data with the compiled pattern, you need to create your own -pcre_extra data block and set the study_data field to point to the +pcre[16]_extra data block and set the study_data field to point to the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study data is present. Then pass the -pcre_extra block to pcre_exec() or pcre_dfa_exec() in the -usual way. +pcre[16]_extra block to the matching function in the usual way. If the +pattern was studied for just-in-time optimization, that data cannot be saved, +and so is lost by a save/restore cycle.


    COMPATIBILITY WITH DIFFERENT PCRE RELEASES

    @@ -138,9 +149,9 @@


    REVISION

    -Last updated: 17 November 2010 +Last updated: 10 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcresample.html pcre3-8.31/doc/html/pcresample.html --- pcre3-8.12/doc/html/pcresample.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcresample.html 2012-07-06 09:55:28.000000000 +0000 @@ -24,11 +24,12 @@ this listing to re-create pcredemo.c.

    -The program compiles the regular expression that is its first argument, and -matches it against the subject string in its second argument. No PCRE options -are set, and default character tables are used. If matching succeeds, the -program outputs the portion of the subject that matched, together with the -contents of any captured substrings. +The demonstration program, which uses the original PCRE 8-bit library, compiles +the regular expression that is its first argument, and matches it against the +subject string in its second argument. No PCRE options are set, and default +character tables are used. If matching succeeds, the program outputs the +portion of the subject that matched, together with the contents of any captured +substrings.

    If the -g option is given on the command line, the program then goes on to @@ -65,8 +66,8 @@

    Note that there is a much more comprehensive test program, called pcretest, -which supports many more facilities for testing regular expressions and the -PCRE library. The +which supports many more facilities for testing regular expressions and both +PCRE libraries. The pcredemo program is provided as a simple coding example.

    @@ -100,9 +101,9 @@ REVISION

    -Last updated: 17 November 2010 +Last updated: 10 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcrestack.html pcre3-8.31/doc/html/pcrestack.html --- pcre3-8.12/doc/html/pcrestack.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcrestack.html 2012-07-06 09:55:28.000000000 +0000 @@ -16,11 +16,14 @@ PCRE DISCUSSION OF STACK USAGE

    -When you call pcre_exec(), it makes use of an internal function called -match(). This calls itself recursively at branch points in the pattern, -in order to remember the state of the match so that it can back up and try a -different alternative if the first one fails. As matching proceeds deeper and -deeper into the tree of possibilities, the recursion depth increases. +When you call pcre[16]_exec(), it makes use of an internal function +called match(). This calls itself recursively at branch points in the +pattern, in order to remember the state of the match so that it can back up and +try a different alternative if the first one fails. As matching proceeds deeper +and deeper into the tree of possibilities, the recursion depth increases. The +match() function is also called in other circumstances, for example, +whenever a parenthesized sub-pattern is entered, and in certain cases of +repetition.

    Not all calls of match() increase the recursion depth; for an item such @@ -30,22 +33,32 @@ current call (a "tail recursion"), the function is just restarted instead.

    -The pcre_dfa_exec() function operates in an entirely different way, and -uses recursion only when there is a regular expression recursion or subroutine -call in the pattern. This includes the processing of assertion and "once-only" -subpatterns, which are handled like subroutine calls. Normally, these are never -very deep, and the limit on the complexity of pcre_dfa_exec() is -controlled by the amount of workspace it is given. However, it is possible to -write patterns with runaway infinite recursions; such patterns will cause -pcre_dfa_exec() to run out of stack. At present, there is no protection -against this. +The above comments apply when pcre[16]_exec() is run in its normal +interpretive manner. If the pattern was studied with the +PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and +the options passed to pcre[16]_exec() were not incompatible, the matching +process uses the JIT-compiled code instead of the match() function. In +this case, the memory requirements are handled entirely differently. See the +pcrejit +documentation for details. +

    +

    +The pcre[16]_dfa_exec() function operates in an entirely different way, +and uses recursion only when there is a regular expression recursion or +subroutine call in the pattern. This includes the processing of assertion and +"once-only" subpatterns, which are handled like subroutine calls. Normally, +these are never very deep, and the limit on the complexity of +pcre[16]_dfa_exec() is controlled by the amount of workspace it is given. +However, it is possible to write patterns with runaway infinite recursions; +such patterns will cause pcre[16]_dfa_exec() to run out of stack. At +present, there is no protection against this.

    -The comments that follow do NOT apply to pcre_dfa_exec(); they are -relevant only for pcre_exec(). +The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are +relevant only for pcre[16]_exec() without the JIT optimization.


    -Reducing pcre_exec()'s stack usage +Reducing pcre[16]_exec()'s stack usage

    Each time that match() is actually called recursively, it uses memory @@ -81,54 +94,81 @@ than one character whenever possible.


    -Compiling PCRE to use heap instead of stack for pcre_exec() +Compiling PCRE to use heap instead of stack for pcre[16]_exec()

    In environments where stack memory is constrained, you might want to compile PCRE to use heap memory instead of stack for remembering back-up points when -pcre_exec() is running. This makes it run a lot more slowly, however. +pcre[16]_exec() is running. This makes it run a lot more slowly, however. Details of how to do this are given in the pcrebuild documentation. When built in this way, instead of using the stack, PCRE obtains and frees memory by calling the functions that are pointed to by the -pcre_stack_malloc and pcre_stack_free variables. By default, these -point to malloc() and free(), but you can replace the pointers to -cause PCRE to use your own functions. Since the block sizes are always the -same, and are always freed in reverse order, it may be possible to implement -customized memory handlers that are more efficient than the standard functions. +pcre[16]_stack_malloc and pcre[16]_stack_free variables. By +default, these point to malloc() and free(), but you can replace +the pointers to cause PCRE to use your own functions. Since the block sizes are +always the same, and are always freed in reverse order, it may be possible to +implement customized memory handlers that are more efficient than the standard +functions.


    -Limiting pcre_exec()'s stack usage +Limiting pcre[16]_exec()'s stack usage

    You can set limits on the number of times that match() is called, both in -total and recursively. If a limit is exceeded, pcre_exec() returns an +total and recursively. If a limit is exceeded, pcre[16]_exec() returns an error code. Setting suitable limits should prevent it from running out of stack. The default values of the limits are very large, and unlikely ever to operate. They can be changed when PCRE is built, and they can also be set when -pcre_exec() is called. For details of these interfaces, see the +pcre[16]_exec() is called. For details of these interfaces, see the pcrebuild documentation and the -section on extra data for pcre_exec() +section on extra data for pcre[16]_exec() in the pcreapi documentation.

    As a very rough rule of thumb, you should reckon on about 500 bytes per -recursion. Thus, if you want to limit your stack usage to 8Mb, you -should set the limit at 16000 recursions. A 64Mb stack, on the other hand, can -support around 128000 recursions. +recursion. Thus, if you want to limit your stack usage to 8Mb, you should set +the limit at 16000 recursions. A 64Mb stack, on the other hand, can support +around 128000 recursions.

    In Unix-like environments, the pcretest test program has a command line option (-S) that can be used to increase the size of its stack. As long as the stack is large enough, another option (-M) can be used to find the smallest limits that allow a particular pattern to match a given subject -string. This is done by calling pcre_exec() repeatedly with different +string. This is done by calling pcre[16]_exec() repeatedly with different limits.


    +Obtaining an estimate of stack usage +
    +

    +The actual amount of stack used per recursion can vary quite a lot, depending +on the compiler that was used to build PCRE and the optimization or debugging +options that were set for it. The rule of thumb value of 500 bytes mentioned +above may be larger or smaller than what is actually needed. A better +approximation can be obtained by running this command: +

    +  pcretest -m -C
    +
    +The -C option causes pcretest to output information about the +options with which PCRE was compiled. When -m is also given (before +-C), information about stack use is given in a line like this: +
    +  Match recursion uses stack: approximate frame size = 640 bytes
    +
    +The value is approximate because some recursions need a bit more (up to perhaps +16 more bytes). +

    +

    +If the above command is given when PCRE is compiled to use the heap instead of +the stack for recursion, the value that is output is the size of each block +that is obtained from the heap. +

    +
    Changing stack size in Unix-like systems

    @@ -150,7 +190,7 @@

    This reads the current limits (soft and hard) using getrlimit(), then attempts to increase the soft limit to 100Mb using setrlimit(). You must -do this before calling pcre_exec(). +do this before calling pcre[16]_exec().


    Changing stack size in Mac OS X @@ -176,9 +216,9 @@ REVISION

    -Last updated: 03 January 2010 +Last updated: 21 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcresyntax.html pcre3-8.31/doc/html/pcresyntax.html --- pcre3-8.12/doc/html/pcresyntax.html 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/html/pcresyntax.html 2012-07-06 09:55:28.000000000 +0000 @@ -46,8 +46,7 @@ The full syntax and semantics of the regular expressions that are supported by PCRE are described in the pcrepattern -documentation. This document contains just a quick-reference summary of the -syntax. +documentation. This document contains a quick-reference summary of the syntax.


    QUOTING

    @@ -62,7 +61,7 @@ \a alarm, that is, the BEL character (hex 07) \cx "control-x", where x is any ASCII character \e escape (hex 1B) - \f formfeed (hex 0C) + \f form feed (hex 0C) \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) @@ -76,25 +75,25 @@

       .          any character except newline;
                    in dotall mode, any character whatsoever
    -  \C         one byte, even in UTF-8 mode (best avoided)
    +  \C         one data unit, even in UTF mode (best avoided)
       \d         a decimal digit
       \D         a character that is not a decimal digit
    -  \h         a horizontal whitespace character
    -  \H         a character that is not a horizontal whitespace character
    +  \h         a horizontal white space character
    +  \H         a character that is not a horizontal white space character
       \N         a character that is not a newline
       \p{xx}     a character with the xx property
       \P{xx}     a character without the xx property
       \R         a newline sequence
    -  \s         a whitespace character
    -  \S         a character that is not a whitespace character
    -  \v         a vertical whitespace character
    -  \V         a character that is not a vertical whitespace character
    +  \s         a white space character
    +  \S         a character that is not a white space character
    +  \v         a vertical white space character
    +  \V         a character that is not a vertical white space character
       \w         a "word" character
       \W         a "non-word" character
       \X         an extended Unicode sequence
     
    In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII -characters, even in UTF-8 mode. However, this can be changed by setting the +characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option.


    GENERAL CATEGORY PROPERTIES FOR \p and \P
    @@ -162,13 +161,16 @@ Avestan, Balinese, Bamum, +Batak, Bengali, Bopomofo, +Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, +Chakma, Cham, Cherokee, Common, @@ -211,7 +213,11 @@ Lycian, Lydian, Malayalam, +Mandaic, Meetei_Mayek, +Meroitic_Cursive, +Meroitic_Hieroglyphs, +Miao, Mongolian, Myanmar, New_Tai_Lue, @@ -230,8 +236,10 @@ Runic, Samaritan, Saurashtra, +Sharada, Shavian, Sinhala, +Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, @@ -240,6 +248,7 @@ Tai_Le, Tai_Tham, Tai_Viet, +Takri, Tamil, Telugu, Thaana, @@ -269,7 +278,7 @@ lower lower case letter print printing, including space punct printing, excluding alphanumeric - space whitespace + space white space upper upper case letter word same as \w xdigit hexadecimal digit @@ -367,7 +376,8 @@ newline-setting options with similar syntax:
       (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
    -  (*UTF8)         set UTF-8 mode (PCRE_UTF8)
    +  (*UTF8)         set UTF-8 mode: 8-bit library (PCRE_UTF8)
    +  (*UTF16)        set UTF-16 mode: 16-bit library (PCRE_UTF16)
       (*UCP)          set PCRE_UCP (use Unicode properties for \d etc)
     

    @@ -439,6 +449,7 @@
       (*ACCEPT)       force successful match
       (*FAIL)         force backtrack; synonym (*F)
    +  (*MARK:NAME)    set name to be passed back; synonym (*:NAME)
     
    The following act only when a subsequent match failure causes a backtrack to reach them. They all force a match failure, but they differ in what happens @@ -447,14 +458,18 @@
       (*COMMIT)       overall failure, no advance of starting point
       (*PRUNE)        advance to next starting character
    -  (*SKIP)         advance start to current matching position
    +  (*PRUNE:NAME)   equivalent to (*MARK:NAME)(*PRUNE)
    +  (*SKIP)         advance to current matching position
    +  (*SKIP:NAME)    advance to position corresponding to an earlier
    +                  (*MARK:NAME); if not found, the (*SKIP) is ignored
       (*THEN)         local failure, backtrack to next alternation
    +  (*THEN:NAME)    equivalent to (*MARK:NAME)(*THEN)
     


    NEWLINE CONVENTIONS

    These are recognized only at the very start of the pattern or after a -(*BSR_...) or (*UTF8) or (*UCP) option. +(*BSR_...), (*UTF8), (*UTF16) or (*UCP) option.

       (*CR)           carriage return only
       (*LF)           linefeed only
    @@ -466,7 +481,7 @@
     
    WHAT \R MATCHES

    These are recognized only at the very start of the pattern or after a -(*...) option that sets the newline convention or UTF-8 or UCP mode. +(*...) option that sets the newline convention or a UTF or UCP mode.

       (*BSR_ANYCRLF)  CR, LF, or CRLF
       (*BSR_UNICODE)  any Unicode newline sequence
    @@ -495,9 +510,9 @@
     


    REVISION

    -Last updated: 21 November 2010 +Last updated: 10 January 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcretest.html pcre3-8.31/doc/html/pcretest.html --- pcre3-8.12/doc/html/pcretest.html 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/html/pcretest.html 2012-07-06 09:55:27.000000000 +0000 @@ -14,24 +14,25 @@


    SYNOPSIS

    -pcretest [options] [source] [destination] +pcretest [options] [input file [output file]]

    pcretest was written as a test program for the PCRE regular expression @@ -42,30 +43,78 @@ documentation. For details of the PCRE library function calls and their options, see the pcreapi -documentation. +and +pcre16 +documentation. The input for pcretest is a sequence of regular expression +patterns and strings to be matched, as described below. The output shows the +result of each match. Options on the command line and the patterns control PCRE +options and exactly what is output. +

    +
    PCRE's 8-BIT and 16-BIT LIBRARIES
    +

    +From release 8.30, two separate PCRE libraries can be built. The original one +supports 8-bit character strings, whereas the newer 16-bit library supports +character strings encoded in 16-bit units. The pcretest program can be +used to test both libraries. However, it is itself still an 8-bit program, +reading 8-bit input and writing 8-bit output. When testing the 16-bit library, +the patterns and data strings are converted to 16-bit format before being +passed to the PCRE library functions. Results are converted to 8-bit for +output. +

    +

    +References to functions and structures of the form pcre[16]_xx below +mean "pcre_xx when using the 8-bit library or pcre16_xx when using +the 16-bit library". +

    +
    COMMAND LINE OPTIONS
    +

    +-16 +If both the 8-bit and the 16-bit libraries have been built, this option causes +the 16-bit library to be used. If only the 16-bit library has been built, this +is the default (so has no effect). If only the 8-bit library has been built, +this option causes an error.

    -
    OPTIONS

    -b -Behave as if each regex has the /B (show bytecode) modifier; the internal -form is output after compilation. +Behave as if each pattern has the /B (show byte code) modifier; the +internal form is output after compilation.

    -C Output the version number of the PCRE library, and all available information -about the optional features that are included, and then exit. +about the optional features that are included, and then exit. All other options +are ignored. +

    +

    +-C option +Output information about a specific build-time option, then exit. This +functionality is intended for use in scripts such as RunTest. The +following options output the value indicated: +

    +  linksize   the internal link size (2, 3, or 4)
    +  newline    the default newline setting:
    +               CR, LF, CRLF, ANYCRLF, or ANY
    +
    +The following options output 1 for true or zero for false: +
    +  jit        just-in-time support is available
    +  pcre16     the 16-bit library was built
    +  pcre8      the 8-bit library was built
    +  ucp        Unicode property support is available
    +  utf        UTF-8 and/or UTF-16 support is available
    +

    -d -Behave as if each regex has the /D (debug) modifier; the internal +Behave as if each pattern has the /D (debug) modifier; the internal form and information about the compiled pattern is output after compilation; -d is equivalent to -b -i.

    -dfa Behave as if each data line contains the \D escape sequence; this causes the -alternative matching function, pcre_dfa_exec(), to be used instead of the -standard pcre_exec() function (more detail is given below). +alternative matching function, pcre[16]_dfa_exec(), to be used instead of +the standard pcre[16]_exec() function (more detail is given below).

    -help @@ -73,35 +122,35 @@

    -i -Behave as if each regex has the /I modifier; information about the +Behave as if each pattern has the /I modifier; information about the compiled pattern is given after compilation.

    -M Behave as if each data line contains the \M escape sequence; this causes PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by -calling pcre_exec() repeatedly with different limits. +calling pcre[16]_exec() repeatedly with different limits.

    -m Output the size of each compiled pattern after it has been compiled. This is -equivalent to adding /M to each regular expression. For compatibility -with earlier versions of pcretest, -s is a synonym for -m. +equivalent to adding /M to each regular expression. The size is given in +bytes for both libraries.

    -o osize Set the number of elements in the output vector that is used when calling -pcre_exec() or pcre_dfa_exec() to be osize. The default value -is 45, which is enough for 14 capturing subexpressions for pcre_exec() or -22 different matches for pcre_dfa_exec(). The vector size can be -changed for individual matching calls by including \O in the data line (see -below). +pcre[16]_exec() or pcre[16]_dfa_exec() to be osize. The +default value is 45, which is enough for 14 capturing subexpressions for +pcre[16]_exec() or 22 different matches for pcre[16]_dfa_exec(). +The vector size can be changed for individual matching calls by including \O +in the data line (see below).

    -p -Behave as if each regex has the /P modifier; the POSIX wrapper API is +Behave as if each pattern has the /P modifier; the POSIX wrapper API is used to call PCRE. None of the other options has any effect when -p is -set. +set. This option can be used only with the 8-bit library.

    -q @@ -109,10 +158,49 @@

    -S size -On Unix-like systems, set the size of the runtime stack to size +On Unix-like systems, set the size of the run-time stack to size megabytes.

    +-s or -s+ +Behave as if each pattern has the /S modifier; in other words, force each +pattern to be studied. If -s+ is used, all the JIT compile options are +passed to pcre[16]_study(), causing just-in-time optimization to be set +up if it is available, for both full and partial matching. Specific JIT compile +options can be selected by following -s+ with a digit in the range 1 to +7, which selects the JIT compile modes as follows: +

    +  1  normal match only
    +  2  soft partial match only
    +  3  normal match and soft partial match
    +  4  hard partial match only
    +  6  soft and hard partial match
    +  7  all three modes (default)
    +
    +If -s++ is used instead of -s+ (with or without a following digit), +the text "(JIT)" is added to the first output line after a match or no match +when JIT-compiled code was actually used. +

    +

    +If the /I or /D option is present on a pattern (requesting output +about the compiled pattern), information about the result of studying is not +included when studying is caused only by -s and neither -i nor +-d is present on the command line. This behaviour means that the output +from tests that are run with and without -s should be identical, except +when options that output information about the actual running of a match are +set. +
    +
    +The -M, -t, and -tm options, which give information about +resources used, are likely to produce different output with and without +-s. Output may also differ if the /C option is present on an +individual pattern. This uses callouts to trace the the matching process, and +this may be different between studied and non-studied patterns. If the pattern +contains (*MARK) items there may also be differences, for the same reason. The +-s command line option can be overridden for specific patterns that +should never be studied (see the /S pattern modifier below). +

    +

    -t Run each compile, study, and match many times with a timer, and output resulting time per compile or match (in milliseconds). Do not set -m with @@ -127,7 +215,7 @@ This is like -t except that it times only the matching phase, not the compile or study phases.

    -
    DESCRIPTION
    +
    DESCRIPTION

    If pcretest is given two filename arguments, it reads from the first and writes to the second. If it is given only one filename argument, it reads from @@ -184,19 +272,19 @@ is interpreted as the first line of a pattern that starts with "abc/", causing pcretest to read the next line as a continuation of the regular expression.

    -
    PATTERN MODIFIERS
    +
    PATTERN MODIFIERS

    A pattern may be followed by any number of modifiers, which are mostly single characters. Following Perl usage, these are referred to below as, for example, "the /i modifier", even though the delimiter of the pattern need not -always be a slash, and no slash is used when writing modifiers. Whitespace may +always be a slash, and no slash is used when writing modifiers. White space may appear between the final pattern delimiter and the first modifier, and between the modifiers themselves.

    The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when -pcre_compile() is called. These four modifier letters have the same +pcre[16]_compile() is called. These four modifier letters have the same effect as they do in Perl. For example:

       /caseless/i
    @@ -204,8 +292,12 @@
     The following table shows additional modifiers for setting PCRE compile-time
     options that do not correspond to anything in Perl:
     
    -  /8              PCRE_UTF8
    -  /?              PCRE_NO_UTF8_CHECK
    +  /8              PCRE_UTF8           ) when using the 8-bit
    +  /?              PCRE_NO_UTF8_CHECK  )   library
    +
    +  /8              PCRE_UTF16          ) when using the 16-bit
    +  /?              PCRE_NO_UTF16_CHECK )   library
    +
       /A              PCRE_ANCHORED
       /C              PCRE_AUTO_CALLOUT
       /E              PCRE_DOLLAR_ENDONLY
    @@ -226,15 +318,18 @@
       /<bsr_unicode>  PCRE_BSR_UNICODE
     
    The modifiers that are enclosed in angle brackets are literal strings as shown, -including the angle brackets, but the letters can be in either case. This -example sets multiline matching with CRLF as the line ending sequence: +including the angle brackets, but the letters within can be in either case. +This example sets multiline matching with CRLF as the line ending sequence:
    -  /^abc/m<crlf>
    +  /^abc/m<CRLF>
     
    -As well as turning on the PCRE_UTF8 option, the /8 modifier also causes -any non-printing characters in output strings to be printed using the -\x{hh...} notation if they are valid UTF-8 sequences. Full details of the PCRE -options are given in the +As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes +all non-printing characters in output strings to be printed using the +\x{hh...} notation. Otherwise, those less than 0x100 are output in hex without +the curly brackets. +

    +

    +Full details of the PCRE options are given in the pcreapi documentation.

    @@ -246,14 +341,14 @@ by the /g or /G modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The difference between /g and /G is that the former uses the startoffset argument to -pcre_exec() to start searching at a new point within the entire string -(which is in effect what Perl does), whereas the latter passes over a shortened -substring. This makes a difference to the matching process if the pattern -begins with a lookbehind assertion (including \b or \B). +pcre[16]_exec() to start searching at a new point within the entire +string (which is in effect what Perl does), whereas the latter passes over a +shortened substring. This makes a difference to the matching process if the +pattern begins with a lookbehind assertion (including \b or \B).

    -If any call to pcre_exec() in a /g or /G sequence matches an -empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and +If any call to pcre[16]_exec() in a /g or /G sequence matches +an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set in order to search for another, non-empty, match at the same point. If this second match fails, the start offset is advanced, and the normal match is retried. This imitates the way Perl handles such cases when @@ -271,17 +366,29 @@

    The /+ modifier requests that as well as outputting the substring that -matched the entire pattern, pcretest should in addition output the remainder of -the subject string. This is useful for tests where the subject contains -multiple copies of the same substring. +matched the entire pattern, pcretest should in addition output the +remainder of the subject string. This is useful for tests where the subject +contains multiple copies of the same substring. If the + modifier appears +twice, the same action is taken for captured substrings. In each case the +remainder is output on the following line with a plus character following the +capture number. Note that this modifier must not immediately follow the /S +modifier because /S+ and /S++ have other meanings. +

    +

    +The /= modifier requests that the values of all potential captured +parentheses be output after a match. By default, only those up to the highest +one actually used in the match are output (corresponding to the return code +from pcre[16]_exec()). Values in the offsets vector corresponding to +higher numbers should be set to -1, and these are output as "<unset>". This +modifier gives a way of checking that this is happening.

    The /B modifier is a debugging feature. It requests that pcretest -output a representation of the compiled byte code after compilation. Normally -this information contains length and offset values; however, if /Z is -also present, this data is replaced by spaces. This is a special feature for -use in the automatic test scripts; it ensures that the same output is generated -for different internal link sizes. +output a representation of the compiled code after compilation. Normally this +information contains length and offset values; however, if /Z is also +present, this data is replaced by spaces. This is a special feature for use in +the automatic test scripts; it ensures that the same output is generated for +different internal link sizes.

    The /D modifier is a PCRE debugging feature, and is equivalent to @@ -289,29 +396,29 @@

    The /F modifier causes pcretest to flip the byte order of the -fields in the compiled pattern that contain 2-byte and 4-byte numbers. This -facility is for testing the feature in PCRE that allows it to execute patterns -that were compiled on a host with a different endianness. This feature is not -available when the POSIX interface to PCRE is being used, that is, when the -/P pattern modifier is specified. See also the section about saving and -reloading compiled patterns below. +2-byte and 4-byte fields in the compiled pattern. This facility is for testing +the feature in PCRE that allows it to execute patterns that were compiled on a +host with a different endianness. This feature is not available when the POSIX +interface to PCRE is being used, that is, when the /P pattern modifier is +specified. See also the section about saving and reloading compiled patterns +below.

    The /I modifier requests that pcretest output information about the compiled pattern (whether it is anchored, has a fixed first character, and -so on). It does this by calling pcre_fullinfo() after compiling a +so on). It does this by calling pcre[16]_fullinfo() after compiling a pattern. If the pattern is studied, the results of that are also output.

    The /K modifier requests pcretest to show names from backtracking -control verbs that are returned from calls to pcre_exec(). It causes -pcretest to create a pcre_extra block if one has not already been -created by a call to pcre_study(), and to set the PCRE_EXTRA_MARK flag -and the mark field within it, every time that pcre_exec() is -called. If the variable that the mark field points to is non-NULL for a -match, non-match, or partial match, pcretest prints the string to which -it points. For a match, this is shown on a line by itself, tagged with "MK:". -For a non-match it is added to the message. +control verbs that are returned from calls to pcre[16]_exec(). It causes +pcretest to create a pcre[16]_extra block if one has not already +been created by a call to pcre[16]_study(), and to set the +PCRE_EXTRA_MARK flag and the mark field within it, every time that +pcre[16]_exec() is called. If the variable that the mark field +points to is non-NULL for a match, non-match, or partial match, pcretest +prints the string to which it points. For a match, this is shown on a line by +itself, tagged with "MK:". For a non-match it is added to the message.

    The /L modifier must be followed directly by the name of a locale, for @@ -320,25 +427,62 @@ /pattern/Lfr_FR

    For this reason, it must be the last modifier. The given locale is set, -pcre_maketables() is called to build a set of character tables for the -locale, and this is then passed to pcre_compile() when compiling the -regular expression. Without an /L (or /T) modifier, NULL is passed -as the tables pointer; that is, /L applies only to the expression on -which it appears. -

    -

    -The /M modifier causes the size of memory block used to hold the compiled -pattern to be output. -

    -

    -The /S modifier causes pcre_study() to be called after the -expression has been compiled, and the results used when the expression is -matched. +pcre[16]_maketables() is called to build a set of character tables for +the locale, and this is then passed to pcre[16]_compile() when compiling +the regular expression. Without an /L (or /T) modifier, NULL is +passed as the tables pointer; that is, /L applies only to the expression +on which it appears. +

    +

    +The /M modifier causes the size in bytes of the memory block used to hold +the compiled pattern to be output. This does not include the size of the +pcre[16] block; it is just the actual compiled data. If the pattern is +successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the +JIT compiled code is also output. +

    +

    +If the /S modifier appears once, it causes pcre[16]_study() to be +called after the expression has been compiled, and the results used when the +expression is matched. If /S appears twice, it suppresses studying, even +if it was requested externally by the -s command line option. This makes +it possible to specify that certain patterns are always studied, and others are +never studied, independently of -s. This feature is used in the test +files in a few cases where the output is different when the pattern is studied. +

    +

    +If the /S modifier is immediately followed by a + character, the call to +pcre[16]_study() is made with all the JIT study options, requesting +just-in-time optimization support if it is available, for both normal and +partial matching. If you want to restrict the JIT compiling modes, you can +follow /S+ with a digit in the range 1 to 7: +

    +  1  normal match only
    +  2  soft partial match only
    +  3  normal match and soft partial match
    +  4  hard partial match only
    +  6  soft and hard partial match
    +  7  all three modes (default)
    +
    +If /S++ is used instead of /S+ (with or without a following digit), +the text "(JIT)" is added to the first output line after a match or no match +when JIT-compiled code was actually used. +

    +

    +Note that there is also an independent /+ modifier; it must not be given +immediately after /S or /S+ because this will be misinterpreted. +

    +

    +If JIT studying is successful, the compiled JIT code will automatically be used +when pcre[16]_exec() is run, except when incompatible run-time options +are specified. For more details, see the +pcrejit +documentation. See also the \J escape sequence below for a way of +setting the size of the JIT stack.

    The /T modifier must be followed by a single digit. It causes a specific -set of built-in character tables to be passed to pcre_compile(). It is -used in the standard PCRE tests to check behaviour with different character +set of built-in character tables to be passed to pcre[16]_compile(). It +is used in the standard PCRE tests to check behaviour with different character tables. The digit specifies the tables as follows:

       0   the default ASCII tables, as distributed in
    @@ -353,8 +497,9 @@
     

    The /P modifier causes pcretest to call PCRE via the POSIX wrapper -API rather than its native API. When /P is set, the following modifiers -set options for the regcomp() function: +API rather than its native API. This supports only the 8-bit library. When +/P is set, the following modifiers set options for the regcomp() +function:

       /i    REG_ICASE
       /m    REG_NEWLINE
    @@ -367,11 +512,11 @@
     The /+ modifier works as described above. All other modifiers are
     ignored.
     

    -
    DATA LINES
    +
    DATA LINES

    -Before each data line is passed to pcre_exec(), leading and trailing -whitespace is removed, and it is then scanned for \ escapes. Some of these are -pretty esoteric features, intended for checking out some of the more +Before each data line is passed to pcre[16]_exec(), leading and trailing +white space is removed, and it is then scanned for \ escapes. Some of these +are pretty esoteric features, intended for checking out some of the more complicated features of PCRE. If you are just testing "ordinary" regular expressions, you probably don't need any of these. The following escapes are recognized: @@ -379,58 +524,68 @@ \a alarm (BEL, \x07) \b backspace (\x08) \e escape (\x27) - \f formfeed (\x0c) + \f form feed (\x0c) \n newline (\x0a) \qdd set the PCRE_MATCH_LIMIT limit to dd (any number of digits) \r carriage return (\x0d) \t tab (\x09) \v vertical tab (\x0b) - \nnn octal character (up to 3 octal digits) - always a byte unless > 255 in UTF-8 mode + \nnn octal character (up to 3 octal digits); always + a byte unless > 255 in UTF-8 or 16-bit mode \xhh hexadecimal byte (up to 2 hex digits) - \x{hh...} hexadecimal character, any number of digits in UTF-8 mode - \A pass the PCRE_ANCHORED option to pcre_exec() or pcre_dfa_exec() - \B pass the PCRE_NOTBOL option to pcre_exec() or pcre_dfa_exec() - \Cdd call pcre_copy_substring() for substring dd after a successful match (number less than 32) - \Cname call pcre_copy_named_substring() for substring "name" after a successful match (name termin- + \x{hh...} hexadecimal character (any number of hex digits) + \A pass the PCRE_ANCHORED option to pcre[16]_exec() or pcre[16]_dfa_exec() + \B pass the PCRE_NOTBOL option to pcre[16]_exec() or pcre[16]_dfa_exec() + \Cdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32) + \Cname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin- ated by next non alphanumeric character) \C+ show the current captured substrings at callout time \C- do not supply a callout function \C!n return 1 instead of 0 when callout number n is reached \C!n!m return 1 instead of 0 when callout number n is reached for the nth time \C*n pass the number n (may be negative) as callout data; this is used as the callout return value - \D use the pcre_dfa_exec() match function - \F only shortest match for pcre_dfa_exec() - \Gdd call pcre_get_substring() for substring dd after a successful match (number less than 32) - \Gname call pcre_get_named_substring() for substring "name" after a successful match (name termin- + \D use the pcre[16]_dfa_exec() match function + \F only shortest match for pcre[16]_dfa_exec() + \Gdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32) + \Gname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin- ated by next non-alphanumeric character) - \L call pcre_get_substringlist() after a successful match + \Jdd set up a JIT stack of dd kilobytes maximum (any number of digits) + \L call pcre[16]_get_substringlist() after a successful match \M discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings - \N pass the PCRE_NOTEMPTY option to pcre_exec() or pcre_dfa_exec(); if used twice, pass the + \N pass the PCRE_NOTEMPTY option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the PCRE_NOTEMPTY_ATSTART option - \Odd set the size of the output vector passed to pcre_exec() to dd (any number of digits) - \P pass the PCRE_PARTIAL_SOFT option to pcre_exec() or pcre_dfa_exec(); if used twice, pass the + \Odd set the size of the output vector passed to pcre[16]_exec() to dd (any number of digits) + \P pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the PCRE_PARTIAL_HARD option \Qdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits) - \R pass the PCRE_DFA_RESTART option to pcre_dfa_exec() + \R pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec() \S output details of memory get/free calls during matching - \Y pass the PCRE_NO_START_OPTIMIZE option to pcre_exec() or pcre_dfa_exec() - \Z pass the PCRE_NOTEOL option to pcre_exec() or pcre_dfa_exec() - \? pass the PCRE_NO_UTF8_CHECK option to pcre_exec() or pcre_dfa_exec() + \Y pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec() or pcre[16]_dfa_exec() + \Z pass the PCRE_NOTEOL option to pcre[16]_exec() or pcre[16]_dfa_exec() + \? pass the PCRE_NO_UTF[8|16]_CHECK option to pcre[16]_exec() or pcre[16]_dfa_exec() \>dd start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset - argument for pcre_exec() or pcre_dfa_exec() - \<cr> pass the PCRE_NEWLINE_CR option to pcre_exec() or pcre_dfa_exec() - \<lf> pass the PCRE_NEWLINE_LF option to pcre_exec() or pcre_dfa_exec() - \<crlf> pass the PCRE_NEWLINE_CRLF option to pcre_exec() or pcre_dfa_exec() - \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre_exec() or pcre_dfa_exec() - \<any> pass the PCRE_NEWLINE_ANY option to pcre_exec() or pcre_dfa_exec() -

    -Note that \xhh always specifies one byte, even in UTF-8 mode; this makes it -possible to construct invalid UTF-8 sequences for testing purposes. On the -other hand, \x{hh} is interpreted as a UTF-8 character in UTF-8 mode, -generating more than one byte if the value is greater than 127. When not in -UTF-8 mode, it generates one byte for values less than 256, and causes an error -for greater values. + argument for pcre[16]_exec() or pcre[16]_dfa_exec() + \<cr> pass the PCRE_NEWLINE_CR option to pcre[16]_exec() or pcre[16]_dfa_exec() + \<lf> pass the PCRE_NEWLINE_LF option to pcre[16]_exec() or pcre[16]_dfa_exec() + \<crlf> pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec() or pcre[16]_dfa_exec() + \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec() or pcre[16]_dfa_exec() + \<any> pass the PCRE_NEWLINE_ANY option to pcre[16]_exec() or pcre[16]_dfa_exec() +
    +The use of \x{hh...} is not dependent on the use of the /8 modifier on +the pattern. It is recognized always. There may be any number of hexadecimal +digits inside the braces; invalid values provoke error messages. +

    +

    +Note that \xhh specifies one byte rather than one character in UTF-8 mode; +this makes it possible to construct invalid UTF-8 sequences for testing +purposes. On the other hand, \x{hh} is interpreted as a UTF-8 character in +UTF-8 mode, generating more than one byte if the value is greater than 127. +When testing the 8-bit library not in UTF-8 mode, \x{hh} generates one byte +for values less than 256, and causes an error for greater values. +

    +

    +In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it +possible to construct invalid UTF-16 sequences for testing purposes.

    The escapes that specify line ending sequences are literal strings, exactly as @@ -443,22 +598,33 @@ input.

    -If \M is present, pcretest calls pcre_exec() several times, with -different values in the match_limit and match_limit_recursion -fields of the pcre_extra data structure, until it finds the minimum -numbers for each parameter that allow pcre_exec() to complete. The -match_limit number is a measure of the amount of backtracking that takes -place, and checking it out can be instructive. For most simple matches, the -number is quite small, but for patterns with very large numbers of matching -possibilities, it can become large very quickly with increasing length of -subject string. The match_limit_recursion number is a measure of how much -stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed -to complete the match attempt. +The \J escape provides a way of setting the maximum stack size that is +used by the just-in-time optimization code. It is ignored if JIT optimization +is not being used. Providing a stack that is larger than the default 32K is +necessary only for very complicated patterns. +

    +

    +If \M is present, pcretest calls pcre[16]_exec() several times, +with different values in the match_limit and match_limit_recursion +fields of the pcre[16]_extra data structure, until it finds the minimum +numbers for each parameter that allow pcre[16]_exec() to complete without +error. Because this is testing a specific feature of the normal interpretive +pcre[16]_exec() execution, the use of any JIT optimization that might +have been set up by the /S+ qualifier of -s+ option is disabled. +

    +

    +The match_limit number is a measure of the amount of backtracking +that takes place, and checking it out can be instructive. For most simple +matches, the number is quite small, but for patterns with very large numbers of +matching possibilities, it can become large very quickly with increasing length +of subject string. The match_limit_recursion number is a measure of how +much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is +needed to complete the match attempt.

    When \O is used, the value specified may be higher or lower than the size set by the -O command line option (or defaulted to 45); \O applies only to -the call of pcre_exec() for the line in which it appears. +the call of pcre[16]_exec() for the line in which it appears.

    If the /P modifier was present on the pattern, causing the POSIX wrapper @@ -466,20 +632,11 @@ \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to regexec().

    -

    -The use of \x{hh...} to represent UTF-8 characters is not dependent on the use -of the /8 modifier on the pattern. It is recognized always. There may be -any number of hexadecimal digits inside the braces. The result is from one to -six bytes, encoded according to the original UTF-8 rules of RFC 2279. This -allows for values in the range 0 to 0x7FFFFFFF. Note that not all of those are -valid Unicode code points, or indeed valid UTF-8 characters according to the -later rules in RFC 3629. -

    -
    THE ALTERNATIVE MATCHING FUNCTION
    +
    THE ALTERNATIVE MATCHING FUNCTION

    By default, pcretest uses the standard PCRE matching function, -pcre_exec() to match each data line. From release 6.0, PCRE supports an -alternative matching function, pcre_dfa_test(), which operates in a +pcre[16]_exec() to match each data line. PCRE also supports an +alternative matching function, pcre[16]_dfa_test(), which operates in a different way, and has some restrictions. The differences between the two functions are described in the pcrematching @@ -487,29 +644,32 @@

    If a data line contains the \D escape sequence, or if the command line -contains the -dfa option, the alternative matching function is called. +contains the -dfa option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, the \F escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match.

    -
    DEFAULT OUTPUT FROM PCRETEST
    +
    DEFAULT OUTPUT FROM PCRETEST

    This section describes the output when the normal matching function, -pcre_exec(), is being used. +pcre[16]_exec(), is being used.

    -When a match succeeds, pcretest outputs the list of captured substrings that -pcre_exec() returns, starting with number 0 for the string that matched -the whole pattern. Otherwise, it outputs "No match" when the return is +When a match succeeds, pcretest outputs the list of captured substrings +that pcre[16]_exec() returns, starting with number 0 for the string that +matched the whole pattern. Otherwise, it outputs "No match" when the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching -substring when pcre_exec() returns PCRE_ERROR_PARTIAL. (Note that this is -the entire substring that was inspected during the partial match; it may -include characters before the actual match start if a lookbehind assertion, -\K, \b, or \B was involved.) For any other returns, it outputs the PCRE -negative error number. Here is an example of an interactive pcretest run. +substring when pcre[16]_exec() returns PCRE_ERROR_PARTIAL. (Note that +this is the entire substring that was inspected during the partial match; it +may include characters before the actual match start if a lookbehind assertion, +\K, \b, or \B was involved.) For any other return, pcretest outputs +the PCRE negative error number and a short descriptive phrase. If the error is +a failed UTF string check, the offset of the start of the failing character and +the reason code are also output, provided that the size of the output vector is +at least two. Here is an example of an interactive pcretest run.

       $ pcretest
    -  PCRE version 7.0 30-Nov-2006
    +  PCRE version 8.13 2011-04-30
     
         re> /^abc(\d+)/
       data> abc123
    @@ -518,11 +678,11 @@
       data> xyz
       No match
     
    -Note that unset capturing substrings that are not followed by one that is set -are not returned by pcre_exec(), and are not shown by pcretest. In -the following example, there are two capturing substrings, but when the first -data line is matched, the second, unset substring is not shown. An "internal" -unset substring is shown as "<unset>", as for the second data line. +Unset capturing substrings that are not followed by one that is set are not +returned by pcre[16]_exec(), and are not shown by pcretest. In the +following example, there are two capturing substrings, but when the first data +line is matched, the second, unset substring is not shown. An "internal" unset +substring is shown as "<unset>", as for the second data line.
         re> /(a)|(b)/
       data> a
    @@ -533,11 +693,12 @@
        1: <unset>
        2: b
     
    -If the strings contain any non-printing characters, they are output as \0x -escapes, or as \x{...} escapes if the /8 modifier was present on the -pattern. See below for the definition of non-printing characters. If the -pattern has the /+ modifier, the output for substring 0 is followed by -the the rest of the subject string, identified by "0+" like this: +If the strings contain any non-printing characters, they are output as \xhh +escapes if the value is less than 256 and UTF mode is not set. Otherwise they +are output as \x{hh...} escapes. See below for the definition of non-printing +characters. If the pattern has the /+ modifier, the output for substring +0 is followed by the the rest of the subject string, identified by "0+" like +this:
         re> /cat/+
       data> cataract
    @@ -556,7 +717,14 @@
        0: ipp
        1: pp
     
    -"No match" is output only if the first match attempt fails. +"No match" is output only if the first match attempt fails. Here is an example +of a failure message (the offset 4 that is specified by \>4 is past the end of +the subject string): +
    +    re> /xyz/
    +  data> xyz\>4
    +  Error -24 (bad offset value)
    +

    If any of the sequences \C, \G, or \L are present in a @@ -572,9 +740,9 @@ included in data by means of the \n escape (or \r, \r\n, etc., depending on the newline sequence setting).

    -
    OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
    +
    OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION

    -When the alternative matching function, pcre_dfa_exec(), is used (by +When the alternative matching function, pcre[16]_dfa_exec(), is used (by means of the \D escape sequence or the -dfa command line option), the output consists of a list of all the matches that start at the first point in the subject where there is at least one match. For example: @@ -608,7 +776,7 @@ Since the matching function does not support substring capture, the escape sequences that are concerned with captured substrings are not relevant.

    -
    RESTARTING AFTER A PARTIAL MATCH
    +
    RESTARTING AFTER A PARTIAL MATCH

    When the alternative matching function has given the PCRE_ERROR_PARTIAL return, indicating that the subject partially matched the pattern, you can restart the @@ -625,21 +793,21 @@ pcrepartial documentation.

    -
    CALLOUTS
    +
    CALLOUTS

    If the pattern contains any callout requests, pcretest's callout function is called during matching. This works with both matching functions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the next pattern item to be -tested. For example, the output +tested. For example:

       --->pqrabcdef
         0    ^  ^     \d
     
    -indicates that callout number 0 occurred for a match attempt starting at the -fourth character of the subject string, when the pointer was at the seventh -character of the data, and when the next pattern item was \d. Just one -circumflex is output if the start and current positions are the same. +This output indicates that callout number 0 occurred for a match attempt +starting at the fourth character of the subject string, when the pointer was at +the seventh character of the data, and when the next pattern item was \d. Just +one circumflex is output if the start and current positions are the same.

    Callouts numbered 255 are assumed to be automatic callouts, inserted as a @@ -656,9 +824,28 @@ +10 ^ ^ 0: E*

    +If a pattern contains (*MARK) items, an additional line is output whenever +a change of latest mark is passed to the callout function. For example: +
    +    re> /a(*MARK:X)bc/C
    +  data> abc
    +  --->abc
    +   +0 ^       a
    +   +1 ^^      (*MARK:X)
    +  +10 ^^      b
    +  Latest Mark: X
    +  +11 ^ ^     c
    +  +12 ^  ^
    +   0: abc
    +
    +The mark changes between matching "a" and "b", but stays the same for the rest +of the match, so nothing more is output. If, as a result of backtracking, the +mark reverts to being unset, the text "<unset>" is output. +

    +

    The callout function in pcretest returns zero (carry on matching) by default, but you can use a \C item in a data line (as described above) to -change this. +change this and other parameters of the callout.

    Inserting callouts can be helpful when using pcretest to check @@ -667,7 +854,7 @@ pcrecallout documentation.

    -
    NON-PRINTING CHARACTERS
    +
    NON-PRINTING CHARACTERS

    When pcretest is outputting text in the compiled version of a pattern, bytes other than 32-126 are always treated as non-printing characters are are @@ -679,10 +866,10 @@ the pattern (using the /L modifier). In this case, the isprint() function to distinguish printing and non-printing characters.

    -
    SAVING AND RELOADING COMPILED PATTERNS
    +
    SAVING AND RELOADING COMPILED PATTERNS

    The facilities described in this section are not available when the POSIX -inteface to PCRE is being used, that is, when the /P pattern modifier is +interface to PCRE is being used, that is, when the /P pattern modifier is specified.

    @@ -695,6 +882,8 @@ See the pcreprecompile documentation for a discussion about saving and re-using compiled patterns. +Note that if the pattern was successfully studied with JIT optimization, the +JIT data cannot be saved.

    The data that is written is binary. The first eight bytes are the length of the @@ -703,28 +892,37 @@ there is no study data (either the pattern was not studied, or studying did not return any data), the second length is zero. The lengths are followed by an exact copy of the compiled pattern. If there is additional study data, this -follows immediately after the compiled pattern. After writing the file, -pcretest expects to read a new pattern. +(excluding any JIT data) follows immediately after the compiled pattern. After +writing the file, pcretest expects to read a new pattern.

    -A saved pattern can be reloaded into pcretest by specifing < and a file +A saved pattern can be reloaded into pcretest by specifying < and a file name instead of a pattern. The name of the file must not contain a < character, as otherwise pcretest will interpret the line as a pattern delimited by < characters. For example:

        re> </some/file
    -  Compiled regex loaded from /some/file
    +  Compiled pattern loaded from /some/file
       No study data
     
    -When the pattern has been loaded, pcretest proceeds to read data lines in -the usual way. +If the pattern was previously studied with the JIT optimization, the JIT +information cannot be saved and restored, and so is lost. When the pattern has +been loaded, pcretest proceeds to read data lines in the usual way.

    You can copy a file written by pcretest to a different host and reload it there, even if the new host has opposite endianness to the one on which the pattern was compiled. For example, you can compile on an i86 machine and run on -a SPARC machine. +a SPARC machine. When a pattern is reloaded on a host with different +endianness, the confirmation message is changed to: +

    +  Compiled pattern (byte-inverted) loaded from /some/file
    +
    +The test suite contains some saved pre-compiled patterns with different +endianness. These are reloaded using "<!" instead of just "<". This suppresses +the "(byte-inverted)" text so that the output is the same on all hosts. It also +forces debugging output once the pattern has been reloaded.

    File names for saving and reloading can be absolute or relative, but note that @@ -741,12 +939,13 @@ Finally, if you attempt to load a file that is not in the correct format, the result is undefined.

    -
    SEE ALSO
    +
    SEE ALSO

    -pcre(3), pcreapi(3), pcrecallout(3), pcrematching(3), -pcrepartial(d), pcrepattern(3), pcreprecompile(3). +pcre(3), pcre16(3), pcreapi(3), pcrecallout(3), +pcrejit, pcrematching(3), pcrepartial(d), +pcrepattern(3), pcreprecompile(3).

    -
    AUTHOR
    +
    AUTHOR

    Philip Hazel
    @@ -755,11 +954,11 @@ Cambridge CB2 3QH, England.

    -
    REVISION
    +
    REVISION

    -Last updated: 21 November 2010 +Last updated: 21 February 2012
    -Copyright © 1997-2010 University of Cambridge. +Copyright © 1997-2012 University of Cambridge.

    Return to the PCRE index page. diff -Nru pcre3-8.12/doc/html/pcreunicode.html pcre3-8.31/doc/html/pcreunicode.html --- pcre3-8.12/doc/html/pcreunicode.html 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/html/pcreunicode.html 2012-07-06 09:55:28.000000000 +0000 @@ -0,0 +1,240 @@ + + +pcreunicode specification + + +

    pcreunicode man page

    +

    +Return to the PCRE index page. +

    +

    +This page is part of the PCRE HTML documentation. It was generated automatically +from the original man page. If there is any nonsense in it, please consult the +man page, in case the conversion went wrong. +
    +
    +UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT +
    +

    +From Release 8.30, in addition to its previous UTF-8 support, PCRE also +supports UTF-16 by means of a separate 16-bit library. This can be built as +well as, or instead of, the 8-bit library. +

    +
    +UTF-8 SUPPORT +
    +

    +In order process UTF-8 strings, you must build PCRE's 8-bit library with UTF +support, and, in addition, you must call +pcre_compile() +with the PCRE_UTF8 option flag, or the pattern must start with the sequence +(*UTF8). When either of these is the case, both the pattern and any subject +strings that are matched against it are treated as UTF-8 strings instead of +strings of 1-byte characters. +

    +
    +UTF-16 SUPPORT +
    +

    +In order process UTF-16 strings, you must build PCRE's 16-bit library with UTF +support, and, in addition, you must call +pcre16_compile() +with the PCRE_UTF16 option flag, or the pattern must start with the sequence +(*UTF16). When either of these is the case, both the pattern and any subject +strings that are matched against it are treated as UTF-16 strings instead of +strings of 16-bit characters. +

    +
    +UTF SUPPORT OVERHEAD +
    +

    +If you compile PCRE with UTF support, but do not use it at run time, the +library will be a bit bigger, but the additional run time overhead is limited +to testing the PCRE_UTF8/16 flag occasionally, so should not be very big. +

    +
    +UNICODE PROPERTY SUPPORT +
    +

    +If PCRE is built with Unicode character property support (which implies UTF +support), the escape sequences \p{..}, \P{..}, and \X can be used. +The available properties that can be tested are limited to the general +category properties such as Lu for an upper case letter or Nd for a decimal +number, the Unicode script names such as Arabic or Han, and the derived +properties Any and L&. A full list is given in the +pcrepattern +documentation. Only the short names for properties are supported. For example, +\p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported. +Furthermore, in Perl, many properties may optionally be prefixed by "Is", for +compatibility with Perl 5.6. PCRE does not support this. +

    +
    +Validity of UTF-8 strings +
    +

    +When you set the PCRE_UTF8 flag, the byte strings passed as patterns and +subjects are (by default) checked for validity on entry to the relevant +functions. The entire string is checked before any other processing takes +place. From release 7.3 of PCRE, the check is according the rules of RFC 3629, +which are themselves derived from the Unicode specification. Earlier releases +of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit +values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 +to U+10FFFF, excluding U+D800 to U+DFFF. +

    +

    +The excluded code points are the "Surrogate Area" of Unicode. They are reserved +for use by UTF-16, where they are used in pairs to encode codepoints with +values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs +are available independently in the UTF-8 encoding. (In other words, the whole +surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) +

    +

    +If an invalid UTF-8 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first byte +of the failing character. The run-time functions pcre_exec() and +pcre_dfa_exec() also pass back this information, as well as a more +detailed reason code if the caller has provided memory in which to do this. +

    +

    +In some situations, you may already know that your strings are valid, and +therefore want to skip these checks in order to improve performance, for +example in the case of a long subject string that is being scanned repeatedly +with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time +or at run time, PCRE assumes that the pattern or subject it is given +(respectively) contains only valid UTF-8 codes. In this case, it does not +diagnose an invalid UTF-8 string. +

    +

    +If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what +happens depends on why the string is invalid. If the string conforms to the +"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters +in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() and the interpreted +version of pcre_exec(). In other words, apart from the initial validity +test, these functions (when in UTF-8 mode) handle strings according to the more +liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for +pcre_exec() supports only RFC 3629. If you are using JIT optimization, or +if the string does not even conform to RFC 2279, the result is undefined. Your +program may crash. +

    +

    +If you want to process strings of values in the full range 0 to 0x7FFFFFFF, +encoded in a UTF-8-like manner as per the old RFC, you can set +PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this +situation, you will have to apply your own validity check, and avoid the use of +JIT optimization. +

    +
    +Validity of UTF-16 strings +
    +

    +When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are +passed as patterns and subjects are (by default) checked for validity on entry +to the relevant functions. Values other than those in the surrogate range +U+D800 to U+DFFF are independent code points. Values in the surrogate range +must be used in pairs in the correct manner. +

    +

    +If an invalid UTF-16 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first data +unit of the failing character. The run-time functions pcre16_exec() and +pcre16_dfa_exec() also pass back this information, as well as a more +detailed reason code if the caller has provided memory in which to do this. +

    +

    +In some situations, you may already know that your strings are valid, and +therefore want to skip these checks in order to improve performance. If you set +the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that +the pattern or subject it is given (respectively) contains only valid UTF-16 +sequences. In this case, it does not diagnose an invalid UTF-16 string. +

    +
    +General comments about UTF modes +
    +

    +1. Codepoints less than 256 can be specified by either braced or unbraced +hexadecimal escape sequences (for example, \x{b3} or \xb3). Larger values +have to use braced sequences. +

    +

    +2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they match +two-byte characters for values greater than \177. +

    +

    +3. Repeat quantifiers apply to complete UTF characters, not to individual +data units, for example: \x{100}{3}. +

    +

    +4. The dot metacharacter matches one UTF character instead of a single data +unit. +

    +

    +5. The escape sequence \C can be used to match a single byte in UTF-8 mode, or +a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange +effects because it breaks up multi-unit characters (see the description of \C +in the +pcrepattern +documentation). The use of \C is not supported in the alternative matching +function pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT +optimization of pcre[16]_exec(). If JIT optimization is requested for a +UTF pattern that contains \C, it will not succeed, and so the matching will +be carried out by the normal interpretive function. +

    +

    +6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly +test characters of any code value, but, by default, the characters that PCRE +recognizes as digits, spaces, or word characters remain the same set as in +non-UTF mode, all with values less than 256. This remains true even when PCRE +is built to include Unicode property support, because to do otherwise would +slow down PCRE in many common cases. Note in particular that this applies to +\b and \B, because they are defined in terms of \w and \W. If you really +want to test for a wider sense of, say, "digit", you can use explicit Unicode +property tests such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, +the way that the character escapes work is changed so that Unicode properties +are used to determine which characters match. There are more details in the +section on +generic character types +in the +pcrepattern +documentation. +

    +

    +7. Similarly, characters that match the POSIX named character classes are all +low-valued characters, unless the PCRE_UCP option is set. +

    +

    +8. However, the horizontal and vertical white space matching escapes (\h, \H, +\v, and \V) do match all the appropriate Unicode characters, whether or not +PCRE_UCP is set. +

    +

    +9. Case-insensitive matching applies only to characters whose values are less +than 128, unless PCRE is built with Unicode property support. Even when Unicode +property support is available, PCRE still uses its own character tables when +checking the case of low-valued characters, so as not to degrade performance. +The Unicode property information is used only for characters with higher +values. Furthermore, PCRE supports case-insensitive matching only when there is +a one-to-one mapping between a letter's cases. There are a small number of +many-to-one mappings in Unicode; these are not supported by PCRE. +

    +
    +AUTHOR +
    +

    +Philip Hazel +
    +University Computing Service +
    +Cambridge CB2 3QH, England. +
    +

    +
    +REVISION +
    +

    +Last updated: 14 April 2012 +
    +Copyright © 1997-2012 University of Cambridge. +
    +

    +Return to the PCRE index page. +

    diff -Nru pcre3-8.12/doc/index.html.src pcre3-8.31/doc/index.html.src --- pcre3-8.12/doc/index.html.src 2009-09-01 15:57:04.000000000 +0000 +++ pcre3-8.31/doc/index.html.src 2012-04-14 16:12:49.000000000 +0000 @@ -18,6 +18,9 @@ pcre   Introductory page +pcre16 +   Discussion of the 16-bit PCRE library + pcre-config   Information about the installation configuration @@ -42,6 +45,12 @@ pcregrep   The pcregrep command +pcrejit +   Discussion of the just-in-time optimization support + +pcrelimits +   Details of size and other limits + pcrematching   Discussion of the two matching algorithms @@ -71,15 +80,21 @@ pcretest   The pcretest command for testing PCRE + +pcreunicode +   Discussion of Unicode and UTF-8/UTF-16 support

    There are also individual pages that summarize the interface for each function -in the library: +in the library. There is a single page for each pair of 8-bit/16-bit functions.

    + + + @@ -99,6 +114,9 @@ + + + @@ -127,15 +145,27 @@ + + + + + + + + + + + +
    pcre_assign_jit_stack  Assign stack for JIT matching
    pcre_compile   Compile a regular expression
      Match a compiled pattern to a subject string (DFA algorithm; not Perl compatible)
    pcre_free_study  Free study data
    pcre_exec   Match a compiled pattern to a subject string (Perl compatible)
    pcre_info   Obsolete information extraction function
    pcre_jit_stack_alloc  Create a stack for JIT matching
    pcre_jit_stack_free  Free a JIT matching stack
    pcre_maketables   Build character tables in current locale
    pcre_pattern_to_host_byte_order  Convert compiled pattern to host byte order if necessary
    pcre_refcount   Maintain reference count in compiled pattern
    pcre_study   Study a compiled pattern
    pcre_utf16_to_host_byte_order  Convert UTF-16 string to host byte order if necessary
    pcre_version   Return PCRE version and release date
    diff -Nru pcre3-8.12/doc/pcre-config.1 pcre3-8.31/doc/pcre-config.1 --- pcre3-8.12/doc/pcre-config.1 2007-04-18 09:05:55.000000000 +0000 +++ pcre3-8.31/doc/pcre-config.1 2012-03-31 16:13:48.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE-CONFIG 1 +.TH PCRE-CONFIG 1 "01 January 2012" "PCRE 8.30" .SH NAME pcre-config - program to return PCRE configuration .SH SYNOPSIS @@ -6,14 +6,19 @@ .sp .B pcre-config [--prefix] [--exec-prefix] [--version] [--libs] .ti +5n -.B [--libs-posix] [--cflags] [--cflags-posix] +.B [--libs16] [--libs-cpp] [--libs-posix] [--cflags] +.ti +5n +.B [--cflags-posix] . . .SH DESCRIPTION .rs .sp \fBpcre-config\fP returns the configuration of the installed PCRE -libraries and the options required to compile a program to use them. +libraries and the options required to compile a program to use them. Some of +the options apply only to the 8-bit or 16-bit libraries, respectively, and are +not available if only one of those libraries has been built. If an unavailable +option is encountered, the "usage" information is output. . . .SH OPTIONS @@ -34,11 +39,20 @@ .TP 10 \fB--libs\fP Writes to the standard output the command line options required to link -with PCRE (\fB-lpcre\fP on many systems). +with the 8-bit PCRE library (\fB-lpcre\fP on many systems). +.TP 10 +\fB--libs16\fP +Writes to the standard output the command line options required to link +with the 16-bit PCRE library (\fB-lpcre16\fP on many systems). +.TP 10 +\fB--libs-cpp\fP +Writes to the standard output the command line options required to link with +PCRE's C++ wrapper library (\fB-lpcrecpp\fP \fB-lpcre\fP on many +systems). .TP 10 \fB--libs-posix\fP Writes to the standard output the command line options required to link with -the PCRE posix emulation library (\fB-lpcreposix\fP \fB-lpcre\fP on many +PCRE's POSIX API wrapper library (\fB-lpcreposix\fP \fB-lpcre\fP on many systems). .TP 10 \fB--cflags\fP @@ -48,7 +62,7 @@ .TP 10 \fB--cflags-posix\fP Writes to the standard output the command line options required to compile -files that use the PCRE posix emulation library (this may include some \fB-I\fP +files that use PCRE's POSIX API wrapper library (this may include some \fB-I\fP options, but is blank on many systems). . . @@ -62,12 +76,12 @@ .rs .sp This manual page was originally written by Mark Baker for the Debian GNU/Linux -system. It has been slightly revised as a generic PCRE man page. +system. It has been subsequently revised as a generic PCRE man page. . . .SH REVISION .rs .sp .nf -Last updated: 18 April 2007 +Last updated: 01 January 2012 .fi diff -Nru pcre3-8.12/doc/pcre-config.txt pcre3-8.31/doc/pcre-config.txt --- pcre3-8.12/doc/pcre-config.txt 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/pcre-config.txt 2012-07-06 09:55:27.000000000 +0000 @@ -8,35 +8,49 @@ SYNOPSIS pcre-config [--prefix] [--exec-prefix] [--version] [--libs] - [--libs-posix] [--cflags] [--cflags-posix] + [--libs16] [--libs-cpp] [--libs-posix] [--cflags] + [--cflags-posix] DESCRIPTION pcre-config returns the configuration of the installed PCRE libraries - and the options required to compile a program to use them. + and the options required to compile a program to use them. Some of the + options apply only to the 8-bit or 16-bit libraries, respectively, and + are not available if only one of those libraries has been built. If an + unavailable option is encountered, the "usage" information is output. OPTIONS --prefix Writes the directory prefix used in the PCRE installation for - architecture independent files (/usr on many systems, + architecture independent files (/usr on many systems, /usr/local on some systems) to the standard output. --exec-prefix Writes the directory prefix used in the PCRE installation for - architecture dependent files (normally the same as --prefix) + architecture dependent files (normally the same as --prefix) to the standard output. - --version Writes the version number of the installed PCRE libraries to + --version Writes the version number of the installed PCRE libraries to the standard output. - --libs Writes to the standard output the command line options - required to link with PCRE (-lpcre on many systems). + --libs Writes to the standard output the command line options + required to link with the 8-bit PCRE library (-lpcre on many + systems). + + --libs16 Writes to the standard output the command line options + required to link with the 16-bit PCRE library (-lpcre16 on + many systems). + + --libs-cpp + Writes to the standard output the command line options + required to link with PCRE's C++ wrapper library (-lpcrecpp + -lpcre on many systems). --libs-posix Writes to the standard output the command line options - required to link with the PCRE posix emulation library + required to link with PCRE's POSIX API wrapper library (-lpcreposix -lpcre on many systems). --cflags Writes to the standard output the command line options @@ -45,7 +59,7 @@ --cflags-posix Writes to the standard output the command line options - required to compile files that use the PCRE posix emulation + required to compile files that use PCRE's POSIX API wrapper library (this may include some -I options, but is blank on many systems). @@ -58,10 +72,10 @@ AUTHOR This manual page was originally written by Mark Baker for the Debian - GNU/Linux system. It has been slightly revised as a generic PCRE man - page. + GNU/Linux system. It has been subsequently revised as a generic PCRE + man page. REVISION - Last updated: 18 April 2007 + Last updated: 01 January 2012 diff -Nru pcre3-8.12/doc/pcre.3 pcre3-8.31/doc/pcre.3 --- pcre3-8.12/doc/pcre.3 2011-01-11 16:28:57.000000000 +0000 +++ pcre3-8.31/doc/pcre.3 2012-03-31 16:31:44.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE 3 +.TH PCRE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH INTRODUCTION @@ -11,10 +11,29 @@ support for one or two .NET and Oniguruma syntax items, and there is an option for requesting some minor changes that give better JavaScript compatibility. .P +Starting with release 8.30, it is possible to compile two separate PCRE +libraries: the original, which supports 8-bit character strings (including +UTF-8 strings), and a second library that supports 16-bit character strings +(including UTF-16 strings). The build process allows either one or both to be +built. The majority of the work to make this possible was done by Zoltan +Herczeg. +.P +The two libraries contain identical sets of functions, except that the names in +the 16-bit library start with \fBpcre16_\fP instead of \fBpcre_\fP. To avoid +over-complication and reduce the documentation maintenance load, most of the +documentation describes the 8-bit library, with the differences for the 16-bit +library described separately in the +.\" HREF +\fBpcre16\fP +.\" +page. References to functions or structures of the form \fIpcre[16]_xxx\fP +should be read as meaning "\fIpcre_xxx\fP when using the 8-bit library and +\fIpcre16_xxx\fP when using the 16-bit library". +.P The current implementation of PCRE corresponds approximately with Perl 5.12, -including support for UTF-8 encoded strings and Unicode general category -properties. However, UTF-8 and Unicode support has to be explicitly enabled; it -is not the default. The Unicode tables correspond to Unicode release 5.2.0. +including support for UTF-8/16 encoded strings and Unicode general category +properties. However, UTF-8/16 and Unicode support has to be explicitly enabled; +it is not the default. The Unicode tables correspond to Unicode release 6.0.0. .P In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a different @@ -27,8 +46,8 @@ .P PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, Google Inc. -have provided a comprehensive C++ wrapper. This is now included as part of the -PCRE distribution. The +have provided a comprehensive C++ wrapper for the 8-bit library. This is now +included as part of the PCRE distribution. The .\" HREF \fBpcrecpp\fP .\" @@ -68,13 +87,13 @@ found in the \fBREADME\fP and \fBNON-UNIX-USE\fP files in the source distribution. .P -The library contains a number of undocumented internal functions and data +The libraries contains a number of undocumented internal functions and data tables that are used by more than one of the exported external functions, but which are not intended for use by external callers. Their names all begin with -"_pcre_", which hopefully will not provoke any name clashes. In some -environments, it is possible to control which external symbols are exported -when a shared library is built, and in these cases the undocumented symbols are -not exported. +"_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In +some environments, it is possible to control which external symbols are +exported when a shared library is built, and in these cases the undocumented +symbols are not exported. . . .SH "USER DOCUMENTATION" @@ -87,203 +106,33 @@ of searching. The sections are as follows: .sp pcre this document + pcre16 details of the 16-bit library pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API pcrebuild options for building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility - pcrecpp details of the C++ wrapper + pcrecpp details of the C++ wrapper for the 8-bit library pcredemo a demonstration C program that uses PCRE - pcregrep description of the \fBpcregrep\fP command + pcregrep description of the \fBpcregrep\fP command (8-bit only) + pcrejit discussion of the just-in-time optimization support + pcrelimits details of size and other limits pcrematching discussion of the two matching algorithms pcrepartial details of the partial matching facility .\" JOIN pcrepattern syntax and semantics of supported regular expressions pcreperform discussion of performance issues - pcreposix the POSIX-compatible C API + pcreposix the POSIX-compatible C API for the 8-bit library pcreprecompile details of saving and re-using precompiled patterns pcresample discussion of the pcredemo program pcrestack discussion of stack usage pcresyntax quick syntax reference pcretest description of the \fBpcretest\fP testing command + pcreunicode discussion of Unicode and UTF-8/16 support .sp In addition, in the "man" and HTML formats, there is a short page for each -C library function, listing its arguments and results. -. -. -.SH LIMITATIONS -.rs -.sp -There are some size limitations in PCRE but it is hoped that they will never in -practice be relevant. -.P -The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE is -compiled with the default internal linkage size of 2. If you want to process -regular expressions that are truly enormous, you can compile PCRE with an -internal linkage size of 3 or 4 (see the \fBREADME\fP file in the source -distribution and the -.\" HREF -\fBpcrebuild\fP -.\" -documentation for details). In these cases the limit is substantially larger. -However, the speed of execution is slower. -.P -All values in repeating quantifiers must be less than 65536. -.P -There is no limit to the number of parenthesized subpatterns, but there can be -no more than 65535 capturing subpatterns. -.P -The maximum length of name for a named subpattern is 32 characters, and the -maximum number of named subpatterns is 10000. -.P -The maximum length of a subject string is the largest positive number that an -integer variable can hold. However, when using the traditional matching -function, PCRE uses recursion to handle subpatterns and indefinite repetition. -This means that the available stack space may limit the size of a subject -string that can be processed by certain patterns. For a discussion of stack -issues, see the -.\" HREF -\fBpcrestack\fP -.\" -documentation. -. -. -.\" HTML -.SH "UTF-8 AND UNICODE PROPERTY SUPPORT" -.rs -.sp -From release 3.3, PCRE has had some support for character strings encoded in -the UTF-8 format. For release 4.0 this was greatly extended to cover most -common requirements, and in release 5.0 additional support for Unicode general -category properties was added. -.P -In order process UTF-8 strings, you must build PCRE to include UTF-8 support in -the code, and, in addition, you must call -.\" HREF -\fBpcre_compile()\fP -.\" -with the PCRE_UTF8 option flag, or the pattern must start with the sequence -(*UTF8). When either of these is the case, both the pattern and any subject -strings that are matched against it are treated as UTF-8 strings instead of -strings of 1-byte characters. -.P -If you compile PCRE with UTF-8 support, but do not use it at run time, the -library will be a bit bigger, but the additional run time overhead is limited -to testing the PCRE_UTF8 flag occasionally, so should not be very big. -.P -If PCRE is built with Unicode character property support (which implies UTF-8 -support), the escape sequences \ep{..}, \eP{..}, and \eX are supported. -The available properties that can be tested are limited to the general -category properties such as Lu for an upper case letter or Nd for a decimal -number, the Unicode script names such as Arabic or Han, and the derived -properties Any and L&. A full list is given in the -.\" HREF -\fBpcrepattern\fP -.\" -documentation. Only the short names for properties are supported. For example, -\ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported. -Furthermore, in Perl, many properties may optionally be prefixed by "Is", for -compatibility with Perl 5.6. PCRE does not support this. -. -. -.\" HTML -.SS "Validity of UTF-8 strings" -.rs -.sp -When you set the PCRE_UTF8 flag, the strings passed as patterns and subjects -are (by default) checked for validity on entry to the relevant functions. From -release 7.3 of PCRE, the check is according the rules of RFC 3629, which are -themselves derived from the Unicode specification. Earlier releases of PCRE -followed the rules of RFC 2279, which allows the full range of 31-bit values (0 -to 0x7FFFFFFF). The current check allows only values in the range U+0 to -U+10FFFF, excluding U+D800 to U+DFFF. -.P -The excluded code points are the "Low Surrogate Area" of Unicode, of which the -Unicode Standard says this: "The Low Surrogate Area does not contain any -character assignments, consequently no character code charts or namelists are -provided for this area. Surrogates are reserved for use with UTF-16 and then -must be used in pairs." The code points that are encoded by UTF-16 pairs are -available as independent code points in the UTF-8 encoding. (In other words, -the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up -UTF-8.) -.P -If an invalid UTF-8 string is passed to PCRE, an error return -(PCRE_ERROR_BADUTF8) is given. In some situations, you may already know that -your strings are valid, and therefore want to skip these checks in order to -improve performance. If you set the PCRE_NO_UTF8_CHECK flag at compile time or -at run time, PCRE assumes that the pattern or subject it is given -(respectively) contains only valid UTF-8 codes. In this case, it does not -diagnose an invalid UTF-8 string. -.P -If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what -happens depends on why the string is invalid. If the string conforms to the -"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters -in the range 0 to 0x7FFFFFFF. In other words, apart from the initial validity -test, PCRE (when in UTF-8 mode) handles strings according to the more liberal -rules of RFC 2279. However, if the string does not even conform to RFC 2279, -the result is undefined. Your program may crash. -.P -If you want to process strings of values in the full range 0 to 0x7FFFFFFF, -encoded in a UTF-8-like manner as per the old RFC, you can set -PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this -situation, you will have to apply your own validity check. -. -. -.SS "General comments about UTF-8 mode" -.rs -.sp -1. An unbraced hexadecimal escape sequence (such as \exb3) matches a two-byte -UTF-8 character if the value is greater than 127. -.P -2. Octal numbers up to \e777 are recognized, and match two-byte UTF-8 -characters for values greater than \e177. -.P -3. Repeat quantifiers apply to complete UTF-8 characters, not to individual -bytes, for example: \ex{100}{3}. -.P -4. The dot metacharacter matches one UTF-8 character instead of a single byte. -.P -5. The escape sequence \eC can be used to match a single byte in UTF-8 mode, -but its use can lead to some strange effects. This facility is not available in -the alternative matching function, \fBpcre_dfa_exec()\fP. -.P -6. The character escapes \eb, \eB, \ed, \eD, \es, \eS, \ew, and \eW correctly -test characters of any code value, but, by default, the characters that PCRE -recognizes as digits, spaces, or word characters remain the same set as before, -all with values less than 256. This remains true even when PCRE is built to -include Unicode property support, because to do otherwise would slow down PCRE -in many common cases. Note in particular that this applies to \eb and \eB, -because they are defined in terms of \ew and \eW. If you really want to test -for a wider sense of, say, "digit", you can use explicit Unicode property tests -such as \ep{Nd}. Alternatively, if you set the PCRE_UCP option, the way that -the character escapes work is changed so that Unicode properties are used to -determine which characters match. There are more details in the section on -.\" HTML -.\" -generic character types -.\" -in the -.\" HREF -\fBpcrepattern\fP -.\" -documentation. -.P -7. Similarly, characters that match the POSIX named character classes are all -low-valued characters, unless the PCRE_UCP option is set. -.P -8. However, the horizontal and vertical whitespace matching escapes (\eh, \eH, -\ev, and \eV) do match all the appropriate Unicode characters, whether or not -PCRE_UCP is set. -.P -9. Case-insensitive matching applies only to characters whose values are less -than 128, unless PCRE is built with Unicode property support. Even when Unicode -property support is available, PCRE still uses its own character tables when -checking the case of low-valued characters, so as not to degrade performance. -The Unicode property information is used only for characters with higher -values. Furthermore, PCRE supports case-insensitive matching only when there is -a one-to-one mapping between a letter's cases. There are a small number of -many-to-one mappings in Unicode; these are not supported by PCRE. +8-bit C library function, listing its arguments and results. . . .SH AUTHOR @@ -304,6 +153,6 @@ .rs .sp .nf -Last updated: 13 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 10 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcre.txt pcre3-8.31/doc/pcre.txt --- pcre3-8.12/doc/pcre.txt 2011-01-15 17:27:46.000000000 +0000 +++ pcre3-8.31/doc/pcre.txt 2012-07-06 09:55:28.000000000 +0000 @@ -25,11 +25,27 @@ items, and there is an option for requesting some minor changes that give better JavaScript compatibility. + Starting with release 8.30, it is possible to compile two separate PCRE + libraries: the original, which supports 8-bit character strings + (including UTF-8 strings), and a second library that supports 16-bit + character strings (including UTF-16 strings). The build process allows + either one or both to be built. The majority of the work to make this + possible was done by Zoltan Herczeg. + + The two libraries contain identical sets of functions, except that the + names in the 16-bit library start with pcre16_ instead of pcre_. To + avoid over-complication and reduce the documentation maintenance load, + most of the documentation describes the 8-bit library, with the differ- + ences for the 16-bit library described separately in the pcre16 page. + References to functions or structures of the form pcre[16]_xxx should + be read as meaning "pcre_xxx when using the 8-bit library and + pcre16_xxx when using the 16-bit library". + The current implementation of PCRE corresponds approximately with Perl - 5.12, including support for UTF-8 encoded strings and Unicode general - category properties. However, UTF-8 and Unicode support has to be - explicitly enabled; it is not the default. The Unicode tables corre- - spond to Unicode release 5.2.0. + 5.12, including support for UTF-8/16 encoded strings and Unicode gen- + eral category properties. However, UTF-8/16 and Unicode support has to + be explicitly enabled; it is not the default. The Unicode tables corre- + spond to Unicode release 6.0.0. In addition to the Perl-compatible matching function, PCRE contains an alternative function that matches the same compiled patterns in a dif- @@ -39,218 +55,401 @@ PCRE is written in C and released as a C library. A number of people have written wrappers and interfaces of various kinds. In particular, - Google Inc. have provided a comprehensive C++ wrapper. This is now - included as part of the PCRE distribution. The pcrecpp page has details - of this interface. Other people's contributions can be found in the - Contrib directory at the primary FTP site, which is: + Google Inc. have provided a comprehensive C++ wrapper for the 8-bit + library. This is now included as part of the PCRE distribution. The + pcrecpp page has details of this interface. Other people's contribu- + tions can be found in the Contrib directory at the primary FTP site, + which is: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre - Details of exactly which Perl regular expression features are and are + Details of exactly which Perl regular expression features are and are not supported by PCRE are given in separate documents. See the pcrepat- - tern and pcrecompat pages. There is a syntax summary in the pcresyntax + tern and pcrecompat pages. There is a syntax summary in the pcresyntax page. - Some features of PCRE can be included, excluded, or changed when the - library is built. The pcre_config() function makes it possible for a - client to discover which features are available. The features them- - selves are described in the pcrebuild page. Documentation about build- - ing PCRE for various operating systems can be found in the README and + Some features of PCRE can be included, excluded, or changed when the + library is built. The pcre_config() function makes it possible for a + client to discover which features are available. The features them- + selves are described in the pcrebuild page. Documentation about build- + ing PCRE for various operating systems can be found in the README and NON-UNIX-USE files in the source distribution. - The library contains a number of undocumented internal functions and - data tables that are used by more than one of the exported external - functions, but which are not intended for use by external callers. - Their names all begin with "_pcre_", which hopefully will not provoke - any name clashes. In some environments, it is possible to control which - external symbols are exported when a shared library is built, and in - these cases the undocumented symbols are not exported. + The libraries contains a number of undocumented internal functions and + data tables that are used by more than one of the exported external + functions, but which are not intended for use by external callers. + Their names all begin with "_pcre_" or "_pcre16_", which hopefully will + not provoke any name clashes. In some environments, it is possible to + control which external symbols are exported when a shared library is + built, and in these cases the undocumented symbols are not exported. USER DOCUMENTATION - The user documentation for PCRE comprises a number of different sec- - tions. In the "man" format, each of these is a separate "man page". In - the HTML format, each is a separate page, linked from the index page. - In the plain text format, all the sections, except the pcredemo sec- + The user documentation for PCRE comprises a number of different sec- + tions. In the "man" format, each of these is a separate "man page". In + the HTML format, each is a separate page, linked from the index page. + In the plain text format, all the sections, except the pcredemo sec- tion, are concatenated, for ease of searching. The sections are as fol- lows: pcre this document + pcre16 details of the 16-bit library pcre-config show PCRE installation configuration information pcreapi details of PCRE's native C API pcrebuild options for building PCRE pcrecallout details of the callout feature pcrecompat discussion of Perl compatibility - pcrecpp details of the C++ wrapper + pcrecpp details of the C++ wrapper for the 8-bit library pcredemo a demonstration C program that uses PCRE - pcregrep description of the pcregrep command + pcregrep description of the pcregrep command (8-bit only) + pcrejit discussion of the just-in-time optimization support + pcrelimits details of size and other limits pcrematching discussion of the two matching algorithms pcrepartial details of the partial matching facility pcrepattern syntax and semantics of supported regular expressions pcreperform discussion of performance issues - pcreposix the POSIX-compatible C API + pcreposix the POSIX-compatible C API for the 8-bit library pcreprecompile details of saving and re-using precompiled patterns pcresample discussion of the pcredemo program pcrestack discussion of stack usage pcresyntax quick syntax reference pcretest description of the pcretest testing command + pcreunicode discussion of Unicode and UTF-8/16 support - In addition, in the "man" and HTML formats, there is a short page for - each C library function, listing its arguments and results. + In addition, in the "man" and HTML formats, there is a short page for + each 8-bit C library function, listing its arguments and results. -LIMITATIONS +AUTHOR - There are some size limitations in PCRE but it is hoped that they will - never in practice be relevant. + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. - The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE - is compiled with the default internal linkage size of 2. If you want to - process regular expressions that are truly enormous, you can compile - PCRE with an internal linkage size of 3 or 4 (see the README file in - the source distribution and the pcrebuild documentation for details). - In these cases the limit is substantially larger. However, the speed - of execution is slower. + Putting an actual email address here seems to have been a spam magnet, + so I've taken it away. If you want to email me, use my two initials, + followed by the two digits 10, at the domain cam.ac.uk. - All values in repeating quantifiers must be less than 65536. - There is no limit to the number of parenthesized subpatterns, but there - can be no more than 65535 capturing subpatterns. +REVISION - The maximum length of name for a named subpattern is 32 characters, and - the maximum number of named subpatterns is 10000. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ - The maximum length of a subject string is the largest positive number - that an integer variable can hold. However, when using the traditional - matching function, PCRE uses recursion to handle subpatterns and indef- - inite repetition. This means that the available stack space may limit - the size of a subject string that can be processed by certain patterns. - For a discussion of stack issues, see the pcrestack documentation. +PCRE(3) PCRE(3) -UTF-8 AND UNICODE PROPERTY SUPPORT - From release 3.3, PCRE has had some support for character strings - encoded in the UTF-8 format. For release 4.0 this was greatly extended - to cover most common requirements, and in release 5.0 additional sup- - port for Unicode general category properties was added. - - In order process UTF-8 strings, you must build PCRE to include UTF-8 - support in the code, and, in addition, you must call pcre_compile() - with the PCRE_UTF8 option flag, or the pattern must start with the - sequence (*UTF8). When either of these is the case, both the pattern - and any subject strings that are matched against it are treated as - UTF-8 strings instead of strings of 1-byte characters. - - If you compile PCRE with UTF-8 support, but do not use it at run time, - the library will be a bit bigger, but the additional run time overhead - is limited to testing the PCRE_UTF8 flag occasionally, so should not be - very big. +NAME + PCRE - Perl-compatible regular expressions - If PCRE is built with Unicode character property support (which implies - UTF-8 support), the escape sequences \p{..}, \P{..}, and \X are sup- - ported. The available properties that can be tested are limited to the - general category properties such as Lu for an upper case letter or Nd - for a decimal number, the Unicode script names such as Arabic or Han, - and the derived properties Any and L&. A full list is given in the - pcrepattern documentation. Only the short names for properties are sup- - ported. For example, \p{L} matches a letter. Its Perl synonym, \p{Let- - ter}, is not supported. Furthermore, in Perl, many properties may - optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE - does not support this. + #include - Validity of UTF-8 strings - When you set the PCRE_UTF8 flag, the strings passed as patterns and - subjects are (by default) checked for validity on entry to the relevant - functions. From release 7.3 of PCRE, the check is according the rules - of RFC 3629, which are themselves derived from the Unicode specifica- - tion. Earlier releases of PCRE followed the rules of RFC 2279, which - allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current - check allows only values in the range U+0 to U+10FFFF, excluding U+D800 - to U+DFFF. - - The excluded code points are the "Low Surrogate Area" of Unicode, of - which the Unicode Standard says this: "The Low Surrogate Area does not - contain any character assignments, consequently no character code - charts or namelists are provided for this area. Surrogates are reserved - for use with UTF-16 and then must be used in pairs." The code points - that are encoded by UTF-16 pairs are available as independent code - points in the UTF-8 encoding. (In other words, the whole surrogate - thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) - - If an invalid UTF-8 string is passed to PCRE, an error return - (PCRE_ERROR_BADUTF8) is given. In some situations, you may already know - that your strings are valid, and therefore want to skip these checks in - order to improve performance. If you set the PCRE_NO_UTF8_CHECK flag at - compile time or at run time, PCRE assumes that the pattern or subject - it is given (respectively) contains only valid UTF-8 codes. In this - case, it does not diagnose an invalid UTF-8 string. +PCRE 16-BIT API BASIC FUNCTIONS - If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, - what happens depends on why the string is invalid. If the string con- - forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a - string of characters in the range 0 to 0x7FFFFFFF. In other words, - apart from the initial validity test, PCRE (when in UTF-8 mode) handles - strings according to the more liberal rules of RFC 2279. However, if - the string does not even conform to RFC 2279, the result is undefined. - Your program may crash. + pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options, + const char **errptr, int *erroffset, + const unsigned char *tableptr); - If you want to process strings of values in the full range 0 to - 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can - set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in - this situation, you will have to apply your own validity check. + pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options, + int *errorcodeptr, + const char **errptr, int *erroffset, + const unsigned char *tableptr); - General comments about UTF-8 mode + pcre16_extra *pcre16_study(const pcre16 *code, int options, + const char **errptr); - 1. An unbraced hexadecimal escape sequence (such as \xb3) matches a - two-byte UTF-8 character if the value is greater than 127. + void pcre16_free_study(pcre16_extra *extra); - 2. Octal numbers up to \777 are recognized, and match two-byte UTF-8 - characters for values greater than \177. + int pcre16_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize); - 3. Repeat quantifiers apply to complete UTF-8 characters, not to indi- - vidual bytes, for example: \x{100}{3}. + int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra, + PCRE_SPTR16 subject, int length, int startoffset, + int options, int *ovector, int ovecsize, + int *workspace, int wscount); - 4. The dot metacharacter matches one UTF-8 character instead of a sin- - gle byte. - 5. The escape sequence \C can be used to match a single byte in UTF-8 - mode, but its use can lead to some strange effects. This facility is - not available in the alternative matching function, pcre_dfa_exec(). +PCRE 16-BIT API STRING EXTRACTION FUNCTIONS - 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly - test characters of any code value, but, by default, the characters that - PCRE recognizes as digits, spaces, or word characters remain the same - set as before, all with values less than 256. This remains true even - when PCRE is built to include Unicode property support, because to do - otherwise would slow down PCRE in many common cases. Note in particular - that this applies to \b and \B, because they are defined in terms of \w - and \W. If you really want to test for a wider sense of, say, "digit", - you can use explicit Unicode property tests such as \p{Nd}. Alterna- - tively, if you set the PCRE_UCP option, the way that the character - escapes work is changed so that Unicode properties are used to deter- - mine which characters match. There are more details in the section on - generic character types in the pcrepattern documentation. + int pcre16_copy_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int buffersize); - 7. Similarly, characters that match the POSIX named character classes - are all low-valued characters, unless the PCRE_UCP option is set. + int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, + int buffersize); - 8. However, the horizontal and vertical whitespace matching escapes - (\h, \H, \v, and \V) do match all the appropriate Unicode characters, - whether or not PCRE_UCP is set. + int pcre16_get_named_substring(const pcre16 *code, + PCRE_SPTR16 subject, int *ovector, + int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr); - 9. Case-insensitive matching applies only to characters whose values - are less than 128, unless PCRE is built with Unicode property support. - Even when Unicode property support is available, PCRE still uses its - own character tables when checking the case of low-valued characters, - so as not to degrade performance. The Unicode property information is - used only for characters with higher values. Furthermore, PCRE supports - case-insensitive matching only when there is a one-to-one mapping - between a letter's cases. There are a small number of many-to-one map- - pings in Unicode; these are not supported by PCRE. + int pcre16_get_stringnumber(const pcre16 *code, + PCRE_SPTR16 name); + + int pcre16_get_stringtable_entries(const pcre16 *code, + PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last); + + int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, + int stringcount, int stringnumber, + PCRE_SPTR16 *stringptr); + + int pcre16_get_substring_list(PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 **listptr); + + void pcre16_free_substring(PCRE_SPTR16 stringptr); + + void pcre16_free_substring_list(PCRE_SPTR16 *stringptr); + + +PCRE 16-BIT API AUXILIARY FUNCTIONS + + pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize); + + void pcre16_jit_stack_free(pcre16_jit_stack *stack); + + void pcre16_assign_jit_stack(pcre16_extra *extra, + pcre16_jit_callback callback, void *data); + + const unsigned char *pcre16_maketables(void); + + int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra, + int what, void *where); + + int pcre16_refcount(pcre16 *code, int adjust); + + int pcre16_config(int what, void *where); + + const char *pcre16_version(void); + + int pcre16_pattern_to_host_byte_order(pcre16 *code, + pcre16_extra *extra, const unsigned char *tables); + + +PCRE 16-BIT API INDIRECTED FUNCTIONS + + void *(*pcre16_malloc)(size_t); + + void (*pcre16_free)(void *); + + void *(*pcre16_stack_malloc)(size_t); + + void (*pcre16_stack_free)(void *); + + int (*pcre16_callout)(pcre16_callout_block *); + + +PCRE 16-BIT API 16-BIT-ONLY FUNCTION + + int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, + PCRE_SPTR16 input, int length, int *byte_order, + int keep_boms); + + +THE PCRE 16-BIT LIBRARY + + Starting with release 8.30, it is possible to compile a PCRE library + that supports 16-bit character strings, including UTF-16 strings, as + well as or instead of the original 8-bit library. The majority of the + work to make this possible was done by Zoltan Herczeg. The two + libraries contain identical sets of functions, used in exactly the same + way. Only the names of the functions and the data types of their argu- + ments and results are different. To avoid over-complication and reduce + the documentation maintenance load, most of the PCRE documentation + describes the 8-bit library, with only occasional references to the + 16-bit library. This page describes what is different when you use the + 16-bit library. + + WARNING: A single application can be linked with both libraries, but + you must take care when processing any particular pattern to use func- + tions from just one library. For example, if you want to study a pat- + tern that was compiled with pcre16_compile(), you must do so with + pcre16_study(), not pcre_study(), and you must free the study data with + pcre16_free_study(). + + +THE HEADER FILE + + There is only one header file, pcre.h. It contains prototypes for all + the functions in both libraries, as well as definitions of flags, + structures, error codes, etc. + + +THE LIBRARY NAME + + In Unix-like systems, the 16-bit library is called libpcre16, and can + normally be accesss by adding -lpcre16 to the command for linking an + application that uses PCRE. + + +STRING TYPES + + In the 8-bit library, strings are passed to PCRE library functions as + vectors of bytes with the C type "char *". In the 16-bit library, + strings are passed as vectors of unsigned 16-bit quantities. The macro + PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is + defined as "const PCRE_UCHAR16 *". In very many environments, "short + int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 + as "short int", but checks that it really is a 16-bit data type. If it + is not, the build fails with an error message telling the maintainer to + modify the definition appropriately. + + +STRUCTURE TYPES + + The types of the opaque structures that are used for compiled 16-bit + patterns and JIT stacks are pcre16 and pcre16_jit_stack respectively. + The type of the user-accessible structure that is returned by + pcre16_study() is pcre16_extra, and the type of the structure that is + used for passing data to a callout function is pcre16_callout_block. + These structures contain the same fields, with the same names, as their + 8-bit counterparts. The only difference is that pointers to character + strings are 16-bit instead of 8-bit types. + + +16-BIT FUNCTIONS + + For every function in the 8-bit library there is a corresponding func- + tion in the 16-bit library with a name that starts with pcre16_ instead + of pcre_. The prototypes are listed above. In addition, there is one + extra function, pcre16_utf16_to_host_byte_order(). This is a utility + function that converts a UTF-16 character string to host byte order if + necessary. The other 16-bit functions expect the strings they are + passed to be in host byte order. + + The input and output arguments of pcre16_utf16_to_host_byte_order() may + point to the same address, that is, conversion in place is supported. + The output buffer must be at least as long as the input. + + The length argument specifies the number of 16-bit data units in the + input string; a negative value specifies a zero-terminated string. + + If byte_order is NULL, it is assumed that the string starts off in host + byte order. This may be changed by byte-order marks (BOMs) anywhere in + the string (commonly as the first character). + + If byte_order is not NULL, a non-zero value of the integer to which it + points means that the input starts off in host byte order, otherwise + the opposite order is assumed. Again, BOMs in the string can change + this. The final byte order is passed back at the end of processing. + + If keep_boms is not zero, byte-order mark characters (0xfeff) are + copied into the output string. Otherwise they are discarded. + + The result of the function is the number of 16-bit units placed into + the output buffer, including the zero terminator if the string was + zero-terminated. + + +SUBJECT STRING OFFSETS + + The offsets within subject strings that are returned by the matching + functions are in 16-bit units rather than bytes. + + +NAMED SUBPATTERNS + + The name-to-number translation table that is maintained for named sub- + patterns uses 16-bit characters. The pcre16_get_stringtable_entries() + function returns the length of each entry in the table as the number of + 16-bit data units. + + +OPTION NAMES + + There are two new general option names, PCRE_UTF16 and + PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and + PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options + define the same bits in the options word. There is a discussion about + the validity of UTF-16 strings in the pcreunicode page. + + For the pcre16_config() function there is an option PCRE_CONFIG_UTF16 + that returns 1 if UTF-16 support is configured, otherwise 0. If this + option is given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is + given to pcre16_config(), the result is the PCRE_ERROR_BADOPTION error. + + +CHARACTER CODES + + In 16-bit mode, when PCRE_UTF16 is not set, character values are + treated in the same way as in 8-bit, non UTF-8 mode, except, of course, + that they can range from 0 to 0xffff instead of 0 to 0xff. Character + types for characters less than 0xff can therefore be influenced by the + locale in the same way as before. Characters greater than 0xff have + only one case, and no "type" (such as letter or digit). + + In UTF-16 mode, the character code is Unicode, in the range 0 to + 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff + because those are "surrogate" values that are used in pairs to encode + values greater than 0xffff. + + A UTF-16 string can indicate its endianness by special code knows as a + byte-order mark (BOM). The PCRE functions do not handle this, expecting + strings to be in host byte order. A utility function called + pcre16_utf16_to_host_byte_order() is provided to help with this (see + above). + + +ERROR NAMES + + The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 corre- + spond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is + given when a compiled pattern is passed to a function that processes + patterns in the other mode, for example, if a pattern compiled with + pcre_compile() is passed to pcre16_exec(). + + There are new error codes whose names begin with PCRE_UTF16_ERR for + invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for + UTF-8 strings that are described in the section entitled "Reason codes + for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors + are: + + PCRE_UTF16_ERR1 Missing low surrogate at end of string + PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate + PCRE_UTF16_ERR3 Isolated low surrogate + PCRE_UTF16_ERR4 Invalid character 0xfffe + + +ERROR TEXTS + + If there is an error while compiling a pattern, the error text that is + passed back by pcre16_compile() or pcre16_compile2() is still an 8-bit + character string, zero-terminated. + + +CALLOUTS + + The subject and mark fields in the callout block that is passed to a + callout function point to 16-bit vectors. + + +TESTING + + The pcretest program continues to operate with 8-bit input and output + files, but it can be used for testing the 16-bit library. If it is run + with the command line option -16, patterns and subject strings are con- + verted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit + library functions are used instead of the 8-bit ones. Returned 16-bit + strings are converted to 8-bit for output. If the 8-bit library was not + compiled, pcretest defaults to 16-bit and the -16 option is ignored. + + When PCRE is being built, the RunTest script that is called by "make + check" uses the pcretest -C option to discover which of the 8-bit and + 16-bit libraries has been built, and runs the tests appropriately. + + +NOT SUPPORTED IN 16-BIT MODE + + Not all the features of the 8-bit library are available with the 16-bit + library. The C++ and POSIX wrapper functions support only the 8-bit + library, and the pcregrep program is at present 8-bit only. AUTHOR @@ -259,15 +458,11 @@ University Computing Service Cambridge CB2 3QH, England. - Putting an actual email address here seems to have been a spam magnet, - so I've taken it away. If you want to email me, use my two initials, - followed by the two digits 10, at the domain cam.ac.uk. - REVISION - Last updated: 13 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 14 April 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -307,46 +502,89 @@ is not described. +BUILDING 8-BIT and 16-BIT LIBRARIES + + By default, a library called libpcre is built, containing functions + that take string arguments contained in vectors of bytes, either as + single-byte characters, or interpreted as UTF-8 strings. You can also + build a separate library, called libpcre16, in which strings are con- + tained in vectors of 16-bit data units and interpreted either as sin- + gle-unit characters or UTF-16 strings, by adding + + --enable-pcre16 + + to the configure command. If you do not want the 8-bit library, add + + --disable-pcre8 + + as well. At least one of the two libraries must be built. Note that the + C++ and POSIX wrappers are for the 8-bit library only, and that pcre- + grep is an 8-bit program. None of these are built if you select only + the 16-bit library. + + +BUILDING SHARED AND STATIC LIBRARIES + + The PCRE building process uses libtool to build both shared and static + Unix libraries by default. You can suppress one of these by adding one + of + + --disable-shared + --disable-static + + to the configure command, as required. + + C++ SUPPORT - By default, the configure script will search for a C++ compiler and C++ - header files. If it finds them, it automatically builds the C++ wrapper - library for PCRE. You can disable this by adding + By default, if the 8-bit library is being built, the configure script + will search for a C++ compiler and C++ header files. If it finds them, + it automatically builds the C++ wrapper library (which supports only + 8-bit strings). You can disable this by adding --disable-cpp to the configure command. -UTF-8 SUPPORT +UTF-8 and UTF-16 SUPPORT - To build PCRE with support for UTF-8 Unicode character strings, add + To build PCRE with support for UTF Unicode character strings, add - --enable-utf8 + --enable-utf - to the configure command. Of itself, this does not make PCRE treat - strings as UTF-8. As well as compiling PCRE with this option, you also - have have to set the PCRE_UTF8 option when you call the pcre_compile() - or pcre_compile2() functions. - - If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE - expects its input to be either ASCII or UTF-8 (depending on the runtime - option). It is not possible to support both EBCDIC and UTF-8 codes in - the same version of the library. Consequently, --enable-utf8 and + to the configure command. This setting applies to both libraries, + adding support for UTF-8 to the 8-bit library and support for UTF-16 to + the 16-bit library. There are no separate options for enabling UTF-8 + and UTF-16 independently because that would allow ridiculous settings + such as requesting UTF-16 support while building only the 8-bit + library. It is not possible to build one library with UTF support and + the other without in the same configuration. (For backwards compatibil- + ity, --enable-utf8 is a synonym of --enable-utf.) + + Of itself, this setting does not make PCRE treat strings as UTF-8 or + UTF-16. As well as compiling PCRE with this option, you also have have + to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pat- + tern compiling functions. + + If you set --enable-utf when compiling in an EBCDIC environment, PCRE + expects its input to be either ASCII or UTF-8 (depending on the run- + time option). It is not possible to support both EBCDIC and UTF-8 codes + in the same version of the library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive. UNICODE CHARACTER PROPERTY SUPPORT - UTF-8 support allows PCRE to process character values greater than 255 - in the strings that it handles. On its own, however, it does not pro- - vide any facilities for accessing the properties of such characters. If - you want to be able to use the pattern escapes \P, \p, and \X, which - refer to Unicode character properties, you must add + UTF support allows the libraries to process character codepoints up to + 0x10ffff in the strings that they handle. On its own, however, it does + not provide any facilities for accessing the properties of such charac- + ters. If you want to be able to use the pattern escapes \P, \p, and \X, + which refer to Unicode character properties, you must add --enable-unicode-properties - to the configure command. This implies UTF-8 support, even if you have + to the configure command. This implies UTF support, even if you have not explicitly requested it. Including Unicode property support adds around 30K of tables to the @@ -354,6 +592,23 @@ are supported. Details are given in the pcrepattern documentation. +JUST-IN-TIME COMPILER SUPPORT + + Just-in-time compiler support is included in the build by specifying + + --enable-jit + + This support is available only for certain hardware architectures. If + this option is set for an unsupported architecture, a compile time + error occurs. See the pcrejit documentation for a discussion of JIT + usage. When JIT support is enabled, pcregrep automatically makes use of + it, unless you add + + --disable-pcregrep-jit + + to the "configure" command. + + CODE VALUE OF NEWLINE By default, PCRE interprets the linefeed (LF) character as indicating @@ -400,28 +655,16 @@ functions are called. -BUILDING SHARED AND STATIC LIBRARIES - - The PCRE building process uses libtool to build both shared and static - Unix libraries by default. You can suppress one of these by adding one - of - - --disable-shared - --disable-static - - to the configure command, as required. - - POSIX MALLOC USAGE - When PCRE is called through the POSIX interface (see the pcreposix doc- - umentation), additional working storage is required for holding the - pointers to capturing substrings, because PCRE requires three integers - per substring, whereas the POSIX interface provides only two. If the - number of expected substrings is small, the wrapper function uses space - on the stack, because this is faster than using malloc() for each call. - The default threshold above which the stack is no longer used is 10; it - can be changed by adding a setting such as + When the 8-bit library is called through the POSIX interface (see the + pcreposix documentation), additional working storage is required for + holding the pointers to capturing substrings, because PCRE requires + three integers per substring, whereas the POSIX interface provides only + two. If the number of expected substrings is small, the wrapper func- + tion uses space on the stack, because this is faster than using mal- + loc() for each call. The default threshold above which the stack is no + longer used is 10; it can be changed by adding a setting such as --with-posix-malloc-threshold=20 @@ -435,107 +678,108 @@ nation metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. - Nevertheless, some people do want to process truyl enormous patterns, + Nevertheless, some people do want to process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte off- sets by adding a setting such as --with-link-size=3 - to the configure command. The value given must be 2, 3, or 4. Using - longer offsets slows down the operation of PCRE because it has to load - additional bytes when handling them. + to the configure command. The value given must be 2, 3, or 4. For the + 16-bit library, a value of 3 is rounded up to 4. Using longer offsets + slows down the operation of PCRE because it has to load additional data + when handling them. AVOIDING EXCESSIVE STACK USAGE When matching with the pcre_exec() function, PCRE implements backtrack- - ing by making recursive calls to an internal function called match(). - In environments where the size of the stack is limited, this can se- - verely limit PCRE's operation. (The Unix environment does not usually + ing by making recursive calls to an internal function called match(). + In environments where the size of the stack is limited, this can se- + verely limit PCRE's operation. (The Unix environment does not usually suffer from this problem, but it may sometimes be necessary to increase - the maximum stack size. There is a discussion in the pcrestack docu- - mentation.) An alternative approach to recursion that uses memory from - the heap to remember data, instead of using recursive function calls, - has been implemented to work round the problem of limited stack size. + the maximum stack size. There is a discussion in the pcrestack docu- + mentation.) An alternative approach to recursion that uses memory from + the heap to remember data, instead of using recursive function calls, + has been implemented to work round the problem of limited stack size. If you want to build a version of PCRE that works this way, add --disable-stack-for-recursion - to the configure command. With this configuration, PCRE will use the - pcre_stack_malloc and pcre_stack_free variables to call memory manage- - ment functions. By default these point to malloc() and free(), but you + to the configure command. With this configuration, PCRE will use the + pcre_stack_malloc and pcre_stack_free variables to call memory manage- + ment functions. By default these point to malloc() and free(), but you can replace the pointers so that your own functions are used instead. - Separate functions are provided rather than using pcre_malloc and - pcre_free because the usage is very predictable: the block sizes - requested are always the same, and the blocks are always freed in - reverse order. A calling program might be able to implement optimized - functions that perform better than malloc() and free(). PCRE runs + Separate functions are provided rather than using pcre_malloc and + pcre_free because the usage is very predictable: the block sizes + requested are always the same, and the blocks are always freed in + reverse order. A calling program might be able to implement optimized + functions that perform better than malloc() and free(). PCRE runs noticeably more slowly when built in this way. This option affects only the pcre_exec() function; it is not relevant for pcre_dfa_exec(). LIMITING PCRE RESOURCE USAGE - Internally, PCRE has a function called match(), which it calls repeat- - edly (sometimes recursively) when matching a pattern with the - pcre_exec() function. By controlling the maximum number of times this - function may be called during a single matching operation, a limit can - be placed on the resources used by a single call to pcre_exec(). The - limit can be changed at run time, as described in the pcreapi documen- - tation. The default is 10 million, but this can be changed by adding a + Internally, PCRE has a function called match(), which it calls repeat- + edly (sometimes recursively) when matching a pattern with the + pcre_exec() function. By controlling the maximum number of times this + function may be called during a single matching operation, a limit can + be placed on the resources used by a single call to pcre_exec(). The + limit can be changed at run time, as described in the pcreapi documen- + tation. The default is 10 million, but this can be changed by adding a setting such as --with-match-limit=500000 - to the configure command. This setting has no effect on the + to the configure command. This setting has no effect on the pcre_dfa_exec() matching function. - In some environments it is desirable to limit the depth of recursive + In some environments it is desirable to limit the depth of recursive calls of match() more strictly than the total number of calls, in order - to restrict the maximum amount of stack (or heap, if --disable-stack- + to restrict the maximum amount of stack (or heap, if --disable-stack- for-recursion is specified) that is used. A second limit controls this; - it defaults to the value that is set for --with-match-limit, which - imposes no additional constraints. However, you can set a lower limit + it defaults to the value that is set for --with-match-limit, which + imposes no additional constraints. However, you can set a lower limit by adding, for example, --with-match-limit-recursion=10000 - to the configure command. This value can also be overridden at run + to the configure command. This value can also be overridden at run time. CREATING CHARACTER TABLES AT BUILD TIME - PCRE uses fixed tables for processing characters whose code values are - less than 256. By default, PCRE is built with a set of tables that are - distributed in the file pcre_chartables.c.dist. These tables are for + PCRE uses fixed tables for processing characters whose code values are + less than 256. By default, PCRE is built with a set of tables that are + distributed in the file pcre_chartables.c.dist. These tables are for ASCII codes only. If you add --enable-rebuild-chartables - to the configure command, the distributed tables are no longer used. - Instead, a program called dftables is compiled and run. This outputs + to the configure command, the distributed tables are no longer used. + Instead, a program called dftables is compiled and run. This outputs the source for new set of tables, created in the default locale of your - C runtime system. (This method of replacing the tables does not work if - you are cross compiling, because dftables is run on the local host. If - you need to create alternative tables when cross compiling, you will + C run-time system. (This method of replacing the tables does not work + if you are cross compiling, because dftables is run on the local host. + If you need to create alternative tables when cross compiling, you will have to do so "by hand".) USING EBCDIC CODE - PCRE assumes by default that it will run in an environment where the - character code is ASCII (or Unicode, which is a superset of ASCII). - This is the case for most computer operating systems. PCRE can, how- + PCRE assumes by default that it will run in an environment where the + character code is ASCII (or Unicode, which is a superset of ASCII). + This is the case for most computer operating systems. PCRE can, how- ever, be compiled to run in an EBCDIC environment by adding --enable-ebcdic to the configure command. This setting implies --enable-rebuild-charta- - bles. You should only use it if you know that you are in an EBCDIC - environment (for example, an IBM mainframe operating system). The - --enable-ebcdic option is incompatible with --enable-utf8. + bles. You should only use it if you know that you are in an EBCDIC + environment (for example, an IBM mainframe operating system). The + --enable-ebcdic option is incompatible with --enable-utf. PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT @@ -548,10 +792,26 @@ --enable-pcregrep-libbz2 to the configure command. These options naturally require that the rel- - evant libraries are installed on your system. Configuration will fail + evant libraries are installed on your system. Configuration will fail if they are not. +PCREGREP BUFFER SIZE + + pcregrep uses an internal buffer to hold a "window" on the file it is + scanning, in order to be able to output "before" and "after" lines when + it finds a match. The size of the buffer is controlled by a parameter + whose default value is 20K. The buffer itself is three times this size, + but because of the way it is used for holding "before" lines, the long- + est line that is guaranteed to be processable is the parameter size. + You can change the default parameter value by adding, for example, + + --with-pcregrep-bufsize=50K + + to the configure command. The caller of pcregrep can, however, override + this value by specifying a run-time option. + + PCRETEST OPTION FOR LIBREADLINE SUPPORT If you add @@ -585,7 +845,7 @@ SEE ALSO - pcreapi(3), pcre_config(3). + pcreapi(3), pcre16, pcre_config(3). AUTHOR @@ -597,8 +857,8 @@ REVISION - Last updated: 29 September 2009 - Copyright (c) 1997-2009 University of Cambridge. + Last updated: 07 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -614,13 +874,15 @@ This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given sub- ject string. The "standard" algorithm is the one provided by the - pcre_exec() function. This works in the same was as Perl's matching - function, and provides a Perl-compatible matching operation. - - An alternative algorithm is provided by the pcre_dfa_exec() function; - this operates in a different way, and is not Perl-compatible. It has - advantages and disadvantages compared with the standard algorithm, and - these are described below. + pcre_exec() and pcre16_exec() functions. These work in the same was as + Perl's matching function, and provide a Perl-compatible matching opera- + tion. The just-in-time (JIT) optimization that is described in the + pcrejit documentation is compatible with these functions. + + An alternative algorithm is provided by the pcre_dfa_exec() and + pcre16_dfa_exec() functions; they operate in a different way, and are + not Perl-compatible. This alternative has advantages and disadvantages + compared with the standard algorithm, and these are described below. When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference @@ -748,42 +1010,43 @@ 6. Callouts are supported, but the value of the capture_top field is always 1, and the value of the capture_last field is always -1. - 7. The \C escape sequence, which (in the standard algorithm) matches a - single byte, even in UTF-8 mode, is not supported because the alterna- - tive algorithm moves through the subject string one character at a - time, for all active paths through the tree. + 7. The \C escape sequence, which (in the standard algorithm) always + matches a single data unit, even in UTF-8 or UTF-16 modes, is not sup- + ported in these modes, because the alternative algorithm moves through + the subject string one character (not data unit) at a time, for all + active paths through the tree. - 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) - are not supported. (*FAIL) is supported, and behaves like a failing + 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) + are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. ADVANTAGES OF THE ALTERNATIVE ALGORITHM - Using the alternative matching algorithm provides the following advan- + Using the alternative matching algorithm provides the following advan- tages: 1. All possible matches (at a single point in the subject) are automat- - ically found, and in particular, the longest match is found. To find + ically found, and in particular, the longest match is found. To find more than one match using the standard algorithm, you have to do kludgy things with callouts. - 2. Because the alternative algorithm scans the subject string just - once, and never needs to backtrack, it is possible to pass very long - subject strings to the matching function in several pieces, checking - for partial matching each time. Although it is possible to do multi- - segment matching using the standard algorithm (pcre_exec()), by retain- - ing partially matched substrings, it is more complicated. The pcrepar- - tial documentation gives details of partial matching and discusses - multi-segment matching. + 2. Because the alternative algorithm scans the subject string just + once, and never needs to backtrack (except for lookbehinds), it is pos- + sible to pass very long subject strings to the matching function in + several pieces, checking for partial matching each time. Although it is + possible to do multi-segment matching using the standard algorithm by + retaining partially matched substrings, it is more complicated. The + pcrepartial documentation gives details of partial matching and dis- + cusses multi-segment matching. DISADVANTAGES OF THE ALTERNATIVE ALGORITHM The alternative algorithm suffers from a number of disadvantages: - 1. It is substantially slower than the standard algorithm. This is - partly because it has to search for all possible matches, but is also + 1. It is substantially slower than the standard algorithm. This is + partly because it has to search for all possible matches, but is also because it is less susceptible to optimization. 2. Capturing parentheses and back references are not supported. @@ -801,8 +1064,8 @@ REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 08 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -812,10 +1075,10 @@ NAME PCRE - Perl-compatible regular expressions + #include -PCRE NATIVE API - #include +PCRE NATIVE API BASIC FUNCTIONS pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, @@ -829,6 +1092,8 @@ pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); + void pcre_free_study(pcre_extra *extra); + int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); @@ -838,6 +1103,9 @@ int options, int *ovector, int ovecsize, int *workspace, int wscount); + +PCRE NATIVE API STRING EXTRACTION FUNCTIONS + int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, @@ -869,18 +1137,32 @@ void pcre_free_substring_list(const char **stringptr); + +PCRE NATIVE API AUXILIARY FUNCTIONS + + pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize); + + void pcre_jit_stack_free(pcre_jit_stack *stack); + + void pcre_assign_jit_stack(pcre_extra *extra, + pcre_jit_callback callback, void *data); + const unsigned char *pcre_maketables(void); int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); - int pcre_info(const pcre *code, int *optptr, int *firstcharptr); - int pcre_refcount(pcre *code, int adjust); int pcre_config(int what, void *where); - char *pcre_version(void); + const char *pcre_version(void); + + int pcre_pattern_to_host_byte_order(pcre *code, + pcre_extra *extra, const unsigned char *tables); + + +PCRE NATIVE API INDIRECTED FUNCTIONS void *(*pcre_malloc)(size_t); @@ -893,46 +1175,80 @@ int (*pcre_callout)(pcre_callout_block *); +PCRE 8-BIT AND 16-BIT LIBRARIES + + From release 8.30, PCRE can be compiled as a library for handling + 16-bit character strings as well as, or instead of, the original + library that handles 8-bit character strings. To avoid too much compli- + cation, this document describes the 8-bit versions of the functions, + with only occasional references to the 16-bit library. + + The 16-bit functions operate in the same way as their 8-bit counter- + parts; they just use different data types for their arguments and + results, and their names start with pcre16_ instead of pcre_. For every + option that has UTF8 in its name (for example, PCRE_UTF8), there is a + corresponding 16-bit name with UTF8 replaced by UTF16. This facility is + in fact just cosmetic; the 16-bit option names define the same bit val- + ues. + + References to bytes and UTF-8 in this document should be read as refer- + ences to 16-bit data quantities and UTF-16 when using the 16-bit + library, unless specified otherwise. More details of the specific dif- + ferences for the 16-bit library are given in the pcre16 page. + + PCRE API OVERVIEW PCRE has its own native API, which is described in this document. There - are also some wrapper functions that correspond to the POSIX regular - expression API. These are described in the pcreposix documentation. - Both of these APIs define a set of C function calls. A C++ wrapper is - distributed with PCRE. It is documented in the pcrecpp page. - - The native API C function prototypes are defined in the header file - pcre.h, and on Unix systems the library itself is called libpcre. It - can normally be accessed by adding -lpcre to the command for linking an - application that uses PCRE. The header file defines the macros - PCRE_MAJOR and PCRE_MINOR to contain the major and minor release num- - bers for the library. Applications can use these to include support + are also some wrapper functions (for the 8-bit library only) that cor- + respond to the POSIX regular expression API, but they do not give + access to all the functionality. They are described in the pcreposix + documentation. Both of these APIs define a set of C function calls. A + C++ wrapper (again for the 8-bit library only) is also distributed with + PCRE. It is documented in the pcrecpp page. + + The native API C function prototypes are defined in the header file + pcre.h, and on Unix-like systems the (8-bit) library itself is called + libpcre. It can normally be accessed by adding -lpcre to the command + for linking an application that uses PCRE. The header file defines the + macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release + numbers for the library. Applications can use these to include support for different releases of PCRE. In a Windows environment, if you want to statically link an application - program against a non-dll pcre.a file, you must define PCRE_STATIC - before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- + program against a non-dll pcre.a file, you must define PCRE_STATIC + before including pcre.h or pcrecpp.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. - The functions pcre_compile(), pcre_compile2(), pcre_study(), and - pcre_exec() are used for compiling and matching regular expressions in - a Perl-compatible manner. A sample program that demonstrates the sim- - plest way of using them is provided in the file called pcredemo.c in + The functions pcre_compile(), pcre_compile2(), pcre_study(), and + pcre_exec() are used for compiling and matching regular expressions in + a Perl-compatible manner. A sample program that demonstrates the sim- + plest way of using them is provided in the file called pcredemo.c in the PCRE source distribution. A listing of this program is given in the - pcredemo documentation, and the pcresample documentation describes how + pcredemo documentation, and the pcresample documentation describes how to compile and run it. + Just-in-time compiler support is an optional feature of PCRE that can + be built in appropriate hardware environments. It greatly speeds up the + matching performance of many patterns. Simple programs can easily + request that it be used if available, by setting an option that is + ignored when it is not relevant. More complicated programs might need + to make use of the functions pcre_jit_stack_alloc(), + pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control + the JIT code's memory usage. These functions are discussed in the + pcrejit documentation. + A second matching function, pcre_dfa_exec(), which is not Perl-compati- - ble, is also provided. This uses a different algorithm for the match- - ing. The alternative algorithm finds all possible matches (at a given - point in the subject), and scans the subject just once (unless there - are lookbehind assertions). However, this algorithm does not return - captured substrings. A description of the two matching algorithms and - their advantages and disadvantages is given in the pcrematching docu- + ble, is also provided. This uses a different algorithm for the match- + ing. The alternative algorithm finds all possible matches (at a given + point in the subject), and scans the subject just once (unless there + are lookbehind assertions). However, this algorithm does not return + captured substrings. A description of the two matching algorithms and + their advantages and disadvantages is given in the pcrematching docu- mentation. - In addition to the main compiling and matching functions, there are + In addition to the main compiling and matching functions, there are convenience functions for extracting captured substrings from a subject string that is matched by pcre_exec(). They are: @@ -947,103 +1263,106 @@ pcre_free_substring() and pcre_free_substring_list() are also provided, to free the memory used for extracted strings. - The function pcre_maketables() is used to build a set of character - tables in the current locale for passing to pcre_compile(), - pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is - provided for specialist use. Most commonly, no special tables are - passed, in which case internal tables that are generated when PCRE is + The function pcre_maketables() is used to build a set of character + tables in the current locale for passing to pcre_compile(), + pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is + provided for specialist use. Most commonly, no special tables are + passed, in which case internal tables that are generated when PCRE is built are used. - The function pcre_fullinfo() is used to find out information about a - compiled pattern; pcre_info() is an obsolete version that returns only - some of the available information, but is retained for backwards com- - patibility. The function pcre_version() returns a pointer to a string - containing the version of PCRE and its date of release. + The function pcre_fullinfo() is used to find out information about a + compiled pattern. The function pcre_version() returns a pointer to a + string containing the version of PCRE and its date of release. - The function pcre_refcount() maintains a reference count in a data - block containing a compiled pattern. This is provided for the benefit + The function pcre_refcount() maintains a reference count in a data + block containing a compiled pattern. This is provided for the benefit of object-oriented applications. - The global variables pcre_malloc and pcre_free initially contain the - entry points of the standard malloc() and free() functions, respec- + The global variables pcre_malloc and pcre_free initially contain the + entry points of the standard malloc() and free() functions, respec- tively. PCRE calls the memory management functions via these variables, - so a calling program can replace them if it wishes to intercept the + so a calling program can replace them if it wishes to intercept the calls. This should be done before calling any PCRE functions. - The global variables pcre_stack_malloc and pcre_stack_free are also - indirections to memory management functions. These special functions - are used only when PCRE is compiled to use the heap for remembering + The global variables pcre_stack_malloc and pcre_stack_free are also + indirections to memory management functions. These special functions + are used only when PCRE is compiled to use the heap for remembering data, instead of recursive function calls, when running the pcre_exec() - function. See the pcrebuild documentation for details of how to do - this. It is a non-standard way of building PCRE, for use in environ- - ments that have limited stacks. Because of the greater use of memory - management, it runs more slowly. Separate functions are provided so - that special-purpose external code can be used for this case. When - used, these functions are always called in a stack-like manner (last - obtained, first freed), and always for memory blocks of the same size. - There is a discussion about PCRE's stack usage in the pcrestack docu- + function. See the pcrebuild documentation for details of how to do + this. It is a non-standard way of building PCRE, for use in environ- + ments that have limited stacks. Because of the greater use of memory + management, it runs more slowly. Separate functions are provided so + that special-purpose external code can be used for this case. When + used, these functions are always called in a stack-like manner (last + obtained, first freed), and always for memory blocks of the same size. + There is a discussion about PCRE's stack usage in the pcrestack docu- mentation. The global variable pcre_callout initially contains NULL. It can be set - by the caller to a "callout" function, which PCRE will then call at - specified points during a matching operation. Details are given in the + by the caller to a "callout" function, which PCRE will then call at + specified points during a matching operation. Details are given in the pcrecallout documentation. NEWLINES - PCRE supports five different conventions for indicating line breaks in - strings: a single CR (carriage return) character, a single LF (line- + PCRE supports five different conventions for indicating line breaks in + strings: a single CR (carriage return) character, a single LF (line- feed) character, the two-character sequence CRLF, any of the three pre- - ceding, or any Unicode newline sequence. The Unicode newline sequences - are the three just mentioned, plus the single characters VT (vertical - tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line + ceding, or any Unicode newline sequence. The Unicode newline sequences + are the three just mentioned, plus the single characters VT (vertical + tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). - Each of the first three conventions is used by at least one operating - system as its standard newline sequence. When PCRE is built, a default - can be specified. The default default is LF, which is the Unix stan- - dard. When PCRE is run, the default can be overridden, either when a + Each of the first three conventions is used by at least one operating + system as its standard newline sequence. When PCRE is built, a default + can be specified. The default default is LF, which is the Unix stan- + dard. When PCRE is run, the default can be overridden, either when a pattern is compiled, or when it is matched. At compile time, the newline convention can be specified by the options - argument of pcre_compile(), or it can be specified by special text at + argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences. In the PCRE documentation the word "newline" is used to mean "the char- - acter or pair of characters that indicate a line break". The choice of - newline convention affects the handling of the dot, circumflex, and + acter or pair of characters that indicate a line break". The choice of + newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when - CRLF is a recognized line ending sequence, the match position advance- + CRLF is a recognized line ending sequence, the match position advance- ment for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below. - The choice of newline convention does not affect the interpretation of - the \n or \r escape sequences, nor does it affect what \R matches, + The choice of newline convention does not affect the interpretation of + the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options. MULTITHREADING - The PCRE functions can be used in multi-threading applications, with + The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the callout function pointed to by pcre_callout, are shared by all threads. - The compiled form of a regular expression is not altered during match- + The compiled form of a regular expression is not altered during match- ing, so the same compiled pattern can safely be used by several threads at once. + If the just-in-time optimization feature is being used, it needs sepa- + rate memory stack areas for each thread. See the pcrejit documentation + for more details. + SAVING PRECOMPILED PATTERNS FOR LATER USE The compiled form of a regular expression can be saved and re-used at a - later time, possibly by a different program, and even on a host other - than the one on which it was compiled. Details are given in the - pcreprecompile documentation. However, compiling a regular expression - with one version of PCRE for use with a different version is not guar- - anteed to work and may cause crashes. + later time, possibly by a different program, and even on a host other + than the one on which it was compiled. Details are given in the + pcreprecompile documentation, which includes a description of the + pcre_pattern_to_host_byte_order() function. However, compiling a regu- + lar expression with one version of PCRE for use with a different ver- + sion is not guaranteed to work and may cause crashes. CHECKING BUILD-TIME OPTIONS @@ -1057,72 +1376,99 @@ The first argument for pcre_config() is an integer, specifying which information is required; the second argument is a pointer to a variable - into which the information is placed. The following information is + into which the information is placed. The returned value is zero on + success, or the negative error code PCRE_ERROR_BADOPTION if the value + in the first argument is not recognized. The following information is available: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is avail- - able; otherwise it is set to zero. + able; otherwise it is set to zero. If this option is given to the + 16-bit version of this function, pcre16_config(), the result is + PCRE_ERROR_BADOPTION. + + PCRE_CONFIG_UTF16 + + The output is an integer that is set to one if UTF-16 support is avail- + able; otherwise it is set to zero. This value should normally be given + to the 16-bit version of this function, pcre16_config(). If it is given + to the 8-bit version of this function, the result is PCRE_ERROR_BADOP- + TION. PCRE_CONFIG_UNICODE_PROPERTIES The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero. + PCRE_CONFIG_JIT + + The output is an integer that is set to one if support for just-in-time + compiling is available; otherwise it is set to zero. + + PCRE_CONFIG_JITTARGET + + The output is a pointer to a zero-terminated "const char *" string. If + JIT support is available, the string contains the name of the architec- + ture for which the JIT compiler is configured, for example "x86 32bit + (little endian + unaligned)". If JIT support is not available, the + result is NULL. + PCRE_CONFIG_NEWLINE - The output is an integer whose value specifies the default character - sequence that is recognized as meaning "newline". The four values that + The output is an integer whose value specifies the default character + sequence that is recognized as meaning "newline". The four values that are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF, - and -1 for ANY. Though they are derived from ASCII, the same values + and -1 for ANY. Though they are derived from ASCII, the same values are returned in EBCDIC environments. The default should normally corre- spond to the standard sequence for your operating system. PCRE_CONFIG_BSR The output is an integer whose value indicates what character sequences - the \R escape sequence matches by default. A value of 0 means that \R - matches any Unicode line ending sequence; a value of 1 means that \R + the \R escape sequence matches by default. A value of 0 means that \R + matches any Unicode line ending sequence; a value of 1 means that \R matches only CR, LF, or CRLF. The default can be overridden when a pat- tern is compiled or matched. PCRE_CONFIG_LINK_SIZE - The output is an integer that contains the number of bytes used for - internal linkage in compiled regular expressions. The value is 2, 3, or - 4. Larger values allow larger regular expressions to be compiled, at - the expense of slower matching. The default value of 2 is sufficient - for all but the most massive patterns, since it allows the compiled - pattern to be up to 64K in size. + The output is an integer that contains the number of bytes used for + internal linkage in compiled regular expressions. For the 8-bit + library, the value can be 2, 3, or 4. For the 16-bit library, the value + is either 2 or 4 and is still a number of bytes. The default value of 2 + is sufficient for all but the most massive patterns, since it allows + the compiled pattern to be up to 64K in size. Larger values allow + larger regular expressions to be compiled, at the expense of slower + matching. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD - The output is an integer that contains the threshold above which the - POSIX interface uses malloc() for output vectors. Further details are + The output is an integer that contains the threshold above which the + POSIX interface uses malloc() for output vectors. Further details are given in the pcreposix documentation. PCRE_CONFIG_MATCH_LIMIT - The output is a long integer that gives the default limit for the num- - ber of internal matching function calls in a pcre_exec() execution. + The output is a long integer that gives the default limit for the num- + ber of internal matching function calls in a pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_MATCH_LIMIT_RECURSION The output is a long integer that gives the default limit for the depth - of recursion when calling the internal matching function in a - pcre_exec() execution. Further details are given with pcre_exec() + of recursion when calling the internal matching function in a + pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_STACKRECURSE - The output is an integer that is set to one if internal recursion when + The output is an integer that is set to one if internal recursion when running pcre_exec() is implemented by recursive function calls that use - the stack to remember their state. This is the usual way that PCRE is + the stack to remember their state. This is the usual way that PCRE is compiled. The output is zero if PCRE was compiled to use blocks of data - on the heap instead of recursive function calls. In this case, - pcre_stack_malloc and pcre_stack_free are called to manage memory + on the heap instead of recursive function calls. In this case, + pcre_stack_malloc and pcre_stack_free are called to manage memory blocks on the heap, thus avoiding the use of the stack. @@ -1139,65 +1485,65 @@ Either of the functions pcre_compile() or pcre_compile2() can be called to compile a pattern into an internal form. The only difference between - the two interfaces is that pcre_compile2() has an additional argument, - errorcodeptr, via which a numerical error code can be returned. To - avoid too much repetition, we refer just to pcre_compile() below, but + the two interfaces is that pcre_compile2() has an additional argument, + errorcodeptr, via which a numerical error code can be returned. To + avoid too much repetition, we refer just to pcre_compile() below, but the information applies equally to pcre_compile2(). The pattern is a C string terminated by a binary zero, and is passed in - the pattern argument. A pointer to a single block of memory that is - obtained via pcre_malloc is returned. This contains the compiled code + the pattern argument. A pointer to a single block of memory that is + obtained via pcre_malloc is returned. This contains the compiled code and related data. The pcre type is defined for the returned block; this is a typedef for a structure whose contents are not externally defined. It is up to the caller to free the memory (via pcre_free) when it is no longer required. - Although the compiled code of a PCRE regex is relocatable, that is, it + Although the compiled code of a PCRE regex is relocatable, that is, it does not depend on memory location, the complete pcre data block is not - fully relocatable, because it may contain a copy of the tableptr argu- + fully relocatable, because it may contain a copy of the tableptr argu- ment, which is an address (see below). The options argument contains various bit settings that affect the com- - pilation. It should be zero if no options are required. The available - options are described below. Some of them (in particular, those that - are compatible with Perl, but some others as well) can also be set and - unset from within the pattern (see the detailed description in the - pcrepattern documentation). For those options that can be different in - different parts of the pattern, the contents of the options argument + pilation. It should be zero if no options are required. The available + options are described below. Some of them (in particular, those that + are compatible with Perl, but some others as well) can also be set and + unset from within the pattern (see the detailed description in the + pcrepattern documentation). For those options that can be different in + different parts of the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The - PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and - PCRE_NO_START_OPT options can be set at the time of matching as well as - at compile time. + PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and + PCRE_NO_START_OPTIMIZE options can be set at the time of matching as + well as at compile time. If errptr is NULL, pcre_compile() returns NULL immediately. Otherwise, - if compilation of a pattern fails, pcre_compile() returns NULL, and + if compilation of a pattern fails, pcre_compile() returns NULL, and sets the variable pointed to by errptr to point to a textual error mes- sage. This is a static string that is part of the library. You must not - try to free it. The offset from the start of the pattern to the byte - that was being processed when the error was discovered is placed in the - variable pointed to by erroffset, which must not be NULL. If it is, an - immediate error is given. Some errors are not detected until checks are - carried out when the whole pattern has been scanned; in this case the - offset is set to the end of the pattern. + try to free it. Normally, the offset from the start of the pattern to + the byte that was being processed when the error was discovered is + placed in the variable pointed to by erroffset, which must not be NULL + (if it is, an immediate error is given). However, for an invalid UTF-8 + string, the offset is that of the first byte of the failing character. + Some errors are not detected until the whole pattern has been scanned; + in these cases, the offset passed back is the length of the pattern. Note that the offset is in bytes, not characters, even in UTF-8 mode. - It may point into the middle of a UTF-8 character (for example, when - PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string). + It may sometimes point into the middle of a UTF-8 character. - If pcre_compile2() is used instead of pcre_compile(), and the error- - codeptr argument is not NULL, a non-zero error code number is returned - via this argument in the event of an error. This is in addition to the + If pcre_compile2() is used instead of pcre_compile(), and the error- + codeptr argument is not NULL, a non-zero error code number is returned + via this argument in the event of an error. This is in addition to the textual error message. Error codes and messages are listed below. - If the final argument, tableptr, is NULL, PCRE uses a default set of - character tables that are built when PCRE is compiled, using the - default C locale. Otherwise, tableptr must be an address that is the - result of a call to pcre_maketables(). This value is stored with the - compiled pattern, and used again by pcre_exec(), unless another table + If the final argument, tableptr, is NULL, PCRE uses a default set of + character tables that are built when PCRE is compiled, using the + default C locale. Otherwise, tableptr must be an address that is the + result of a call to pcre_maketables(). This value is stored with the + compiled pattern, and used again by pcre_exec(), unless another table pointer is passed to it. For more discussion, see the section on locale support below. - This code fragment shows a typical straightforward call to pcre_com- + This code fragment shows a typical straightforward call to pcre_com- pile(): pcre *re; @@ -1210,147 +1556,161 @@ &erroffset, /* for error offset */ NULL); /* use default character tables */ - The following names for option bits are defined in the pcre.h header + The following names for option bits are defined in the pcre.h header file: PCRE_ANCHORED If this bit is set, the pattern is forced to be "anchored", that is, it - is constrained to match only at the first matching point in the string - that is being searched (the "subject string"). This effect can also be - achieved by appropriate constructs in the pattern itself, which is the + is constrained to match only at the first matching point in the string + that is being searched (the "subject string"). This effect can also be + achieved by appropriate constructs in the pattern itself, which is the only way to do it in Perl. PCRE_AUTO_CALLOUT If this bit is set, pcre_compile() automatically inserts callout items, - all with number 255, before each pattern item. For discussion of the + all with number 255, before each pattern item. For discussion of the callout facility, see the pcrecallout documentation. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape - sequence matches. The choice is either to match only CR, LF, or CRLF, + sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by set- ting an option when a compiled pattern is matched. PCRE_CASELESS - If this bit is set, letters in the pattern match both upper and lower - case letters. It is equivalent to Perl's /i option, and it can be - changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE - always understands the concept of case for characters whose values are - less than 128, so caseless matching is always possible. For characters - with higher values, the concept of case is supported if PCRE is com- - piled with Unicode property support, but not otherwise. If you want to - use caseless matching for characters 128 and above, you must ensure - that PCRE is compiled with Unicode property support as well as with + If this bit is set, letters in the pattern match both upper and lower + case letters. It is equivalent to Perl's /i option, and it can be + changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE + always understands the concept of case for characters whose values are + less than 128, so caseless matching is always possible. For characters + with higher values, the concept of case is supported if PCRE is com- + piled with Unicode property support, but not otherwise. If you want to + use caseless matching for characters 128 and above, you must ensure + that PCRE is compiled with Unicode property support as well as with UTF-8 support. PCRE_DOLLAR_ENDONLY - If this bit is set, a dollar metacharacter in the pattern matches only - at the end of the subject string. Without this option, a dollar also - matches immediately before a newline at the end of the string (but not - before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored - if PCRE_MULTILINE is set. There is no equivalent to this option in + If this bit is set, a dollar metacharacter in the pattern matches only + at the end of the subject string. Without this option, a dollar also + matches immediately before a newline at the end of the string (but not + before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored + if PCRE_MULTILINE is set. There is no equivalent to this option in Perl, and no way to set it within a pattern. PCRE_DOTALL - If this bit is set, a dot metacharacter in the pattern matches a char- + If this bit is set, a dot metacharacter in the pattern matches a char- acter of any value, including one that indicates a newline. However, it - only ever matches one character, even if newlines are coded as CRLF. - Without this option, a dot does not match when the current position is + only ever matches one character, even if newlines are coded as CRLF. + Without this option, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can - be changed within a pattern by a (?s) option setting. A negative class + be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of the set- ting of this option. PCRE_DUPNAMES - If this bit is set, names used to identify capturing subpatterns need + If this bit is set, names used to identify capturing subpatterns need not be unique. This can be helpful for certain types of pattern when it - is known that only one instance of the named subpattern can ever be - matched. There are more details of named subpatterns below; see also + is known that only one instance of the named subpattern can ever be + matched. There are more details of named subpatterns below; see also the pcrepattern documentation. PCRE_EXTENDED - If this bit is set, whitespace data characters in the pattern are - totally ignored except when escaped or inside a character class. White- + If this bit is set, white space data characters in the pattern are + totally ignored except when escaped or inside a character class. White space does not include the VT character (code 11). In addition, charac- ters between an unescaped # outside a character class and the next new- - line, inclusive, are also ignored. This is equivalent to Perl's /x - option, and it can be changed within a pattern by a (?x) option set- + line, inclusive, are also ignored. This is equivalent to Perl's /x + option, and it can be changed within a pattern by a (?x) option set- ting. - Which characters are interpreted as newlines is controlled by the - options passed to pcre_compile() or by a special sequence at the start - of the pattern, as described in the section entitled "Newline conven- + Which characters are interpreted as newlines is controlled by the + options passed to pcre_compile() or by a special sequence at the start + of the pattern, as described in the section entitled "Newline conven- tions" in the pcrepattern documentation. Note that the end of this type - of comment is a literal newline sequence in the pattern; escape + of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. - This option makes it possible to include comments inside complicated - patterns. Note, however, that this applies only to data characters. - Whitespace characters may never appear within special character + This option makes it possible to include comments inside complicated + patterns. Note, however, that this applies only to data characters. + White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that intro- duces a conditional subpattern. PCRE_EXTRA - This option was invented in order to turn on additional functionality - of PCRE that is incompatible with Perl, but it is currently of very - little use. When set, any backslash in a pattern that is followed by a - letter that has no special meaning causes an error, thus reserving - these combinations for future expansion. By default, as in Perl, a - backslash followed by a letter with no special meaning is treated as a + This option was invented in order to turn on additional functionality + of PCRE that is incompatible with Perl, but it is currently of very + little use. When set, any backslash in a pattern that is followed by a + letter that has no special meaning causes an error, thus reserving + these combinations for future expansion. By default, as in Perl, a + backslash followed by a letter with no special meaning is treated as a literal. (Perl can, however, be persuaded to give an error for this, by - running it with the -w option.) There are at present no other features - controlled by this option. It can also be set by a (?X) option setting + running it with the -w option.) There are at present no other features + controlled by this option. It can also be set by a (?X) option setting within a pattern. PCRE_FIRSTLINE - If this option is set, an unanchored pattern is required to match - before or at the first newline in the subject string, though the + If this option is set, an unanchored pattern is required to match + before or at the first newline in the subject string, though the matched text may continue over the newline. PCRE_JAVASCRIPT_COMPAT If this option is set, PCRE's behaviour is changed in some ways so that - it is compatible with JavaScript rather than Perl. The changes are as + it is compatible with JavaScript rather than Perl. The changes are as follows: - (1) A lone closing square bracket in a pattern causes a compile-time - error, because this is illegal in JavaScript (by default it is treated + (1) A lone closing square bracket in a pattern causes a compile-time + error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set. - (2) At run time, a back reference to an unset subpattern group matches - an empty string (by default this causes the current matching alterna- - tive to fail). A pattern such as (\1)(a) succeeds when this option is - set (assuming it can find an "a" in the subject), whereas it fails by + (2) At run time, a back reference to an unset subpattern group matches + an empty string (by default this causes the current matching alterna- + tive to fail). A pattern such as (\1)(a) succeeds when this option is + set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. + (3) \U matches an upper case "U" character; by default \U causes a com- + pile time error (Perl uses \U to upper case subsequent characters). + + (4) \u matches a lower case "u" character unless it is followed by four + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, \u causes a compile time error (Perl + uses it to upper case the following character). + + (5) \x matches a lower case "x" character unless it is followed by two + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, as in Perl, a hexadecimal number is + always expected after \x, but it may have zero, one, or two digits (so, + for example, \xz matches a binary zero character followed by z). + PCRE_MULTILINE - By default, PCRE treats the subject string as consisting of a single - line of characters (even if it actually contains newlines). The "start - of line" metacharacter (^) matches only at the start of the string, - while the "end of line" metacharacter ($) matches only at the end of + By default, PCRE treats the subject string as consisting of a single + line of characters (even if it actually contains newlines). The "start + of line" metacharacter (^) matches only at the start of the string, + while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as Perl. - When PCRE_MULTILINE it is set, the "start of line" and "end of line" - constructs match immediately following or immediately before internal - newlines in the subject string, respectively, as well as at the very - start and end. This is equivalent to Perl's /m option, and it can be + When PCRE_MULTILINE it is set, the "start of line" and "end of line" + constructs match immediately following or immediately before internal + newlines in the subject string, respectively, as well as at the very + start and end. This is equivalent to Perl's /m option, and it can be changed within a pattern by a (?m) option setting. If there are no new- - lines in a subject string, or no occurrences of ^ or $ in a pattern, + lines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. PCRE_NEWLINE_CR @@ -1359,32 +1719,32 @@ PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY - These options override the default newline definition that was chosen - when PCRE was built. Setting the first or the second specifies that a - newline is indicated by a single character (CR or LF, respectively). - Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the - two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies + These options override the default newline definition that was chosen + when PCRE was built. Setting the first or the second specifies that a + newline is indicated by a single character (CR or LF, respectively). + Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the + two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting - PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be + PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, - plus the single characters VT (vertical tab, U+000B), FF (formfeed, - U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS - (paragraph separator, U+2029). The last two are recognized only in - UTF-8 mode. + plus the single characters VT (vertical tab, U+000B), FF (form feed, + U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS + (paragraph separator, U+2029). For the 8-bit library, the last two are + recognized only in UTF-8 mode. - The newline setting in the options word uses three bits that are + The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are - used (default plus the five values above). This means that if you set - more than one newline option, the combination may or may not be sensi- + used (default plus the five values above). This means that if you set + more than one newline option, the combination may or may not be sensi- ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to - PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and + PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error. - The only time that a line break in a pattern is specially recognized - when compiling is when PCRE_EXTENDED is set. CR and LF are whitespace - characters, and so are ignored in this mode. Also, an unescaped # out- - side a character class indicates a comment that lasts until after the - next line break sequence. In other circumstances, line break sequences + The only time that a line break in a pattern is specially recognized + when compiling is when PCRE_EXTENDED is set. CR and LF are white space + characters, and so are ignored in this mode. Also, an unescaped # out- + side a character class indicates a comment that lasts until after the + next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data. The newline option that is set at compile time becomes the default that @@ -1393,66 +1753,67 @@ PCRE_NO_AUTO_CAPTURE If this option is set, it disables the use of numbered capturing paren- - theses in the pattern. Any opening parenthesis that is not followed by - ? behaves as if it were followed by ?: but named parentheses can still - be used for capturing (and they acquire numbers in the usual way). + theses in the pattern. Any opening parenthesis that is not followed by + ? behaves as if it were followed by ?: but named parentheses can still + be used for capturing (and they acquire numbers in the usual way). There is no equivalent of this option in Perl. NO_START_OPTIMIZE - This is an option that acts at matching time; that is, it is really an - option for pcre_exec() or pcre_dfa_exec(). If it is set at compile - time, it is remembered with the compiled pattern and assumed at match- - ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE + This is an option that acts at matching time; that is, it is really an + option for pcre_exec() or pcre_dfa_exec(). If it is set at compile + time, it is remembered with the compiled pattern and assumed at match- + ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE below. PCRE_UCP - This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, - \w, and some of the POSIX character classes. By default, only ASCII - characters are recognized, but if PCRE_UCP is set, Unicode properties - are used instead to classify characters. More details are given in the - section on generic character types in the pcrepattern page. If you set - PCRE_UCP, matching one of the items it affects takes much longer. The - option is available only if PCRE has been compiled with Unicode prop- + This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, + \w, and some of the POSIX character classes. By default, only ASCII + characters are recognized, but if PCRE_UCP is set, Unicode properties + are used instead to classify characters. More details are given in the + section on generic character types in the pcrepattern page. If you set + PCRE_UCP, matching one of the items it affects takes much longer. The + option is available only if PCRE has been compiled with Unicode prop- erty support. PCRE_UNGREEDY - This option inverts the "greediness" of the quantifiers so that they - are not greedy by default, but become greedy if followed by "?". It is - not compatible with Perl. It can also be set by a (?U) option setting + This option inverts the "greediness" of the quantifiers so that they + are not greedy by default, but become greedy if followed by "?". It is + not compatible with Perl. It can also be set by a (?U) option setting within the pattern. PCRE_UTF8 - This option causes PCRE to regard both the pattern and the subject as - strings of UTF-8 characters instead of single-byte character strings. - However, it is available only when PCRE is built to include UTF-8 sup- - port. If not, the use of this option provokes an error. Details of how - this option changes the behaviour of PCRE are given in the section on - UTF-8 support in the main pcre page. + This option causes PCRE to regard both the pattern and the subject as + strings of UTF-8 characters instead of single-byte strings. However, it + is available only when PCRE is built to include UTF support. If not, + the use of this option provokes an error. Details of how this option + changes the behaviour of PCRE are given in the pcreunicode page. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is automatically checked. There is a discussion about the validity of - UTF-8 strings in the main pcre page. If an invalid UTF-8 sequence of - bytes is found, pcre_compile() returns an error. If you already know - that your pattern is valid, and you want to skip this check for perfor- - mance reasons, you can set the PCRE_NO_UTF8_CHECK option. When it is - set, the effect of passing an invalid UTF-8 string as a pattern is - undefined. It may cause your program to crash. Note that this option - can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress the - UTF-8 validity checking of subject strings. + UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is + found, pcre_compile() returns an error. If you already know that your + pattern is valid, and you want to skip this check for performance rea- + sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the + effect of passing an invalid UTF-8 string as a pattern is undefined. It + may cause your program to crash. Note that this option can also be + passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity + checking of subject strings. COMPILATION ERROR CODES The following table lists the error codes than may be returned by pcre_compile2(), along with the error messages that may be returned by - both compiling functions. As PCRE has developed, some error codes have - fallen out of use. To avoid confusion, they have not been re-used. + both compiling functions. Note that error messages are always 8-bit + ASCII strings, even in 16-bit mode. As PCRE has developed, some error + codes have fallen out of use. To avoid confusion, they have not been + re-used. 0 no error 1 \ at end of pattern @@ -1486,26 +1847,26 @@ 29 (?R or (?[+-]digits must be followed by ) 30 unknown POSIX class name 31 POSIX collating elements are not supported - 32 this version of PCRE is not compiled with PCRE_UTF8 support + 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] 34 character value in \x{...} sequence is too large 35 invalid condition (?(0) 36 \C not allowed in lookbehind assertion - 37 PCRE does not support \L, \l, \N, \U, or \u + 37 PCRE does not support \L, \l, \N{name}, \U, or \u 38 number after (?C is > 255 39 closing ) for (?C expected 40 recursive call could loop indefinitely 41 unrecognized character after (?P 42 syntax error in subpattern name (missing terminator) 43 two named subpatterns have the same name - 44 invalid UTF-8 string + 44 invalid UTF-8 string (specifically UTF-8) 45 support for \P, \p, and \X has not been compiled 46 malformed \P or \p sequence 47 unknown property name after \P or \p 48 subpattern name is too long (maximum 32 characters) 49 too many named subpatterns (maximum 10000) 50 [this code is not in use] - 51 octal value is greater than \377 (not in UTF-8 mode) + 51 octal value is greater than \377 in 8-bit non-UTF-8 mode 52 internal error: overran compiling workspace 53 internal error: previously-checked referenced subpattern not found @@ -1524,7 +1885,17 @@ 65 different names for subpatterns of the same number are not allowed 66 (*MARK) must have an argument - 67 this version of PCRE is not compiled with PCRE_UCP support + 67 this version of PCRE is not compiled with Unicode property + support + 68 \c must be followed by an ASCII character + 69 \k is not followed by a braced, angle-bracketed, or quoted name + 70 internal error: unknown opcode in find_fixedlength() + 71 \N is not supported in a class + 72 too many forward references + 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff) + 74 invalid UTF-16 string (specifically UTF-16) + 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) + 76 character value in \u.... sequence is too large The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. @@ -1553,8 +1924,26 @@ wants to pass any of the other fields to pcre_exec() or pcre_dfa_exec(), it must set up its own pcre_extra block. - The second argument of pcre_study() contains option bits. At present, - no options are defined, and this argument should always be zero. + The second argument of pcre_study() contains option bits. There are + three options: + + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + If any of these are set, and the just-in-time compiler is available, + the pattern is further compiled into machine code that executes much + faster than the pcre_exec() interpretive matching function. If the + just-in-time compiler is not available, these options are ignored. All + other bits in the options argument must be zero. + + JIT compilation is a heavyweight optimization. It can take some time + for patterns to be analyzed, and for one-off matches and simple pat- + terns the benefit of faster execution might be offset by a much slower + study time. Not all patterns can be optimized by the JIT compiler. For + those that cannot be handled, matching automatically falls back to the + pcre_exec() interpreter. For more details, see the pcrejit documenta- + tion. The third argument for pcre_study() is a pointer for an error message. If studying succeeds (even if no data is returned), the variable it @@ -1563,13 +1952,29 @@ must not try to free it. You should test the error pointer for NULL after calling pcre_study(), to be sure that it has run successfully. - This is a typical call to pcre_study(): + When you are finished with a pattern, you can free the memory used for + the study data by calling pcre_free_study(). This function was added to + the API for release 8.20. For earlier versions, the memory could be + freed with pcre_free(), just like the pattern itself. This will still + work in cases where JIT optimization is not used, but it is advisable + to change to the new function when convenient. - pcre_extra *pe; - pe = pcre_study( + This is a typical way in which pcre_study() is used (except that in a + real application there should be tests for errors): + + int rc; + pcre *re; + pcre_extra *sd; + re = pcre_compile("pattern", 0, &error, &erroroffset, NULL); + sd = pcre_study( re, /* result of pcre_compile() */ - 0, /* no options exist */ + 0, /* no options */ &error); /* set to NULL or points to a message */ + rc = pcre_exec( /* see below for details of pcre_exec() options */ + re, sd, "subject", 7, 0, 0, ovector, 30); + ... + pcre_free_study(sd); + pcre_free(re); Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This @@ -1582,70 +1987,73 @@ Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at - which to start matching. + which to start matching. (In 16-bit mode, the bitmap is used for 16-bit + values less than 256.) - The two optimizations just described can be disabled by setting the - PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or - pcre_dfa_exec(). You might want to do this if your pattern contains - callouts or (*MARK), and you want to make use of these facilities in - cases where matching fails. See the discussion of PCRE_NO_START_OPTI- - MIZE below. + These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), + and the information is also used by the JIT compiler. The optimiza- + tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option when + calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execu- + tion is also disabled. You might want to do this if your pattern con- + tains callouts or (*MARK) and you want to make use of these facilities + in cases where matching fails. See the discussion of + PCRE_NO_START_OPTIMIZE below. LOCALE SUPPORT - PCRE handles caseless matching, and determines whether characters are - letters, digits, or whatever, by reference to a set of tables, indexed - by character value. When running in UTF-8 mode, this applies only to - characters with codes less than 128. By default, higher-valued codes + PCRE handles caseless matching, and determines whether characters are + letters, digits, or whatever, by reference to a set of tables, indexed + by character value. When running in UTF-8 mode, this applies only to + characters with codes less than 128. By default, higher-valued codes never match escapes such as \w or \d, but they can be tested with \p if - PCRE is built with Unicode character property support. Alternatively, - the PCRE_UCP option can be set at compile time; this causes \w and + PCRE is built with Unicode character property support. Alternatively, + the PCRE_UCP option can be set at compile time; this causes \w and friends to use Unicode property support instead of built-in tables. The use of locales with Unicode is discouraged. If you are handling charac- - ters with codes greater than 128, you should either use UTF-8 and Uni- + ters with codes greater than 128, you should either use UTF-8 and Uni- code, or use locales, but not try to mix the two. - PCRE contains an internal set of tables that are used when the final - argument of pcre_compile() is NULL. These are sufficient for many + PCRE contains an internal set of tables that are used when the final + argument of pcre_compile() is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII char- acters. However, when PCRE is built, it is possible to cause the inter- nal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different. - The internal tables can always be overridden by tables supplied by the + The internal tables can always be overridden by tables supplied by the application that calls PCRE. These may be created in a different locale - from the default. As more and more applications change to using Uni- + from the default. As more and more applications change to using Uni- code, the need for this locale support is expected to die away. - External tables are built by calling the pcre_maketables() function, - which has no arguments, in the relevant locale. The result can then be - passed to pcre_compile() or pcre_exec() as often as necessary. For - example, to build and use tables that are appropriate for the French - locale (where accented characters with values greater than 128 are + External tables are built by calling the pcre_maketables() function, + which has no arguments, in the relevant locale. The result can then be + passed to pcre_compile() or pcre_exec() as often as necessary. For + example, to build and use tables that are appropriate for the French + locale (where accented characters with values greater than 128 are treated as letters), the following code could be used: setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); re = pcre_compile(..., tables); - The locale name "fr_FR" is used on Linux and other Unix-like systems; + The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french". - When pcre_maketables() runs, the tables are built in memory that is - obtained via pcre_malloc. It is the caller's responsibility to ensure - that the memory containing the tables remains available for as long as + When pcre_maketables() runs, the tables are built in memory that is + obtained via pcre_malloc. It is the caller's responsibility to ensure + that the memory containing the tables remains available for as long as it is needed. The pointer that is passed to pcre_compile() is saved with the compiled - pattern, and the same tables are used via this pointer by pcre_study() + pattern, and the same tables are used via this pointer by pcre_study() and normally also by pcre_exec(). Thus, by default, for any single pat- tern, compilation, studying and matching all happen in the same locale, but different patterns can be compiled in different locales. - It is possible to pass a table pointer or NULL (indicating the use of - the internal tables) to pcre_exec(). Although not intended for this - purpose, this facility could be used to match a pattern in a different + It is possible to pass a table pointer or NULL (indicating the use of + the internal tables) to pcre_exec(). Although not intended for this + purpose, this facility could be used to match a pattern in a different locale from the one in which it was compiled. Passing table pointers at run time is discussed below in the section on matching a pattern. @@ -1655,32 +2063,35 @@ int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); - The pcre_fullinfo() function returns information about a compiled pat- - tern. It replaces the obsolete pcre_info() function, which is neverthe- - less retained for backwards compability (and is documented below). - - The first argument for pcre_fullinfo() is a pointer to the compiled - pattern. The second argument is the result of pcre_study(), or NULL if - the pattern was not studied. The third argument specifies which piece - of information is required, and the fourth argument is a pointer to a - variable to receive the data. The yield of the function is zero for + The pcre_fullinfo() function returns information about a compiled pat- + tern. It replaces the pcre_info() function, which was removed from the + library at version 8.30, after more than 10 years of obsolescence. + + The first argument for pcre_fullinfo() is a pointer to the compiled + pattern. The second argument is the result of pcre_study(), or NULL if + the pattern was not studied. The third argument specifies which piece + of information is required, and the fourth argument is a pointer to a + variable to receive the data. The yield of the function is zero for success, or one of the following negative numbers: - PCRE_ERROR_NULL the argument code was NULL - the argument where was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found - PCRE_ERROR_BADOPTION the value of what was invalid - - The "magic number" is placed at the start of each compiled pattern as - an simple check against passing an arbitrary memory pointer. Here is a - typical call of pcre_fullinfo(), to obtain the length of the compiled - pattern: + PCRE_ERROR_NULL the argument code was NULL + the argument where was NULL + PCRE_ERROR_BADMAGIC the "magic number" was not found + PCRE_ERROR_BADENDIANNESS the pattern was compiled with different + endianness + PCRE_ERROR_BADOPTION the value of what was invalid + + The "magic number" is placed at the start of each compiled pattern as + an simple check against passing an arbitrary memory pointer. The endi- + anness error can occur if a compiled pattern is saved and reloaded on a + different host. Here is a typical call of pcre_fullinfo(), to obtain + the length of the compiled pattern: int rc; size_t length; rc = pcre_fullinfo( re, /* result of pcre_compile() */ - pe, /* result of pcre_study(), or NULL */ + sd, /* result of pcre_study(), or NULL */ PCRE_INFO_SIZE, /* what is required */ &length); /* where to put the data */ @@ -1708,13 +2119,17 @@ PCRE_INFO_FIRSTBYTE - Return information about the first byte of any matched string, for a - non-anchored pattern. The fourth argument should point to an int vari- - able. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name - is still recognized for backwards compatibility.) + Return information about the first data unit of any matched string, for + a non-anchored pattern. (The name of this option refers to the 8-bit + library, where data units are bytes.) The fourth argument should point + to an int variable. + + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), its value is returned. In the 8-bit + library, the value is always less than 256; in the 16-bit library the + value can be up to 0xffff. - If there is a fixed first byte, for example, from a pattern such as - (cat|cow|coyote), its value is returned. Otherwise, if either + If there is no fixed first value, and if either (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or @@ -1729,10 +2144,10 @@ PCRE_INFO_FIRSTTABLE If the pattern was studied, and this resulted in the construction of a - 256-bit table indicating a fixed set of bytes for the first byte in any - matching string, a pointer to the table is returned. Otherwise NULL is - returned. The fourth argument should point to an unsigned char * vari- - able. + 256-bit table indicating a fixed set of values for the first data unit + in any matching string, a pointer to the table is returned. Otherwise + NULL is returned. The fourth argument should point to an unsigned char + * variable. PCRE_INFO_HASCRORLF @@ -1747,25 +2162,49 @@ otherwise 0. The fourth argument should point to an int variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. + PCRE_INFO_JIT + + Return 1 if the pattern was studied with one of the JIT options, and + just-in-time compiling was successful. The fourth argument should point + to an int variable. A return value of 0 means that JIT support is not + available in this version of PCRE, or that the pattern was not studied + with a JIT option, or that the JIT compiler could not handle this par- + ticular pattern. See the pcrejit documentation for details of what can + and cannot be handled. + + PCRE_INFO_JITSIZE + + If the pattern was successfully studied with a JIT option, return the + size of the JIT compiled code, otherwise return zero. The fourth argu- + ment should point to a size_t variable. + PCRE_INFO_LASTLITERAL - Return the value of the rightmost literal byte that must exist in any - matched string, other than at its start, if such a byte has been + Return the value of the rightmost literal data unit that must exist in + any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an int variable. If there - is no such byte, -1 is returned. For anchored patterns, a last literal - byte is recorded only if it follows something of variable length. For + is no such value, -1 is returned. For anchored patterns, a last literal + value is recorded only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1. + PCRE_INFO_MAXLOOKBEHIND + + Return the number of characters (NB not bytes) in the longest lookbe- + hind assertion in the pattern. Note that the simple assertions \b and + \B require a one-character lookbehind. This information is useful when + doing multi-segment matching using the partial matching facilities. + PCRE_INFO_MINLENGTH - If the pattern was studied and a minimum length for matching subject - strings was computed, its value is returned. Otherwise the returned - value is -1. The value is a number of characters, not bytes (this may - be relevant in UTF-8 mode). The fourth argument should point to an int - variable. A non-negative value is a lower bound to the length of any - matching string. There may not be any strings of that length that do - actually match, but every string that does match is at least that long. + If the pattern was studied and a minimum length for matching subject + strings was computed, its value is returned. Otherwise the returned + value is -1. The value is a number of characters, which in UTF-8 mode + may be different from the number of bytes. The fourth argument should + point to an int variable. A non-negative value is a lower bound to the + length of any matching string. There may not be any strings of that + length that do actually match, but every string that does match is at + least that long. PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE @@ -1785,10 +2224,12 @@ gives the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each entry; both of these return an int value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns - a pointer to the first entry of the table (a pointer to char). The - first two bytes of each entry are the number of the capturing parenthe- - sis, most significant byte first. The rest of the entry is the corre- - sponding name, zero terminated. + a pointer to the first entry of the table. This is a pointer to char in + the 8-bit library, where the first two bytes of each entry are the num- + ber of the capturing parenthesis, most significant byte first. In the + 16-bit library, the pointer points to 16-bit data units, the first of + which contains the parenthesis number. The rest of the entry is the + corresponding name, zero terminated. The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in @@ -1801,8 +2242,8 @@ terns may have lower numbers. As a simple example of the name/number table, consider the following - pattern (assume PCRE_EXTENDED is set, so white space - including new- - lines - is ignored): + pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is + set, so white space - including newlines - is ignored): (? (?(\d\d)?\d\d) - (?\d\d) - (?\d\d) ) @@ -1855,62 +2296,47 @@ PCRE_INFO_SIZE - Return the size of the compiled pattern, that is, the value that was - passed as the argument to pcre_malloc() when PCRE was getting memory in - which to place the compiled data. The fourth argument should point to a - size_t variable. + Return the size of the compiled pattern in bytes (for both libraries). + The fourth argument should point to a size_t variable. This value does + not include the size of the pcre structure that is returned by + pcre_compile(). The value that is passed as the argument to pcre_mal- + loc() when pcre_compile() is getting memory in which to place the com- + piled data is the value returned by this option plus the size of the + pcre structure. Studying a compiled pattern, with or without JIT, does + not alter the value returned by this option. PCRE_INFO_STUDYSIZE - Return the size of the data block pointed to by the study_data field in - a pcre_extra block. That is, it is the value that was passed to - pcre_malloc() when PCRE was getting memory into which to place the data - created by pcre_study(). If pcre_extra is NULL, or there is no study - data, zero is returned. The fourth argument should point to a size_t - variable. - - -OBSOLETE INFO FUNCTION - - int pcre_info(const pcre *code, int *optptr, int *firstcharptr); - - The pcre_info() function is now obsolete because its interface is too - restrictive to return all the available data about a compiled pattern. - New programs should use pcre_fullinfo() instead. The yield of - pcre_info() is the number of capturing subpatterns, or one of the fol- - lowing negative numbers: - - PCRE_ERROR_NULL the argument code was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found - - If the optptr argument is not NULL, a copy of the options with which - the pattern was compiled is placed in the integer it points to (see - PCRE_INFO_OPTIONS above). - - If the pattern is not anchored and the firstcharptr argument is not - NULL, it is used to pass back information about the first character of - any matched string (see PCRE_INFO_FIRSTBYTE above). + Return the size in bytes of the data block pointed to by the study_data + field in a pcre_extra block. If pcre_extra is NULL, or there is no + study data, zero is returned. The fourth argument should point to a + size_t variable. The study_data field is set by pcre_study() to record + information that will speed up matching (see the section entitled + "Studying a pattern" above). The format of the study_data block is pri- + vate, but its length is made available via this option so that it can + be saved and restored (see the pcreprecompile documentation for + details). REFERENCE COUNTS int pcre_refcount(pcre *code, int adjust); - The pcre_refcount() function is used to maintain a reference count in + The pcre_refcount() function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the - benefit of applications that operate in an object-oriented manner, + benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done. When a pattern is compiled, the reference count field is initialized to - zero. It is changed only by calling this function, whose action is to - add the adjust value (which may be positive or negative) to it. The + zero. It is changed only by calling this function, whose action is to + add the adjust value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count - is constrained to lie between 0 and 65535, inclusive. If the new value + is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value. - Except when it is zero, the reference count is not correctly preserved - if a pattern is compiled on one host and then transferred to a host + Except when it is zero, the reference count is not correctly preserved + if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.) @@ -1920,18 +2346,22 @@ const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); - The function pcre_exec() is called to match a subject string against a - compiled pattern, which is passed in the code argument. If the pattern - was studied, the result of the study should be passed in the extra - argument. This function is the main matching facility of the library, - and it operates in a Perl-like manner. For specialist use there is also - an alternative matching function, which is described below in the sec- - tion about the pcre_dfa_exec() function. + The function pcre_exec() is called to match a subject string against a + compiled pattern, which is passed in the code argument. If the pattern + was studied, the result of the study should be passed in the extra + argument. You can call pcre_exec() with the same code and extra argu- + ments as many times as you like, in order to match different subject + strings with the same pattern. + + This function is the main matching facility of the library, and it + operates in a Perl-like manner. For specialist use there is also an + alternative matching function, which is described below in the section + about the pcre_dfa_exec() function. - In most applications, the pattern will have been compiled (and option- - ally studied) in the same process that calls pcre_exec(). However, it + In most applications, the pattern will have been compiled (and option- + ally studied) in the same process that calls pcre_exec(). However, it is possible to save compiled patterns and study data, and then use them - later in different processes, possibly even on different hosts. For a + later in different processes, possibly even on different hosts. For a discussion about this, see the pcreprecompile documentation. Here is an example of a simple call to pcre_exec(): @@ -1950,35 +2380,40 @@ Extra data for pcre_exec() - If the extra argument is not NULL, it must point to a pcre_extra data - block. The pcre_study() function returns such a block (when it doesn't - return NULL), but you can also create one for yourself, and pass addi- - tional information in it. The pcre_extra block contains the following + If the extra argument is not NULL, it must point to a pcre_extra data + block. The pcre_study() function returns such a block (when it doesn't + return NULL), but you can also create one for yourself, and pass addi- + tional information in it. The pcre_extra block contains the following fields (not necessarily in this order): unsigned long int flags; void *study_data; + void *executable_jit; unsigned long int match_limit; unsigned long int match_limit_recursion; void *callout_data; const unsigned char *tables; unsigned char **mark; - The flags field is a bitmap that specifies which of the other fields - are set. The flag bits are: + In the 16-bit version of this structure, the mark field has type + "PCRE_UCHAR16 **". - PCRE_EXTRA_STUDY_DATA + The flags field is used to specify which of the other fields are set. + The flag bits are: + + PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_EXECUTABLE_JIT + PCRE_EXTRA_MARK PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_MATCH_LIMIT_RECURSION - PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES - PCRE_EXTRA_MARK - Other flag bits should be set to zero. The study_data field is set in - the pcre_extra block that is returned by pcre_study(), together with - the appropriate flag bit. You should not set this yourself, but you may - add to the block by setting the other fields and their corresponding - flag bits. + Other flag bits should be set to zero. The study_data field and some- + times the executable_jit field are set in the pcre_extra block that is + returned by pcre_study(), together with the appropriate flag bits. You + should not set these yourself, but you may add to the block by setting + other fields and their corresponding flag bits. The match_limit field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to @@ -1986,70 +2421,86 @@ search trees. The classic example is a pattern that uses nested unlim- ited repeats. - Internally, PCRE uses a function called match() which it calls repeat- - edly (sometimes recursively). The limit set by match_limit is imposed - on the number of times this function is called during a match, which - has the effect of limiting the amount of backtracking that can take - place. For patterns that are not anchored, the count restarts from zero - for each position in the subject string. - - The default value for the limit can be set when PCRE is built; the - default default is 10 million, which handles all but the most extreme - cases. You can override the default by suppling pcre_exec() with a - pcre_extra block in which match_limit is set, and - PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is + Internally, pcre_exec() uses a function called match(), which it calls + repeatedly (sometimes recursively). The limit set by match_limit is + imposed on the number of times this function is called during a match, + which has the effect of limiting the amount of backtracking that can + take place. For patterns that are not anchored, the count restarts from + zero for each position in the subject string. + + When pcre_exec() is called with a pattern that was successfully studied + with a JIT option, the way that the matching is executed is entirely + different. However, there is still the possibility of runaway matching + that goes on for a very long time, and so the match_limit value is also + used in this case (but in a different way) to limit how long the match- + ing can continue. + + The default value for the limit can be set when PCRE is built; the + default default is 10 million, which handles all but the most extreme + cases. You can override the default by suppling pcre_exec() with a + pcre_extra block in which match_limit is set, and + PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. - The match_limit_recursion field is similar to match_limit, but instead + The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits - the depth of recursion. The recursion depth is a smaller number than - the total number of calls, because not all calls to match() are recur- + the depth of recursion. The recursion depth is a smaller number than + the total number of calls, because not all calls to match() are recur- sive. This limit is of use only if it is set smaller than match_limit. - Limiting the recursion depth limits the amount of stack that can be - used, or, when PCRE has been compiled to use memory on the heap instead - of the stack, the amount of heap memory that can be used. - - The default value for match_limit_recursion can be set when PCRE is - built; the default default is the same value as the default for - match_limit. You can override the default by suppling pcre_exec() with - a pcre_extra block in which match_limit_recursion is set, and - PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the + Limiting the recursion depth limits the amount of machine stack that + can be used, or, when PCRE has been compiled to use memory on the heap + instead of the stack, the amount of heap memory that can be used. This + limit is not relevant, and is ignored, when matching is done using JIT + compiled code. + + The default value for match_limit_recursion can be set when PCRE is + built; the default default is the same value as the default for + match_limit. You can override the default by suppling pcre_exec() with + a pcre_extra block in which match_limit_recursion is set, and + PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT. - The callout_data field is used in conjunction with the "callout" fea- + The callout_data field is used in conjunction with the "callout" fea- ture, and is described in the pcrecallout documentation. - The tables field is used to pass a character tables pointer to - pcre_exec(); this overrides the value that is stored with the compiled - pattern. A non-NULL value is stored with the compiled pattern only if - custom tables were supplied to pcre_compile() via its tableptr argu- + The tables field is used to pass a character tables pointer to + pcre_exec(); this overrides the value that is stored with the compiled + pattern. A non-NULL value is stored with the compiled pattern only if + custom tables were supplied to pcre_compile() via its tableptr argu- ment. If NULL is passed to pcre_exec() using this mechanism, it forces - PCRE's internal tables to be used. This facility is helpful when re- - using patterns that have been saved after compiling with an external - set of tables, because the external tables might be at a different - address when pcre_exec() is called. See the pcreprecompile documenta- + PCRE's internal tables to be used. This facility is helpful when re- + using patterns that have been saved after compiling with an external + set of tables, because the external tables might be at a different + address when pcre_exec() is called. See the pcreprecompile documenta- tion for a discussion of saving compiled patterns for later use. - If PCRE_EXTRA_MARK is set in the flags field, the mark field must be - set to point to a char * variable. If the pattern contains any back- - tracking control verbs such as (*MARK:NAME), and the execution ends up - with a name to pass back, a pointer to the name string (zero termi- - nated) is placed in the variable pointed to by the mark field. The - names are within the compiled pattern; if you wish to retain such a - name you must copy it before freeing the memory of a compiled pattern. - If there is no name to pass back, the variable pointed to by the mark - field set to NULL. For details of the backtracking control verbs, see - the section entitled "Backtracking control" in the pcrepattern documen- - tation. + If PCRE_EXTRA_MARK is set in the flags field, the mark field must be + set to point to a suitable variable. If the pattern contains any back- + tracking control verbs such as (*MARK:NAME), and the execution ends up + with a name to pass back, a pointer to the name string (zero termi- + nated) is placed in the variable pointed to by the mark field. The + names are within the compiled pattern; if you wish to retain such a + name you must copy it before freeing the memory of a compiled pattern. + If there is no name to pass back, the variable pointed to by the mark + field is set to NULL. For details of the backtracking control verbs, + see the section entitled "Backtracking control" in the pcrepattern doc- + umentation. Option bits for pcre_exec() - The unused bits of the options argument for pcre_exec() must be zero. - The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, - PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, - PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and - PCRE_PARTIAL_HARD. + The unused bits of the options argument for pcre_exec() must be zero. + The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, + PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, + PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and + PCRE_PARTIAL_SOFT. + + If the pattern was successfully studied with one of the just-in-time + (JIT) compile options, the only supported options for JIT execution are + PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, + PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an + unsupported option is used, JIT execution is disabled and the normal + interpretive code in pcre_exec() is run. PCRE_ANCHORED @@ -2172,7 +2623,9 @@ where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at - compile time, it cannot be unset at matching time. + compile time, it cannot be unset at matching time. The use of + PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching + is always done using interpretively. Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern @@ -2206,182 +2659,201 @@ When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when pcre_exec() is subsequently - called. The value of startoffset is also checked to ensure that it - points to the start of a UTF-8 character. There is a discussion about - the validity of UTF-8 strings in the section on UTF-8 support in the - main pcre page. If an invalid UTF-8 sequence of bytes is found, - pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PAR- - TIAL_HARD is set and the problem is a truncated UTF-8 character at the - end of the subject, PCRE_ERROR_SHORTUTF8. If startoffset contains a - value that does not point to the start of a UTF-8 character (or to the - end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. - - If you already know that your subject is valid, and you want to skip - these checks for performance reasons, you can set the - PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to - do this for the second and subsequent calls to pcre_exec() if you are - making repeated calls to find all the matches in a single subject - string. However, you should be sure that the value of startoffset - points to the start of a UTF-8 character (or the end of the subject). - When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid UTF-8 - string as a subject or an invalid value of startoffset is undefined. - Your program may crash. + called. The entire string is checked before any other processing takes + place. The value of startoffset is also checked to ensure that it + points to the start of a UTF-8 character. There is a discussion about + the validity of UTF-8 strings in the pcreunicode page. If an invalid + sequence of bytes is found, pcre_exec() returns the error + PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a + truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In + both cases, information about the precise nature of the error may also + be returned (see the descriptions of these errors in the section enti- + tled Error return values from pcre_exec() below). If startoffset con- + tains a value that does not point to the start of a UTF-8 character (or + to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. + + If you already know that your subject is valid, and you want to skip + these checks for performance reasons, you can set the + PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to + do this for the second and subsequent calls to pcre_exec() if you are + making repeated calls to find all the matches in a single subject + string. However, you should be sure that the value of startoffset + points to the start of a character (or the end of the subject). When + PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a + subject or an invalid value of startoffset is undefined. Your program + may crash. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These options turn on the partial matching feature. For backwards com- - patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial - match occurs if the end of the subject string is reached successfully, - but there are not enough subject characters to complete the match. If + These options turn on the partial matching feature. For backwards com- + patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial + match occurs if the end of the subject string is reached successfully, + but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, - matching continues by testing any remaining alternatives. Only if no - complete match can be found is PCRE_ERROR_PARTIAL returned instead of - PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the - caller is prepared to handle a partial match, but only if no complete + matching continues by testing any remaining alternatives. Only if no + complete match can be found is PCRE_ERROR_PARTIAL returned instead of + PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the + caller is prepared to handle a partial match, but only if no complete match can be found. - If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this - case, if a partial match is found, pcre_exec() immediately returns - PCRE_ERROR_PARTIAL, without considering any other alternatives. In - other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- + If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this + case, if a partial match is found, pcre_exec() immediately returns + PCRE_ERROR_PARTIAL, without considering any other alternatives. In + other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- ered to be more important that an alternative complete match. - In both cases, the portion of the string that was inspected when the + In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a - more detailed discussion of partial and multi-segment matching, with + more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation. The string to be matched by pcre_exec() - The subject string is passed to pcre_exec() as a pointer in subject, a - length (in bytes) in length, and a starting byte offset in startoffset. - If this is negative or greater than the length of the subject, - pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is - zero, the search for a match starts at the beginning of the subject, + The subject string is passed to pcre_exec() as a pointer in subject, a + length in bytes in length, and a starting byte offset in startoffset. + If this is negative or greater than the length of the subject, + pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is + zero, the search for a match starts at the beginning of the subject, and this is by far the most common case. In UTF-8 mode, the byte offset - must point to the start of a UTF-8 character (or the end of the sub- - ject). Unlike the pattern string, the subject may contain binary zero + must point to the start of a UTF-8 character (or the end of the sub- + ject). Unlike the pattern string, the subject may contain binary zero bytes. - A non-zero starting offset is useful when searching for another match - in the same subject by calling pcre_exec() again after a previous suc- - cess. Setting startoffset differs from just passing over a shortened - string and setting PCRE_NOTBOL in the case of a pattern that begins + A non-zero starting offset is useful when searching for another match + in the same subject by calling pcre_exec() again after a previous suc- + cess. Setting startoffset differs from just passing over a shortened + string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern \Biss\B - which finds occurrences of "iss" in the middle of words. (\B matches - only if the current position in the subject is not a word boundary.) - When applied to the string "Mississipi" the first call to pcre_exec() - finds the first occurrence. If pcre_exec() is called again with just - the remainder of the subject, namely "issipi", it does not match, + which finds occurrences of "iss" in the middle of words. (\B matches + only if the current position in the subject is not a word boundary.) + When applied to the string "Mississipi" the first call to pcre_exec() + finds the first occurrence. If pcre_exec() is called again with just + the remainder of the subject, namely "issipi", it does not match, because \B is always false at the start of the subject, which is deemed - to be a word boundary. However, if pcre_exec() is passed the entire + to be a word boundary. However, if pcre_exec() is passed the entire string again, but with startoffset set to 4, it finds the second occur- - rence of "iss" because it is able to look behind the starting point to + rence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter. - Finding all the matches in a subject is tricky when the pattern can + Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by - first trying the match again at the same offset, with the - PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that - fails, advancing the starting offset and trying an ordinary match + first trying the match again at the same offset, with the + PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that + fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the pcre- demo sample program. In the most general case, you have to check to see - if the newline convention recognizes CRLF as a newline, and if so, and + if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. - If a non-zero starting offset is passed when the pattern is anchored, + If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed - if the pattern does not require the match to be at the start of the + if the pattern does not require the match to be at the start of the subject. How pcre_exec() returns captured substrings - In general, a pattern matches a certain portion of the subject, and in - addition, further substrings from the subject may be picked out by - parts of the pattern. Following the usage in Jeffrey Friedl's book, - this is called "capturing" in what follows, and the phrase "capturing - subpattern" is used for a fragment of a pattern that picks out a sub- - string. PCRE supports several other kinds of parenthesized subpattern + In general, a pattern matches a certain portion of the subject, and in + addition, further substrings from the subject may be picked out by + parts of the pattern. Following the usage in Jeffrey Friedl's book, + this is called "capturing" in what follows, and the phrase "capturing + subpattern" is used for a fragment of a pattern that picks out a sub- + string. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured. Captured substrings are returned to the caller via a vector of integers - whose address is passed in ovector. The number of elements in the vec- - tor is passed in ovecsize, which must be a non-negative number. Note: + whose address is passed in ovector. The number of elements in the vec- + tor is passed in ovecsize, which must be a non-negative number. Note: this argument is NOT the size of ovector in bytes. - The first two-thirds of the vector is used to pass back captured sub- - strings, each substring using a pair of integers. The remaining third - of the vector is used as workspace by pcre_exec() while matching cap- - turing subpatterns, and is not available for passing back information. - The number passed in ovecsize should always be a multiple of three. If + The first two-thirds of the vector is used to pass back captured sub- + strings, each substring using a pair of integers. The remaining third + of the vector is used as workspace by pcre_exec() while matching cap- + turing subpatterns, and is not available for passing back information. + The number passed in ovecsize should always be a multiple of three. If it is not, it is rounded down. - When a match is successful, information about captured substrings is - returned in pairs of integers, starting at the beginning of ovector, - and continuing up to two-thirds of its length at the most. The first - element of each pair is set to the byte offset of the first character - in a substring, and the second is set to the byte offset of the first - character after the end of a substring. Note: these values are always + When a match is successful, information about captured substrings is + returned in pairs of integers, starting at the beginning of ovector, + and continuing up to two-thirds of its length at the most. The first + element of each pair is set to the byte offset of the first character + in a substring, and the second is set to the byte offset of the first + character after the end of a substring. Note: these values are always byte offsets, even in UTF-8 mode. They are not character counts. - The first pair of integers, ovector[0] and ovector[1], identify the - portion of the subject string matched by the entire pattern. The next - pair is used for the first capturing subpattern, and so on. The value + The first pair of integers, ovector[0] and ovector[1], identify the + portion of the subject string matched by the entire pattern. The next + pair is used for the first capturing subpattern, and so on. The value returned by pcre_exec() is one more than the highest numbered pair that - has been set. For example, if two substrings have been captured, the - returned value is 3. If there are no capturing subpatterns, the return + has been set. For example, if two substrings have been captured, the + returned value is 3. If there are no capturing subpatterns, the return value from a successful match is 1, indicating that just the first pair of offsets has been set. If a capturing subpattern is matched repeatedly, it is the last portion of the string that it matched that is returned. - If the vector is too small to hold all the captured substring offsets, + If the vector is too small to hold all the captured substring offsets, it is used as far as possible (up to two-thirds of its length), and the - function returns a value of zero. If the substring offsets are not of - interest, pcre_exec() may be called with ovector passed as NULL and - ovecsize as zero. However, if the pattern contains back references and - the ovector is not big enough to remember the related substrings, PCRE - has to get additional memory for use during matching. Thus it is usu- - ally advisable to supply an ovector. + function returns a value of zero. If neither the actual string matched + nor any captured substrings are of interest, pcre_exec() may be called + with ovector passed as NULL and ovecsize as zero. However, if the pat- + tern contains back references and the ovector is not big enough to + remember the related substrings, PCRE has to get additional memory for + use during matching. Thus it is usually advisable to supply an ovector + of reasonable size. + + There are some cases where zero is returned (indicating vector over- + flow) when in fact the vector is exactly the right size for the final + match. For example, consider the pattern + + (a)(?:(b)c|bd) + + If a vector of 6 elements (allowing for only 1 captured substring) is + given with subject string "abd", pcre_exec() will try to set the second + captured string, thereby recording a vector overflow, before failing to + match "c" and backing up to try the second alternative. The zero + return, however, does correctly indicate that the maximum number of + slots (namely 2) have been filled. In similar cases where there is tem- + porary overflow, but the final number of used slots is actually less + than the maximum, a non-zero value is returned. The pcre_fullinfo() function can be used to find out how many capturing - subpatterns there are in a compiled pattern. The smallest size for - ovector that will allow for n captured substrings, in addition to the + subpatterns there are in a compiled pattern. The smallest size for + ovector that will allow for n captured substrings, in addition to the offsets of the substring matched by the whole pattern, is (n+1)*3. - It is possible for capturing subpattern number n+1 to match some part + It is possible for capturing subpattern number n+1 to match some part of the subject when subpattern n has not been used at all. For example, - if the string "abc" is matched against the pattern (a|(z))(bc) the + if the string "abc" is matched against the pattern (a|(z))(bc) the return from the function is 4, and subpatterns 1 and 3 are matched, but - 2 is not. When this happens, both values in the offset pairs corre- + 2 is not. When this happens, both values in the offset pairs corre- sponding to unused subpatterns are set to -1. - Offset values that correspond to unused subpatterns at the end of the - expression are also set to -1. For example, if the string "abc" is - matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not - matched. The return from the function is 2, because the highest used - capturing subpattern number is 1, and the offsets for for the second - and third capturing subpatterns (assuming the vector is large enough, + Offset values that correspond to unused subpatterns at the end of the + expression are also set to -1. For example, if the string "abc" is + matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not + matched. The return from the function is 2, because the highest used + capturing subpattern number is 1, and the offsets for for the second + and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. - Note: Elements of ovector that do not correspond to capturing parenthe- - ses in the pattern are never changed. That is, if a pattern contains n - capturing parentheses, no more than ovector[0] to ovector[2n+1] are set - by pcre_exec(). The other elements retain whatever values they previ- - ously had. + Note: Elements in the first two-thirds of ovector that do not corre- + spond to capturing parentheses in the pattern are never changed. That + is, if a pattern contains n capturing parentheses, no more than ovec- + tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in + the first two-thirds) retain whatever values they previously had. - Some convenience functions are provided for extracting the captured + Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. Error return values from pcre_exec() - If pcre_exec() fails, it returns a negative number. The following are + If pcre_exec() fails, it returns a negative number. The following are defined in the header file: PCRE_ERROR_NOMATCH (-1) @@ -2390,7 +2862,7 @@ PCRE_ERROR_NULL (-2) - Either code or subject was passed as NULL, or ovector was NULL and + Either code or subject was passed as NULL, or ovector was NULL and ovecsize was not zero. PCRE_ERROR_BADOPTION (-3) @@ -2399,76 +2871,82 @@ PCRE_ERROR_BADMAGIC (-4) - PCRE stores a 4-byte "magic number" at the start of the compiled code, + PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch the case when it is passed a junk pointer and to detect when a pattern that was compiled in an environment of one endianness is run in - an environment with the other endianness. This is the error that PCRE + an environment with the other endianness. This is the error that PCRE gives when the magic number is not present. PCRE_ERROR_UNKNOWN_OPCODE (-5) While running the pattern match, an unknown item was encountered in the - compiled pattern. This error could be caused by a bug in PCRE or by + compiled pattern. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. PCRE_ERROR_NOMEMORY (-6) - If a pattern contains back references, but the ovector that is passed + If a pattern contains back references, but the ovector that is passed to pcre_exec() is not big enough to remember the referenced substrings, - PCRE gets a block of memory at the start of matching to use for this - purpose. If the call via pcre_malloc() fails, this error is given. The + PCRE gets a block of memory at the start of matching to use for this + purpose. If the call via pcre_malloc() fails, this error is given. The memory is automatically freed at the end of matching. - This error is also given if pcre_stack_malloc() fails in pcre_exec(). - This can happen only when PCRE has been compiled with --disable-stack- + This error is also given if pcre_stack_malloc() fails in pcre_exec(). + This can happen only when PCRE has been compiled with --disable-stack- for-recursion. PCRE_ERROR_NOSUBSTRING (-7) - This error is used by the pcre_copy_substring(), pcre_get_substring(), + This error is used by the pcre_copy_substring(), pcre_get_substring(), and pcre_get_substring_list() functions (see below). It is never returned by pcre_exec(). PCRE_ERROR_MATCHLIMIT (-8) - The backtracking limit, as specified by the match_limit field in a - pcre_extra structure (or defaulted) was reached. See the description + The backtracking limit, as specified by the match_limit field in a + pcre_extra structure (or defaulted) was reached. See the description above. PCRE_ERROR_CALLOUT (-9) This error is never generated by pcre_exec() itself. It is provided for - use by callout functions that want to yield a distinctive error code. + use by callout functions that want to yield a distinctive error code. See the pcrecallout documentation for details. PCRE_ERROR_BADUTF8 (-10) - A string that contains an invalid UTF-8 byte sequence was passed as a - subject. However, if PCRE_PARTIAL_HARD is set and the problem is a - truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT- - UTF8 is used instead. + A string that contains an invalid UTF-8 byte sequence was passed as a + subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of + the output vector (ovecsize) is at least 2, the byte offset to the + start of the the invalid UTF-8 character is placed in the first ele- + ment, and a reason code is placed in the second element. The reason + codes are listed in the following section. For backward compatibility, + if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char- + acter at the end of the subject (reason codes 1 to 5), + PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. PCRE_ERROR_BADUTF8_OFFSET (-11) - The UTF-8 byte sequence that was passed as a subject was valid, but the - value of startoffset did not point to the beginning of a UTF-8 charac- + The UTF-8 byte sequence that was passed as a subject was checked and + found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the + value of startoffset did not point to the beginning of a UTF-8 charac- ter or the end of the subject. PCRE_ERROR_PARTIAL (-12) - The subject string did not match, but it did match partially. See the + The subject string did not match, but it did match partially. See the pcrepartial documentation for details of partial matching. PCRE_ERROR_BADPARTIAL (-13) - This code is no longer in use. It was formerly returned when the - PCRE_PARTIAL option was used with a compiled pattern containing items - that were not supported for partial matching. From release 8.00 + This code is no longer in use. It was formerly returned when the + PCRE_PARTIAL option was used with a compiled pattern containing items + that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching. PCRE_ERROR_INTERNAL (-14) - An unexpected internal error has occurred. This error could be caused + An unexpected internal error has occurred. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. PCRE_ERROR_BADCOUNT (-15) @@ -2478,7 +2956,7 @@ PCRE_ERROR_RECURSIONLIMIT (-21) The internal recursion limit, as specified by the match_limit_recursion - field in a pcre_extra structure (or defaulted) was reached. See the + field in a pcre_extra structure (or defaulted) was reached. See the description above. PCRE_ERROR_BADNEWLINE (-23) @@ -2492,11 +2970,118 @@ PCRE_ERROR_SHORTUTF8 (-25) - The subject string ended with an incomplete (truncated) UTF-8 charac- - ter, and the PCRE_PARTIAL_HARD option was set. Without this option, - PCRE_ERROR_BADUTF8 is returned in this situation. + This error is returned instead of PCRE_ERROR_BADUTF8 when the subject + string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD + option is set. Information about the failure is returned as for + PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but + this special error code for PCRE_PARTIAL_HARD precedes the implementa- + tion of returned information; it is retained for backwards compatibil- + ity. + + PCRE_ERROR_RECURSELOOP (-26) + + This error is returned when pcre_exec() detects a recursion loop within + the pattern. Specifically, it means that either the whole pattern or a + subpattern has been called recursively for the second time at the same + position in the subject string. Some simple patterns that might do this + are detected and faulted at compile time, but more complicated cases, + in particular mutual recursions between two different subpatterns, can- + not be detected until run time. + + PCRE_ERROR_JIT_STACKLIMIT (-27) + + This error is returned when a pattern that was successfully studied + using a JIT compile option is being matched, but the memory available + for the just-in-time processing stack is not large enough. See the + pcrejit documentation for more details. + + PCRE_ERROR_BADMODE (-28) + + This error is given if a pattern that was compiled by the 8-bit library + is passed to a 16-bit library function, or vice versa. + + PCRE_ERROR_BADENDIANNESS (-29) + + This error is given if a pattern that was compiled and saved is + reloaded on a host with different endianness. The utility function + pcre_pattern_to_host_byte_order() can be used to convert such a pattern + so that it runs on the new host. + + Error numbers -16 to -20, -22, and -30 are not used by pcre_exec(). + + Reason codes for invalid UTF-8 strings + + This section applies only to the 8-bit library. The corresponding + information for the 16-bit library is given in the pcre16 page. + + When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT- + UTF8, and the size of the output vector (ovecsize) is at least 2, the + offset of the start of the invalid UTF-8 character is placed in the + first output vector element (ovector[0]) and a reason code is placed in + the second element (ovector[1]). The reason codes are given names in + the pcre.h header file: + + PCRE_UTF8_ERR1 + PCRE_UTF8_ERR2 + PCRE_UTF8_ERR3 + PCRE_UTF8_ERR4 + PCRE_UTF8_ERR5 + + The string ends with a truncated UTF-8 character; the code specifies + how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 + characters to be no longer than 4 bytes, the encoding scheme (origi- + nally defined by RFC 2279) allows for up to 6 bytes, and this is + checked first; hence the possibility of 4 or 5 missing bytes. + + PCRE_UTF8_ERR6 + PCRE_UTF8_ERR7 + PCRE_UTF8_ERR8 + PCRE_UTF8_ERR9 + PCRE_UTF8_ERR10 + + The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of + the character do not have the binary value 0b10 (that is, either the + most significant bit is 0, or the next bit is 1). + + PCRE_UTF8_ERR11 + PCRE_UTF8_ERR12 + + A character that is valid by the RFC 2279 rules is either 5 or 6 bytes + long; these code points are excluded by RFC 3629. + + PCRE_UTF8_ERR13 + + A 4-byte character has a value greater than 0x10fff; these code points + are excluded by RFC 3629. + + PCRE_UTF8_ERR14 + + A 3-byte character has a value in the range 0xd800 to 0xdfff; this + range of code points are reserved by RFC 3629 for use with UTF-16, and + so are excluded from UTF-8. + + PCRE_UTF8_ERR15 + PCRE_UTF8_ERR16 + PCRE_UTF8_ERR17 + PCRE_UTF8_ERR18 + PCRE_UTF8_ERR19 + + A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes + for a value that can be represented by fewer bytes, which is invalid. + For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- + rect coding uses just one byte. + + PCRE_UTF8_ERR20 + + The two most significant bits of the first byte of a character have the + binary value 0b10 (that is, the most significant bit is 1 and the sec- + ond is 0). Such a byte can only validly occur as the second or subse- + quent byte of a multi-byte character. - Error numbers -16 to -20 and -22 are not used by pcre_exec(). + PCRE_UTF8_ERR21 + + The first byte of a character has the value 0xfe or 0xff. These values + can never occur in a valid UTF-8 string. EXTRACTING CAPTURED SUBSTRINGS BY NUMBER @@ -2512,78 +3097,78 @@ int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr); - Captured substrings can be accessed directly by using the offsets - returned by pcre_exec() in ovector. For convenience, the functions + Captured substrings can be accessed directly by using the offsets + returned by pcre_exec() in ovector. For convenience, the functions pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub- - string_list() are provided for extracting captured substrings as new, - separate, zero-terminated strings. These functions identify substrings - by number. The next section describes functions for extracting named + string_list() are provided for extracting captured substrings as new, + separate, zero-terminated strings. These functions identify substrings + by number. The next section describes functions for extracting named substrings. - A substring that contains a binary zero is correctly extracted and has - a further zero added on the end, but the result is not, of course, a C - string. However, you can process such a string by referring to the - length that is returned by pcre_copy_substring() and pcre_get_sub- + A substring that contains a binary zero is correctly extracted and has + a further zero added on the end, but the result is not, of course, a C + string. However, you can process such a string by referring to the + length that is returned by pcre_copy_substring() and pcre_get_sub- string(). Unfortunately, the interface to pcre_get_substring_list() is - not adequate for handling strings containing binary zeros, because the + not adequate for handling strings containing binary zeros, because the end of the final string is not independently indicated. - The first three arguments are the same for all three of these func- - tions: subject is the subject string that has just been successfully + The first three arguments are the same for all three of these func- + tions: subject is the subject string that has just been successfully matched, ovector is a pointer to the vector of integer offsets that was passed to pcre_exec(), and stringcount is the number of substrings that - were captured by the match, including the substring that matched the + were captured by the match, including the substring that matched the entire regular expression. This is the value returned by pcre_exec() if - it is greater than zero. If pcre_exec() returned zero, indicating that - it ran out of space in ovector, the value passed as stringcount should + it is greater than zero. If pcre_exec() returned zero, indicating that + it ran out of space in ovector, the value passed as stringcount should be the number of elements in the vector divided by three. - The functions pcre_copy_substring() and pcre_get_substring() extract a - single substring, whose number is given as stringnumber. A value of - zero extracts the substring that matched the entire pattern, whereas - higher values extract the captured substrings. For pcre_copy_sub- - string(), the string is placed in buffer, whose length is given by - buffersize, while for pcre_get_substring() a new block of memory is - obtained via pcre_malloc, and its address is returned via stringptr. - The yield of the function is the length of the string, not including + The functions pcre_copy_substring() and pcre_get_substring() extract a + single substring, whose number is given as stringnumber. A value of + zero extracts the substring that matched the entire pattern, whereas + higher values extract the captured substrings. For pcre_copy_sub- + string(), the string is placed in buffer, whose length is given by + buffersize, while for pcre_get_substring() a new block of memory is + obtained via pcre_malloc, and its address is returned via stringptr. + The yield of the function is the length of the string, not including the terminating zero, or one of these error codes: PCRE_ERROR_NOMEMORY (-6) - The buffer was too small for pcre_copy_substring(), or the attempt to + The buffer was too small for pcre_copy_substring(), or the attempt to get memory failed for pcre_get_substring(). PCRE_ERROR_NOSUBSTRING (-7) There is no substring whose number is stringnumber. - The pcre_get_substring_list() function extracts all available sub- - strings and builds a list of pointers to them. All this is done in a + The pcre_get_substring_list() function extracts all available sub- + strings and builds a list of pointers to them. All this is done in a single block of memory that is obtained via pcre_malloc. The address of - the memory block is returned via listptr, which is also the start of - the list of string pointers. The end of the list is marked by a NULL - pointer. The yield of the function is zero if all went well, or the + the memory block is returned via listptr, which is also the start of + the list of string pointers. The end of the list is marked by a NULL + pointer. The yield of the function is zero if all went well, or the error code PCRE_ERROR_NOMEMORY (-6) if the attempt to get the memory block failed. - When any of these functions encounter a substring that is unset, which - can happen when capturing subpattern number n+1 matches some part of - the subject, but subpattern n has not been used at all, they return an + When any of these functions encounter a substring that is unset, which + can happen when capturing subpattern number n+1 matches some part of + the subject, but subpattern n has not been used at all, they return an empty string. This can be distinguished from a genuine zero-length sub- - string by inspecting the appropriate offset in ovector, which is nega- + string by inspecting the appropriate offset in ovector, which is nega- tive for unset substrings. - The two convenience functions pcre_free_substring() and pcre_free_sub- - string_list() can be used to free the memory returned by a previous + The two convenience functions pcre_free_substring() and pcre_free_sub- + string_list() can be used to free the memory returned by a previous call of pcre_get_substring() or pcre_get_substring_list(), respec- - tively. They do nothing more than call the function pointed to by - pcre_free, which of course could be called directly from a C program. - However, PCRE is used in some situations where it is linked via a spe- - cial interface to another programming language that cannot use - pcre_free directly; it is for these cases that the functions are pro- + tively. They do nothing more than call the function pointed to by + pcre_free, which of course could be called directly from a C program. + However, PCRE is used in some situations where it is linked via a spe- + cial interface to another programming language that cannot use + pcre_free directly; it is for these cases that the functions are pro- vided. @@ -2602,7 +3187,7 @@ int stringcount, const char *stringname, const char **stringptr); - To extract a substring by name, you first have to find associated num- + To extract a substring by name, you first have to find associated num- ber. For example, for this pattern (a+)b(?\d+)... @@ -2611,35 +3196,35 @@ be unique (PCRE_DUPNAMES was not set), you can find the number from the name by calling pcre_get_stringnumber(). The first argument is the com- piled pattern, and the second is the name. The yield of the function is - the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no + the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no subpattern of that name. Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job. - Most of the arguments of pcre_copy_named_substring() and - pcre_get_named_substring() are the same as those for the similarly - named functions that extract by number. As these are described in the - previous section, they are not re-described here. There are just two + Most of the arguments of pcre_copy_named_substring() and + pcre_get_named_substring() are the same as those for the similarly + named functions that extract by number. As these are described in the + previous section, they are not re-described here. There are just two differences: - First, instead of a substring number, a substring name is given. Sec- + First, instead of a substring number, a substring name is given. Sec- ond, there is an extra argument, given at the start, which is a pointer - to the compiled pattern. This is needed in order to gain access to the + to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. - These functions call pcre_get_stringnumber(), and if it succeeds, they - then call pcre_copy_substring() or pcre_get_substring(), as appropri- - ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the + These functions call pcre_get_stringnumber(), and if it succeeds, they + then call pcre_copy_substring() or pcre_get_substring(), as appropri- + ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). Warning: If the pattern uses the (?| feature to set up multiple subpat- - terns with the same number, as described in the section on duplicate - subpattern numbers in the pcrepattern page, you cannot use names to - distinguish the different subpatterns, because names are not included - in the compiled code. The matching process uses only numbers. For this - reason, the use of different names for subpatterns of the same number + terns with the same number, as described in the section on duplicate + subpattern numbers in the pcrepattern page, you cannot use names to + distinguish the different subpatterns, because names are not included + in the compiled code. The matching process uses only numbers. For this + reason, the use of different names for subpatterns of the same number causes an error at compile time. @@ -2648,54 +3233,79 @@ int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last); - When a pattern is compiled with the PCRE_DUPNAMES option, names for - subpatterns are not required to be unique. (Duplicate names are always - allowed for subpatterns with the same number, created by using the (?| - feature. Indeed, if such subpatterns are named, they are required to + When a pattern is compiled with the PCRE_DUPNAMES option, names for + subpatterns are not required to be unique. (Duplicate names are always + allowed for subpatterns with the same number, created by using the (?| + feature. Indeed, if such subpatterns are named, they are required to use the same names.) Normally, patterns with duplicate names are such that in any one match, - only one of the named subpatterns participates. An example is shown in + only one of the named subpatterns participates. An example is shown in the pcrepattern documentation. - When duplicates are present, pcre_copy_named_substring() and - pcre_get_named_substring() return the first substring corresponding to - the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING - (-7) is returned; no data is returned. The pcre_get_stringnumber() - function returns one of the numbers that are associated with the name, + When duplicates are present, pcre_copy_named_substring() and + pcre_get_named_substring() return the first substring corresponding to + the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING + (-7) is returned; no data is returned. The pcre_get_stringnumber() + function returns one of the numbers that are associated with the name, but it is not defined which it is. - If you want to get full details of all captured substrings for a given - name, you must use the pcre_get_stringtable_entries() function. The + If you want to get full details of all captured substrings for a given + name, you must use the pcre_get_stringtable_entries() function. The first argument is the compiled pattern, and the second is the name. The - third and fourth are pointers to variables which are updated by the + third and fourth are pointers to variables which are updated by the function. After it has run, they point to the first and last entries in - the name-to-number table for the given name. The function itself - returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if - there are none. The format of the table is described above in the sec- - tion entitled Information about a pattern. Given all the relevant - entries for the name, you can extract each of their numbers, and hence - the captured data, if any. + the name-to-number table for the given name. The function itself + returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if + there are none. The format of the table is described above in the sec- + tion entitled Information about a pattern above. Given all the rele- + vant entries for the name, you can extract each of their numbers, and + hence the captured data, if any. FINDING ALL POSSIBLE MATCHES - The traditional matching function uses a similar algorithm to Perl, + The traditional matching function uses a similar algorithm to Perl, which stops when it finds the first match, starting at a given point in - the subject. If you want to find all possible matches, or the longest - possible match, consider using the alternative matching function (see - below) instead. If you cannot use the alternative function, but still - need to find all possible matches, you can kludge it up by making use + the subject. If you want to find all possible matches, or the longest + possible match, consider using the alternative matching function (see + below) instead. If you cannot use the alternative function, but still + need to find all possible matches, you can kludge it up by making use of the callout facility, which is described in the pcrecallout documen- tation. What you have to do is to insert a callout right at the end of the pat- - tern. When your callout function is called, extract and save the cur- - rent matched substring. Then return 1, which forces pcre_exec() to - backtrack and try other alternatives. Ultimately, when it runs out of + tern. When your callout function is called, extract and save the cur- + rent matched substring. Then return 1, which forces pcre_exec() to + backtrack and try other alternatives. Ultimately, when it runs out of matches, pcre_exec() will yield PCRE_ERROR_NOMATCH. +OBTAINING AN ESTIMATE OF STACK USAGE + + Matching certain patterns using pcre_exec() can use a lot of process + stack, which in certain environments can be rather limited in size. + Some users find it helpful to have an estimate of the amount of stack + that is used by pcre_exec(), to help them set recursion limits, as + described in the pcrestack documentation. The estimate that is output + by pcretest when called with the -m and -C options is obtained by call- + ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its + first five arguments. + + Normally, if its first argument is NULL, pcre_exec() immediately + returns the negative error code PCRE_ERROR_NULL, but with this special + combination of arguments, it returns instead a negative number whose + absolute value is the approximate stack frame size in bytes. (A nega- + tive number is used so that it is clear that no match has happened.) + The value is approximate because in some cases, recursive calls to + pcre_exec() occur when there are one or two additional variables on the + stack. + + If PCRE has been compiled to use the heap instead of the stack for + recursion, the value returned is the size of each block that is + obtained from the heap. + + MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int pcre_dfa_exec(const pcre *code, const pcre_extra *extra, @@ -2703,26 +3313,26 @@ int options, int *ovector, int ovecsize, int *workspace, int wscount); - The function pcre_dfa_exec() is called to match a subject string - against a compiled pattern, using a matching algorithm that scans the - subject string just once, and does not backtrack. This has different - characteristics to the normal algorithm, and is not compatible with - Perl. Some of the features of PCRE patterns are not supported. Never- - theless, there are times when this kind of matching can be useful. For - a discussion of the two matching algorithms, and a list of features - that pcre_dfa_exec() does not support, see the pcrematching documenta- + The function pcre_dfa_exec() is called to match a subject string + against a compiled pattern, using a matching algorithm that scans the + subject string just once, and does not backtrack. This has different + characteristics to the normal algorithm, and is not compatible with + Perl. Some of the features of PCRE patterns are not supported. Never- + theless, there are times when this kind of matching can be useful. For + a discussion of the two matching algorithms, and a list of features + that pcre_dfa_exec() does not support, see the pcrematching documenta- tion. - The arguments for the pcre_dfa_exec() function are the same as for + The arguments for the pcre_dfa_exec() function are the same as for pcre_exec(), plus two extras. The ovector argument is used in a differ- - ent way, and this is described below. The other common arguments are - used in the same way as for pcre_exec(), so their description is not + ent way, and this is described below. The other common arguments are + used in the same way as for pcre_exec(), so their description is not repeated here. - The two additional arguments provide workspace for the function. The - workspace vector should contain at least 20 elements. It is used for + The two additional arguments provide workspace for the function. The + workspace vector should contain at least 20 elements. It is used for keeping track of multiple paths through the pattern tree. More - workspace will be needed for patterns and subjects where there are a + workspace will be needed for patterns and subjects where there are a lot of potential matches. Here is an example of a simple call to pcre_dfa_exec(): @@ -2744,55 +3354,55 @@ Option bits for pcre_dfa_exec() - The unused bits of the options argument for pcre_dfa_exec() must be - zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- + The unused bits of the options argument for pcre_dfa_exec() must be + zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, - PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, - PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- - TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last - four of these are exactly the same as for pcre_exec(), so their + PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, + PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- + TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last + four of these are exactly the same as for pcre_exec(), so their description is not repeated here. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These have the same general effect as they do for pcre_exec(), but the - details are slightly different. When PCRE_PARTIAL_HARD is set for - pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- - ject is reached and there is still at least one matching possibility + These have the same general effect as they do for pcre_exec(), but the + details are slightly different. When PCRE_PARTIAL_HARD is set for + pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- + ject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, the return code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end - of the subject is reached, there have been no complete matches, but - there is still at least one matching possibility. The portion of the - string that was inspected when the longest partial match was found is - set as the first matching string in both cases. There is a more - detailed discussion of partial and multi-segment matching, with exam- + of the subject is reached, there have been no complete matches, but + there is still at least one matching possibility. The portion of the + string that was inspected when the longest partial match was found is + set as the first matching string in both cases. There is a more + detailed discussion of partial and multi-segment matching, with exam- ples, in the pcrepartial documentation. PCRE_DFA_SHORTEST - Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to + Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to stop as soon as it has found one match. Because of the way the alterna- - tive algorithm works, this is necessarily the shortest possible match + tive algorithm works, this is necessarily the shortest possible match at the first possible matching point in the subject string. PCRE_DFA_RESTART When pcre_dfa_exec() returns a partial match, it is possible to call it - again, with additional subject characters, and have it continue with - the same match. The PCRE_DFA_RESTART option requests this action; when - it is set, the workspace and wscount options must reference the same - vector as before because data about the match so far is left in them + again, with additional subject characters, and have it continue with + the same match. The PCRE_DFA_RESTART option requests this action; when + it is set, the workspace and wscount options must reference the same + vector as before because data about the match so far is left in them after a partial match. There is more discussion of this facility in the pcrepartial documentation. Successful returns from pcre_dfa_exec() - When pcre_dfa_exec() succeeds, it may have matched more than one sub- + When pcre_dfa_exec() succeeds, it may have matched more than one sub- string in the subject. Note, however, that all the matches from one run - of the function start at the same point in the subject. The shorter - matches are all initial substrings of the longer matches. For example, + of the function start at the same point in the subject. The shorter + matches are all initial substrings of the longer matches. For example, if the pattern <.*> @@ -2807,19 +3417,20 @@ - On success, the yield of the function is a number greater than zero, - which is the number of matched substrings. The substrings themselves - are returned in ovector. Each string uses two elements; the first is - the offset to the start, and the second is the offset to the end. In - fact, all the strings have the same start offset. (Space could have - been saved by giving this only once, but it was decided to retain some - compatibility with the way pcre_exec() returns data, even though the + On success, the yield of the function is a number greater than zero, + which is the number of matched substrings. The substrings themselves + are returned in ovector. Each string uses two elements; the first is + the offset to the start, and the second is the offset to the end. In + fact, all the strings have the same start offset. (Space could have + been saved by giving this only once, but it was decided to retain some + compatibility with the way pcre_exec() returns data, even though the meaning of the strings is different.) The strings are returned in reverse order of length; that is, the long- - est matching string is given first. If there were too many matches to - fit into ovector, the yield of the function is zero, and the vector is - filled with the longest matches. + est matching string is given first. If there were too many matches to + fit into ovector, the yield of the function is zero, and the vector is + filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() + can use the entire ovector for returning matched strings. Error returns from pcre_dfa_exec() @@ -2843,26 +3454,35 @@ PCRE_ERROR_DFA_UMLIMIT (-18) This return is given if pcre_dfa_exec() is called with an extra block - that contains a setting of the match_limit field. This is not supported - (it is meaningless). + that contains a setting of the match_limit or match_limit_recursion + fields. This is not supported (these fields are meaningless for DFA + matching). PCRE_ERROR_DFA_WSSIZE (-19) - This return is given if pcre_dfa_exec() runs out of space in the + This return is given if pcre_dfa_exec() runs out of space in the workspace vector. PCRE_ERROR_DFA_RECURSE (-20) - When a recursive subpattern is processed, the matching function calls - itself recursively, using private vectors for ovector and workspace. - This error is given if the output vector is not large enough. This + When a recursive subpattern is processed, the matching function calls + itself recursively, using private vectors for ovector and workspace. + This error is given if the output vector is not large enough. This should be extremely rare, as a vector of size 1000 is used. + PCRE_ERROR_DFA_BADRESTART (-30) + + When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some + plausibility checks are made on the contents of the workspace, which + should contain data about the previous partial match. If any of these + checks fail, this error is given. + SEE ALSO - pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepar- - tial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3). + pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematch- + ing(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3), + pcrestack(3). AUTHOR @@ -2874,8 +3494,8 @@ REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 17 June 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -2890,24 +3510,27 @@ int (*pcre_callout)(pcre_callout_block *); + int (*pcre16_callout)(pcre16_callout_block *); + PCRE provides a feature called "callout", which is a means of temporar- ily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting - its entry point in the global variable pcre_callout. By default, this - variable contains NULL, which disables all calling out. - - Within a regular expression, (?C) indicates the points at which the - external function is to be called. Different callout points can be - identified by putting a number less than 256 after the letter C. The - default value is zero. For example, this pattern has two callout + its entry point in the global variable pcre_callout (pcre16_callout for + the 16-bit library). By default, this variable contains NULL, which + disables all calling out. + + Within a regular expression, (?C) indicates the points at which the + external function is to be called. Different callout points can be + identified by putting a number less than 256 after the letter C. The + default value is zero. For example, this pattern has two callout points: (?C1)abc(?C2)def - If the PCRE_AUTO_CALLOUT option bit is set when pcre_compile() or - pcre_compile2() is called, PCRE automatically inserts callouts, all - with number 255, before each item in the pattern. For example, if - PCRE_AUTO_CALLOUT is used with the pattern + If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, + PCRE automatically inserts callouts, all with number 255, before each + item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the + pattern A(\d{2}|--) @@ -2915,62 +3538,68 @@ (?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255) - Notice that there is a callout before and after each parenthesis and - alternation bar. Automatic callouts can be used for tracking the - progress of pattern matching. The pcretest command has an option that - sets automatic callouts; when it is used, the output indicates how the - pattern is matched. This is useful information when you are trying to + Notice that there is a callout before and after each parenthesis and + alternation bar. Automatic callouts can be used for tracking the + progress of pattern matching. The pcretest command has an option that + sets automatic callouts; when it is used, the output indicates how the + pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern. + The use of callouts in a pattern makes it ineligible for optimization + by the just-in-time compiler. Studying such a pattern with the + PCRE_STUDY_JIT_COMPILE option always fails. + MISSING CALLOUTS - You should be aware that, because of optimizations in the way PCRE - matches patterns by default, callouts sometimes do not happen. For + You should be aware that, because of optimizations in the way PCRE + matches patterns by default, callouts sometimes do not happen. For example, if the pattern is ab(?C4)cd PCRE knows that any matching string must contain the letter "d". If the - subject string is "abyz", the lack of "d" means that matching doesn't - ever start, and the callout is never reached. However, with "abyd", + subject string is "abyz", the lack of "d" means that matching doesn't + ever start, and the callout is never reached. However, with "abyd", though the result is still no match, the callout is obeyed. - If the pattern is studied, PCRE knows the minimum length of a matching - string, and will immediately give a "no match" return without actually - running a match if the subject is not long enough, or, for unanchored + If the pattern is studied, PCRE knows the minimum length of a matching + string, and will immediately give a "no match" return without actually + running a match if the subject is not long enough, or, for unanchored patterns, if it has been scanned far enough. - You can disable these optimizations by passing the PCRE_NO_START_OPTI- - MIZE option to pcre_compile(), pcre_exec(), or pcre_dfa_exec(), or by - starting the pattern with (*NO_START_OPT). This slows down the matching - process, but does ensure that callouts such as the example above are - obeyed. + You can disable these optimizations by passing the PCRE_NO_START_OPTI- + MIZE option to the matching function, or by starting the pattern with + (*NO_START_OPT). This slows down the matching process, but does ensure + that callouts such as the example above are obeyed. THE CALLOUT INTERFACE During matching, when PCRE reaches a callout point, the external func- - tion defined by pcre_callout is called (if it is set). This applies to - both the pcre_exec() and the pcre_dfa_exec() matching functions. The - only argument to the callout function is a pointer to a pcre_callout - block. This structure contains the following fields: - - int version; - int callout_number; - int *offset_vector; - const char *subject; - int subject_length; - int start_match; - int current_position; - int capture_top; - int capture_last; - void *callout_data; - int pattern_position; - int next_item_length; + tion defined by pcre_callout or pcre16_callout is called (if it is + set). This applies to both normal and DFA matching. The only argument + to the callout function is a pointer to a pcre_callout or pcre16_call- + out block. These structures contains the following fields: + + int version; + int callout_number; + int *offset_vector; + const char *subject; (8-bit version) + PCRE_SPTR16 subject; (16-bit version) + int subject_length; + int start_match; + int current_position; + int capture_top; + int capture_last; + void *callout_data; + int pattern_position; + int next_item_length; + const unsigned char *mark; (8-bit version) + const PCRE_UCHAR16 *mark; (16-bit version) The version field is an integer containing the version number of the - block format. The initial version was 0; the current version is 1. The + block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. @@ -2979,14 +3608,14 @@ outs, and 255 for automatically generated callouts). The offset_vector field is a pointer to the vector of offsets that was - passed by the caller to pcre_exec() or pcre_dfa_exec(). When - pcre_exec() is used, the contents can be inspected in order to extract - substrings that have been matched so far, in the same way as for - extracting substrings after a match has completed. For pcre_dfa_exec() - this field is not useful. + passed by the caller to the matching function. When pcre_exec() or + pcre16_exec() is used, the contents can be inspected, in order to + extract substrings that have been matched so far, in the same way as + for extracting substrings after a match has completed. For the DFA + matching functions, this field is not useful. The subject and subject_length fields contain copies of the values that - were passed to pcre_exec(). + were passed to the matching function. The start_match field normally contains the offset within the subject at which the current match attempt started. However, if the escape @@ -2998,38 +3627,46 @@ The current_position field contains the offset within the subject of the current match pointer. - When the pcre_exec() function is used, the capture_top field contains - one more than the number of the highest numbered captured substring so - far. If no substrings have been captured, the value of capture_top is - one. This is always the case when pcre_dfa_exec() is used, because it - does not support captured substrings. + When the pcre_exec() or pcre16_exec() is used, the capture_top field + contains one more than the number of the highest numbered captured sub- + string so far. If no substrings have been captured, the value of cap- + ture_top is one. This is always the case when the DFA functions are + used, because they do not support captured substrings. The capture_last field contains the number of the most recently cap- tured substring. If no substrings have been captured, its value is -1. - This is always the case when pcre_dfa_exec() is used. + This is always the case for the DFA matching functions. - The callout_data field contains a value that is passed to pcre_exec() - or pcre_dfa_exec() specifically so that it can be passed back in call- - outs. It is passed in the pcre_callout field of the pcre_extra data + The callout_data field contains a value that is passed to a matching + function specifically so that it can be passed back in callouts. It is + passed in the callout_data field of a pcre_extra or pcre16_extra data structure. If no such data was passed, the value of callout_data in a - pcre_callout block is NULL. There is a description of the pcre_extra - structure in the pcreapi documentation. + callout block is NULL. There is a description of the pcre_extra struc- + ture in the pcreapi documentation. - The pattern_position field is present from version 1 of the pcre_call- - out structure. It contains the offset to the next item to be matched in - the pattern string. - - The next_item_length field is present from version 1 of the pcre_call- - out structure. It contains the length of the next item to be matched in - the pattern string. When the callout immediately precedes an alterna- - tion bar, a closing parenthesis, or the end of the pattern, the length - is zero. When the callout precedes an opening parenthesis, the length - is that of the entire subpattern. + The pattern_position field is present from version 1 of the callout + structure. It contains the offset to the next item to be matched in the + pattern string. + + The next_item_length field is present from version 1 of the callout + structure. It contains the length of the next item to be matched in the + pattern string. When the callout immediately precedes an alternation + bar, a closing parenthesis, or the end of the pattern, the length is + zero. When the callout precedes an opening parenthesis, the length is + that of the entire subpattern. The pattern_position and next_item_length fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts. + The mark field is present from version 2 of the callout structure. In + callouts from pcre_exec() or pcre16_exec() it contains a pointer to the + zero-terminated name of the most recently passed (*MARK), (*PRUNE), or + (*THEN) item in the match, or NULL if no such items have been passed. + Instances of (*PRUNE) or (*THEN) without a name do not obliterate a + previous (*MARK). In callouts from the DFA matching functions this + field always contains NULL. + RETURN VALUES @@ -3037,8 +3674,8 @@ is zero, matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had - failed. If the value is less than zero, the match is abandoned, and - pcre_exec() or pcre_dfa_exec() returns the negative value. + failed. If the value is less than zero, the match is abandoned, the + matching function returns the negative value. Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a stan- @@ -3056,8 +3693,8 @@ REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 08 Janurary 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -3074,43 +3711,53 @@ handle regular expressions. The differences described here are with respect to Perl versions 5.10 and above. - 1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details - of what it does have are given in the section on UTF-8 support in the - main pcre page. - - 2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl - permits them, but they do not mean what you might think. For example, - (?!a){3} does not assert that the next three characters are not "a". It - just asserts that the next character is not "a" three times. - - 3. Capturing subpatterns that occur inside negative lookahead asser- - tions are counted, but their entries in the offsets vector are never - set. Perl sets its numerical variables from any such patterns that are + 1. PCRE has only a subset of Perl's Unicode support. Details of what it + does have are given in the pcreunicode page. + + 2. PCRE allows repeat quantifiers only on parenthesized assertions, but + they do not mean what you might think. For example, (?!a){3} does not + assert that the next three characters are not "a". It just asserts that + the next character is not "a" three times (in principle: PCRE optimizes + this to run the assertion just once). Perl allows repeat quantifiers on + other assertions such as \b, but these do not seem to have any use. + + 3. Capturing subpatterns that occur inside negative lookahead asser- + tions are counted, but their entries in the offsets vector are never + set. Perl sets its numerical variables from any such patterns that are matched before the assertion fails to match something (thereby succeed- - ing), but only if the negative lookahead assertion contains just one + ing), but only if the negative lookahead assertion contains just one branch. - 4. Though binary zero characters are supported in the subject string, + 4. Though binary zero characters are supported in the subject string, they are not allowed in a pattern string because it is passed as a nor- mal C string, terminated by zero. The escape sequence \0 can be used in the pattern to represent a binary zero. - 5. The following Perl escape sequences are not supported: \l, \u, \L, - \U, and \N. In fact these are implemented by Perl's general string-han- - dling and are not part of its pattern matching engine. If any of these - are encountered by PCRE, an error is generated. - - 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE - is built with Unicode character property support. The properties that - can be tested with \p and \P are limited to the general category prop- - erties such as Lu and Nd, script names such as Greek or Han, and the - derived properties Any and L&. PCRE does support the Cs (surrogate) - property, which Perl does not; the Perl documentation says "Because + 5. The following Perl escape sequences are not supported: \l, \u, \L, + \U, and \N when followed by a character name or Unicode value. (\N on + its own, matching a non-newline character, is supported.) In fact these + are implemented by Perl's general string-handling and are not part of + its pattern matching engine. If any of these are encountered by PCRE, + an error is generated by default. However, if the PCRE_JAVASCRIPT_COM- + PAT option is set, \U and \u are interpreted as JavaScript interprets + them. + + 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE + is built with Unicode character property support. The properties that + can be tested with \p and \P are limited to the general category prop- + erties such as Lu and Nd, script names such as Greek or Han, and the + derived properties Any and L&. PCRE does support the Cs (surrogate) + property, which Perl does not; the Perl documentation says "Because Perl hides the need for the user to understand the internal representa- - tion of Unicode characters, there is no need to implement the somewhat + tion of Unicode characters, there is no need to implement the somewhat messy concept of surrogates." - 7. PCRE does support the \Q...\E escape for quoting substrings. Charac- + 7. PCRE implements a simpler version of \X than Perl, which changed to + make \X match what Unicode calls an "extended grapheme cluster". This + is more complicated than an extended Unicode sequence, which is what + PCRE matches. + + 8. PCRE does support the \Q...\E escape for quoting substrings. Charac- ters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE @@ -3126,55 +3773,70 @@ The \Q...\E sequence is recognized both inside and outside character classes. - 8. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) + 9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pat- tern matching. See the pcrecallout documentation for details. - 9. Subpatterns that are called recursively or as "subroutines" are - always treated as atomic groups in PCRE. This is like Python, but - unlike Perl. There is a discussion of an example that explains this in - more detail in the section on recursion differences from Perl in the - pcrepattern page. - - 10. There are some differences that are concerned with the settings of - captured strings when part of a pattern is repeated. For example, - matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 + 10. Subpatterns that are called as subroutines (whether or not recur- + sively) are always treated as atomic groups in PCRE. This is like + Python, but unlike Perl. Captured values that are set outside a sub- + routine call can be reference from inside in PCRE, but not in Perl. + There is a discussion that explains these differences in more detail in + the section on recursion differences from Perl in the pcrepattern page. + + 11. If any of the backtracking control verbs are used in an assertion + or in a subpattern that is called as a subroutine (whether or not + recursively), their effect is confined to that subpattern; it does not + extend to the surrounding pattern. This is not always the case in Perl. + In particular, if (*THEN) is present in a group that is called as a + subroutine, its action is limited to that group, even if the group does + not contain any | characters. There is one exception to this: the name + from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success- + ful positive assertion is passed back when a match succeeds (compare + capturing parentheses in assertions). Note that such subpatterns are + processed as anchored at the point where they are tested. + + 12. There are some differences that are concerned with the settings of + captured strings when part of a pattern is repeated. For example, + matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". - 11. PCRE's handling of duplicate subpattern numbers and duplicate sub- + 13. PCRE's handling of duplicate subpattern numbers and duplicate sub- pattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external ta- - ble to translate between numbers and names. In particular, a pattern - such as (?|(?A)|(?A)|(?\r\n|\n|\x0b|\f|\r|\x85) This is an example of an "atomic group", details of which are given below. This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, - U+000A), VT (vertical tab, U+000B), FF (formfeed, U+000C), CR (carriage - return, U+000D), or NEL (next line, U+0085). The two-character sequence - is treated as a single unit that cannot be split. + U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (car- + riage return, U+000D), or NEL (next line, U+0085). The two-character + sequence is treated as a single unit that cannot be split. - In UTF-8 mode, two additional characters whose codepoints are greater + In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph sepa- rator, U+2029). Unicode character property support is not needed for these characters to be recognized. @@ -3656,28 +4357,28 @@ (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence - These override the default and the options given to pcre_compile() or - pcre_compile2(), but they can be overridden by options given to - pcre_exec() or pcre_dfa_exec(). Note that these special settings, which - are not Perl-compatible, are recognized only at the very start of a - pattern, and that they must be in upper case. If more than one of them - is present, the last one is used. They can be combined with a change of + These override the default and the options given to the compiling func- + tion, but they can themselves be overridden by options given to a + matching function. Note that these special settings, which are not + Perl-compatible, are recognized only at the very start of a pattern, + and that they must be in upper case. If more than one of them is + present, the last one is used. They can be combined with a change of newline convention; for example, a pattern can start with: (*ANY)(*BSR_ANYCRLF) - They can also be combined with the (*UTF8) or (*UCP) special sequences. - Inside a character class, \R is treated as an unrecognized escape - sequence, and so matches the letter "R" by default, but causes an error - if PCRE_EXTRA is set. + They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special + sequences. Inside a character class, \R is treated as an unrecognized + escape sequence, and so matches the letter "R" by default, but causes + an error if PCRE_EXTRA is set. Unicode character properties When PCRE is built with Unicode character property support, three addi- tional escape sequences that match characters with specific properties - are available. When not in UTF-8 mode, these sequences are of course - limited to testing characters whose codepoints are less than 256, but - they do work in this mode. The extra escape sequences are: + are available. When in 8-bit non-UTF-8 mode, these sequences are of + course limited to testing characters whose codepoints are less than + 256, but they do work in this mode. The extra escape sequences are: \p{xx} a character with the xx property \P{xx} a character without the xx property @@ -3700,20 +4401,22 @@ Those that are not part of an identified script are lumped together as "Common". The current list of scripts is: - Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille, - Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, - Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp- - tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, - Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe- - rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, - Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, - Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, - Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, - Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, - Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian, - Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, - Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, - Ugaritic, Vai, Yi. + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, + Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, + Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, + Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- + tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, + Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, + Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, + Yi. Each character has exactly one Unicode general category property, spec- ified by a two-letter abbreviation. For compatibility with Perl, nega- @@ -3780,45 +4483,50 @@ classified as a modifier or "other". The Cs (Surrogate) property applies only to characters in the range - U+D800 to U+DFFF. Such characters are not valid in UTF-8 strings (see - RFC 3629) and so cannot be tested by PCRE, unless UTF-8 validity check- - ing has been turned off (see the discussion of PCRE_NO_UTF8_CHECK in - the pcreapi page). Perl does not support the Cs property. + U+D800 to U+DFFF. Such characters are not valid in Unicode strings and + so cannot be tested by PCRE, unless UTF validity checking has been + turned off (see the discussion of PCRE_NO_UTF8_CHECK and + PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs + property. - The long synonyms for property names that Perl supports (such as - \p{Letter}) are not supported by PCRE, nor is it permitted to prefix + The long synonyms for property names that Perl supports (such as + \p{Letter}) are not supported by PCRE, nor is it permitted to prefix any of these properties with "Is". No character that is in the Unicode table has the Cn (unassigned) prop- erty. Instead, this property is assumed for any code point that is not in the Unicode table. - Specifying caseless matching does not affect these escape sequences. + Specifying caseless matching does not affect these escape sequences. For example, \p{Lu} always matches only upper case letters. - The \X escape matches any number of Unicode characters that form an + The \X escape matches any number of Unicode characters that form an extended Unicode sequence. \X is equivalent to (?>\PM\pM*) - That is, it matches a character without the "mark" property, followed - by zero or more characters with the "mark" property, and treats the - sequence as an atomic group (see below). Characters with the "mark" - property are typically accents that affect the preceding character. - None of them have codepoints less than 256, so in non-UTF-8 mode \X - matches any one character. + That is, it matches a character without the "mark" property, followed + by zero or more characters with the "mark" property, and treats the + sequence as an atomic group (see below). Characters with the "mark" + property are typically accents that affect the preceding character. + None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode + \X matches any one character. + + Note that recent versions of Perl have changed \X to match what Unicode + calls an "extended grapheme cluster", which has a more complicated def- + inition. - Matching characters by Unicode property is not fast, because PCRE has - to search a structure that contains data for over fifteen thousand + Matching characters by Unicode property is not fast, because PCRE has + to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and - \w do not use Unicode properties in PCRE by default, though you can - make them do so by setting the PCRE_UCP option for pcre_compile() or by - starting the pattern with (*UCP). + \w do not use Unicode properties in PCRE by default, though you can + make them do so by setting the PCRE_UCP option or by starting the pat- + tern with (*UCP). PCRE's additional properties - As well as the standard Unicode properties described in the previous - section, PCRE supports four more that make it possible to convert tra- + As well as the standard Unicode properties described in the previous + section, PCRE supports four more that make it possible to convert tra- ditional escape sequences such as \w and \s and POSIX character classes to use Unicode properties. PCRE uses these non-standard, non-Perl prop- erties internally when PCRE_UCP is set. They are: @@ -3828,40 +4536,40 @@ Xsp Any Perl space character Xwd Any Perl "word" character - Xan matches characters that have either the L (letter) or the N (num- - ber) property. Xps matches the characters tab, linefeed, vertical tab, - formfeed, or carriage return, and any other character that has the Z + Xan matches characters that have either the L (letter) or the N (num- + ber) property. Xps matches the characters tab, linefeed, vertical tab, + form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. Resetting the match start - The escape sequence \K causes any previously matched characters not to + The escape sequence \K causes any previously matched characters not to be included in the final matched sequence. For example, the pattern: foo\Kbar - matches "foobar", but reports that it has matched "bar". This feature - is similar to a lookbehind assertion (described below). However, in - this case, the part of the subject before the real match does not have - to be of fixed length, as lookbehind assertions do. The use of \K does - not interfere with the setting of captured substrings. For example, + matches "foobar", but reports that it has matched "bar". This feature + is similar to a lookbehind assertion (described below). However, in + this case, the part of the subject before the real match does not have + to be of fixed length, as lookbehind assertions do. The use of \K does + not interfere with the setting of captured substrings. For example, when the pattern (foo)\Kbar matches "foobar", the first substring is still set to "foo". - Perl documents that the use of \K within assertions is "not well - defined". In PCRE, \K is acted upon when it occurs inside positive + Perl documents that the use of \K within assertions is "not well + defined". In PCRE, \K is acted upon when it occurs inside positive assertions, but is ignored in negative assertions. Simple assertions - The final use of backslash is for certain simple assertions. An asser- - tion specifies a condition that has to be met at a particular point in - a match, without consuming any characters from the subject string. The - use of subpatterns for more complicated assertions is described below. + The final use of backslash is for certain simple assertions. An asser- + tion specifies a condition that has to be met at a particular point in + a match, without consuming any characters from the subject string. The + use of subpatterns for more complicated assertions is described below. The backslashed assertions are: \b matches at a word boundary @@ -3872,49 +4580,49 @@ \z matches only at the end of the subject \G matches at the first matching position in the subject - Inside a character class, \b has a different meaning; it matches the - backspace character. If any other of these assertions appears in a - character class, by default it matches the corresponding literal char- + Inside a character class, \b has a different meaning; it matches the + backspace character. If any other of these assertions appears in a + character class, by default it matches the corresponding literal char- acter (for example, \B matches the letter B). However, if the - PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- + PCRE_EXTRA option is set, an "invalid escape sequence" error is gener- ated instead. - A word boundary is a position in the subject string where the current - character and the previous character do not both match \w or \W (i.e. - one matches \w and the other matches \W), or the start or end of the - string if the first or last character matches \w, respectively. In - UTF-8 mode, the meanings of \w and \W can be changed by setting the - PCRE_UCP option. When this is done, it also affects \b and \B. Neither - PCRE nor Perl has a separate "start of word" or "end of word" metase- - quence. However, whatever follows \b normally determines which it is. + A word boundary is a position in the subject string where the current + character and the previous character do not both match \w or \W (i.e. + one matches \w and the other matches \W), or the start or end of the + string if the first or last character matches \w, respectively. In a + UTF mode, the meanings of \w and \W can be changed by setting the + PCRE_UCP option. When this is done, it also affects \b and \B. Neither + PCRE nor Perl has a separate "start of word" or "end of word" metase- + quence. However, whatever follows \b normally determines which it is. For example, the fragment \ba matches "a" at the start of a word. - The \A, \Z, and \z assertions differ from the traditional circumflex + The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match - at the very start and end of the subject string, whatever options are - set. Thus, they are independent of multiline mode. These three asser- + at the very start and end of the subject string, whatever options are + set. Thus, they are independent of multiline mode. These three asser- tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which - affect only the behaviour of the circumflex and dollar metacharacters. - However, if the startoffset argument of pcre_exec() is non-zero, indi- + affect only the behaviour of the circumflex and dollar metacharacters. + However, if the startoffset argument of pcre_exec() is non-zero, indi- cating that matching is to start at a point other than the beginning of - the subject, \A can never match. The difference between \Z and \z is + the subject, \A can never match. The difference between \Z and \z is that \Z matches before a newline at the end of the string as well as at the very end, whereas \z matches only at the end. - The \G assertion is true only when the current matching position is at - the start point of the match, as specified by the startoffset argument - of pcre_exec(). It differs from \A when the value of startoffset is - non-zero. By calling pcre_exec() multiple times with appropriate argu- + The \G assertion is true only when the current matching position is at + the start point of the match, as specified by the startoffset argument + of pcre_exec(). It differs from \A when the value of startoffset is + non-zero. By calling pcre_exec() multiple times with appropriate argu- ments, you can mimic Perl's /g option, and it is in this kind of imple- mentation where \G can be useful. - Note, however, that PCRE's interpretation of \G, as the start of the + Note, however, that PCRE's interpretation of \G, as the start of the current match, is subtly different from Perl's, which defines it as the - end of the previous match. In Perl, these can be different when the - previously matched string was empty. Because PCRE does just one match + end of the previous match. In Perl, these can be different when the + previously matched string was empty. Because PCRE does just one match at a time, it cannot reproduce this behaviour. - If all the alternatives of a pattern begin with \G, the expression is + If all the alternatives of a pattern begin with \G, the expression is anchored to the starting match position, and the "anchored" flag is set in the compiled regular expression. @@ -3922,60 +4630,59 @@ CIRCUMFLEX AND DOLLAR Outside a character class, in the default matching mode, the circumflex - character is an assertion that is true only if the current matching - point is at the start of the subject string. If the startoffset argu- - ment of pcre_exec() is non-zero, circumflex can never match if the - PCRE_MULTILINE option is unset. Inside a character class, circumflex + character is an assertion that is true only if the current matching + point is at the start of the subject string. If the startoffset argu- + ment of pcre_exec() is non-zero, circumflex can never match if the + PCRE_MULTILINE option is unset. Inside a character class, circumflex has an entirely different meaning (see below). - Circumflex need not be the first character of the pattern if a number - of alternatives are involved, but it should be the first thing in each - alternative in which it appears if the pattern is ever to match that - branch. If all possible alternatives start with a circumflex, that is, - if the pattern is constrained to match only at the start of the sub- - ject, it is said to be an "anchored" pattern. (There are also other + Circumflex need not be the first character of the pattern if a number + of alternatives are involved, but it should be the first thing in each + alternative in which it appears if the pattern is ever to match that + branch. If all possible alternatives start with a circumflex, that is, + if the pattern is constrained to match only at the start of the sub- + ject, it is said to be an "anchored" pattern. (There are also other constructs that can cause a pattern to be anchored.) - A dollar character is an assertion that is true only if the current - matching point is at the end of the subject string, or immediately + A dollar character is an assertion that is true only if the current + matching point is at the end of the subject string, or immediately before a newline at the end of the string (by default). Dollar need not - be the last character of the pattern if a number of alternatives are - involved, but it should be the last item in any branch in which it + be the last character of the pattern if a number of alternatives are + involved, but it should be the last item in any branch in which it appears. Dollar has no special meaning in a character class. - The meaning of dollar can be changed so that it matches only at the - very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at + The meaning of dollar can be changed so that it matches only at the + very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at compile time. This does not affect the \Z assertion. The meanings of the circumflex and dollar characters are changed if the - PCRE_MULTILINE option is set. When this is the case, a circumflex - matches immediately after internal newlines as well as at the start of - the subject string. It does not match after a newline that ends the - string. A dollar matches before any newlines in the string, as well as - at the very end, when PCRE_MULTILINE is set. When newline is specified - as the two-character sequence CRLF, isolated CR and LF characters do + PCRE_MULTILINE option is set. When this is the case, a circumflex + matches immediately after internal newlines as well as at the start of + the subject string. It does not match after a newline that ends the + string. A dollar matches before any newlines in the string, as well as + at the very end, when PCRE_MULTILINE is set. When newline is specified + as the two-character sequence CRLF, isolated CR and LF characters do not indicate newlines. - For example, the pattern /^abc$/ matches the subject string "def\nabc" - (where \n represents a newline) in multiline mode, but not otherwise. - Consequently, patterns that are anchored in single line mode because - all branches start with ^ are not anchored in multiline mode, and a - match for circumflex is possible when the startoffset argument of - pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if + For example, the pattern /^abc$/ matches the subject string "def\nabc" + (where \n represents a newline) in multiline mode, but not otherwise. + Consequently, patterns that are anchored in single line mode because + all branches start with ^ are not anchored in multiline mode, and a + match for circumflex is possible when the startoffset argument of + pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is set. - Note that the sequences \A, \Z, and \z can be used to match the start - and end of the subject in both modes, and if all branches of a pattern - start with \A it is always anchored, whether or not PCRE_MULTILINE is + Note that the sequences \A, \Z, and \z can be used to match the start + and end of the subject in both modes, and if all branches of a pattern + start with \A it is always anchored, whether or not PCRE_MULTILINE is set. FULL STOP (PERIOD, DOT) AND \N Outside a character class, a dot in the pattern matches any one charac- - ter in the subject string except (by default) a character that signi- - fies the end of a line. In UTF-8 mode, the matched character may be - more than one byte long. + ter in the subject string except (by default) a character that signi- + fies the end of a line. When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does @@ -3995,23 +4702,47 @@ The escape sequence \N behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any - character except one that signifies the end of a line. + character except one that signifies the end of a line. Perl also uses + \N to match characters by name; PCRE does not support this. -MATCHING A SINGLE BYTE +MATCHING A SINGLE DATA UNIT - Outside a character class, the escape sequence \C matches any one byte, - both in and out of UTF-8 mode. Unlike a dot, it always matches any - line-ending characters. The feature is provided in Perl in order to - match individual bytes in UTF-8 mode. Because it breaks up UTF-8 char- - acters into individual bytes, the rest of the string may start with a - malformed UTF-8 character. For this reason, the \C escape sequence is - best avoided. + Outside a character class, the escape sequence \C matches any one data + unit, whether or not a UTF mode is set. In the 8-bit library, one data + unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a + dot, \C always matches line-ending characters. The feature is provided + in Perl in order to match individual bytes in UTF-8 mode, but it is + unclear how it can usefully be used. Because \C breaks up characters + into individual data units, matching one unit with \C in a UTF mode + means that the rest of the string may start with a malformed UTF char- + acter. This has undefined results, because PCRE assumes that it is + dealing with valid UTF strings (and by default it checks this at the + start of processing unless the PCRE_NO_UTF8_CHECK or + PCRE_NO_UTF16_CHECK option is used). PCRE does not allow \C to appear in lookbehind assertions (described - below), because in UTF-8 mode this would make it impossible to calcu- + below) in a UTF mode, because this would make it impossible to calcu- late the length of the lookbehind. + In general, the \C escape sequence is best avoided. However, one way of + using it that avoids the problem of malformed UTF characters is to use + a lookahead to check the length of the next character, as in this pat- + tern, which could be used with a UTF-8 string (ignore white space and + line breaks): + + (?| (?=[\x00-\x7f])(\C) | + (?=[\x80-\x{7ff}])(\C)(\C) | + (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) | + (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C)) + + A group that starts with (?| resets the capturing parentheses numbers + in each alternative (see "Duplicate Subpattern Numbers" below). The + assertions at the start of each branch check the next UTF-8 character + for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The + character's individual bytes are then captured by the appropriate num- + ber of groups. + SQUARE BRACKETS AND CHARACTER CLASSES @@ -4019,109 +4750,109 @@ closing square bracket. A closing square bracket on its own is not spe- cial by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, a lone closing square bracket causes a compile-time error. If a closing - square bracket is required as a member of the class, it should be the - first data character in the class (after an initial circumflex, if + square bracket is required as a member of the class, it should be the + first data character in the class (after an initial circumflex, if present) or escaped with a backslash. - A character class matches a single character in the subject. In UTF-8 - mode, the character may be more than one byte long. A matched character - must be in the set of characters defined by the class, unless the first - character in the class definition is a circumflex, in which case the - subject character must not be in the set defined by the class. If a - circumflex is actually required as a member of the class, ensure it is - not the first character, or escape it with a backslash. + A character class matches a single character in the subject. In a UTF + mode, the character may be more than one data unit long. A matched + character must be in the set of characters defined by the class, unless + the first character in the class definition is a circumflex, in which + case the subject character must not be in the set defined by the class. + If a circumflex is actually required as a member of the class, ensure + it is not the first character, or escape it with a backslash. - For example, the character class [aeiou] matches any lower case vowel, - while [^aeiou] matches any character that is not a lower case vowel. + For example, the character class [aeiou] matches any lower case vowel, + while [^aeiou] matches any character that is not a lower case vowel. Note that a circumflex is just a convenient notation for specifying the - characters that are in the class by enumerating those that are not. A - class that starts with a circumflex is not an assertion; it still con- - sumes a character from the subject string, and therefore it fails if + characters that are in the class by enumerating those that are not. A + class that starts with a circumflex is not an assertion; it still con- + sumes a character from the subject string, and therefore it fails if the current pointer is at the end of the string. - In UTF-8 mode, characters with values greater than 255 can be included - in a class as a literal string of bytes, or by using the \x{ escaping - mechanism. - - When caseless matching is set, any letters in a class represent both - their upper case and lower case versions, so for example, a caseless - [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not - match "A", whereas a caseful version would. In UTF-8 mode, PCRE always - understands the concept of case for characters whose values are less - than 128, so caseless matching is always possible. For characters with - higher values, the concept of case is supported if PCRE is compiled - with Unicode property support, but not otherwise. If you want to use - caseless matching in UTF8-mode for characters 128 and above, you must - ensure that PCRE is compiled with Unicode property support as well as - with UTF-8 support. - - Characters that might indicate line breaks are never treated in any - special way when matching character classes, whatever line-ending - sequence is in use, and whatever setting of the PCRE_DOTALL and + In UTF-8 (UTF-16) mode, characters with values greater than 255 + (0xffff) can be included in a class as a literal string of data units, + or by using the \x{ escaping mechanism. + + When caseless matching is set, any letters in a class represent both + their upper case and lower case versions, so for example, a caseless + [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not + match "A", whereas a caseful version would. In a UTF mode, PCRE always + understands the concept of case for characters whose values are less + than 128, so caseless matching is always possible. For characters with + higher values, the concept of case is supported if PCRE is compiled + with Unicode property support, but not otherwise. If you want to use + caseless matching in a UTF mode for characters 128 and above, you must + ensure that PCRE is compiled with Unicode property support as well as + with UTF support. + + Characters that might indicate line breaks are never treated in any + special way when matching character classes, whatever line-ending + sequence is in use, and whatever setting of the PCRE_DOTALL and PCRE_MULTILINE options is used. A class such as [^a] always matches one of these characters. - The minus (hyphen) character can be used to specify a range of charac- - ters in a character class. For example, [d-m] matches any letter - between d and m, inclusive. If a minus character is required in a - class, it must be escaped with a backslash or appear in a position - where it cannot be interpreted as indicating a range, typically as the + The minus (hyphen) character can be used to specify a range of charac- + ters in a character class. For example, [d-m] matches any letter + between d and m, inclusive. If a minus character is required in a + class, it must be escaped with a backslash or appear in a position + where it cannot be interpreted as indicating a range, typically as the first or last character in the class. It is not possible to have the literal character "]" as the end charac- - ter of a range. A pattern such as [W-]46] is interpreted as a class of - two characters ("W" and "-") followed by a literal string "46]", so it - would match "W46]" or "-46]". However, if the "]" is escaped with a - backslash it is interpreted as the end of range, so [W-\]46] is inter- - preted as a class containing a range followed by two other characters. - The octal or hexadecimal representation of "]" can also be used to end + ter of a range. A pattern such as [W-]46] is interpreted as a class of + two characters ("W" and "-") followed by a literal string "46]", so it + would match "W46]" or "-46]". However, if the "]" is escaped with a + backslash it is interpreted as the end of range, so [W-\]46] is inter- + preted as a class containing a range followed by two other characters. + The octal or hexadecimal representation of "]" can also be used to end a range. - Ranges operate in the collating sequence of character values. They can - also be used for characters specified numerically, for example - [\000-\037]. In UTF-8 mode, ranges can include characters whose values - are greater than 255, for example [\x{100}-\x{2ff}]. + Ranges operate in the collating sequence of character values. They can + also be used for characters specified numerically, for example + [\000-\037]. Ranges can include any characters that are valid for the + current mode. If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent - to [][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if - character tables for a French locale are in use, [\xc8-\xcb] matches - accented E characters in both cases. In UTF-8 mode, PCRE supports the - concept of case for characters with values greater than 128 only when + to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if + character tables for a French locale are in use, [\xc8-\xcb] matches + accented E characters in both cases. In UTF modes, PCRE supports the + concept of case for characters with values greater than 128 only when it is compiled with Unicode property support. - The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, + The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V, \w, and \W may appear in a character class, and add the characters that - they match to the class. For example, [\dABCDEF] matches any hexadeci- - mal digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of - \d, \s, \w and their upper case partners, just as it does when they - appear outside a character class, as described in the section entitled + they match to the class. For example, [\dABCDEF] matches any hexadeci- + mal digit. In UTF modes, the PCRE_UCP option affects the meanings of + \d, \s, \w and their upper case partners, just as it does when they + appear outside a character class, as described in the section entitled "Generic character types" above. The escape sequence \b has a different - meaning inside a character class; it matches the backspace character. - The sequences \B, \N, \R, and \X are not special inside a character - class. Like any other unrecognized escape sequences, they are treated - as the literal characters "B", "N", "R", and "X" by default, but cause + meaning inside a character class; it matches the backspace character. + The sequences \B, \N, \R, and \X are not special inside a character + class. Like any other unrecognized escape sequences, they are treated + as the literal characters "B", "N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is set. - A circumflex can conveniently be used with the upper case character - types to specify a more restricted set of characters than the matching - lower case type. For example, the class [^\W_] matches any letter or + A circumflex can conveniently be used with the upper case character + types to specify a more restricted set of characters than the matching + lower case type. For example, the class [^\W_] matches any letter or digit, but not underscore, whereas [\w] includes underscore. A positive character class should be read as "something OR something OR ..." and a negative class as "NOT something AND NOT something AND NOT ...". - The only metacharacters that are recognized in character classes are - backslash, hyphen (only where it can be interpreted as specifying a - range), circumflex (only at the start), opening square bracket (only - when it can be interpreted as introducing a POSIX class name - see the - next section), and the terminating closing square bracket. However, + The only metacharacters that are recognized in character classes are + backslash, hyphen (only where it can be interpreted as specifying a + range), circumflex (only at the start), opening square bracket (only + when it can be interpreted as introducing a POSIX class name - see the + next section), and the terminating closing square bracket. However, escaping other non-alphanumeric characters does no harm. POSIX CHARACTER CLASSES Perl supports the POSIX notation for character classes. This uses names - enclosed by [: and :] within the enclosing square brackets. PCRE also + enclosed by [: and :] within the enclosing square brackets. PCRE also supports this notation. For example, [01[:alpha:]%] @@ -4144,24 +4875,24 @@ word "word" characters (same as \w) xdigit hexadecimal digits - The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), - and space (32). Notice that this list includes the VT character (code + The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), + and space (32). Notice that this list includes the VT character (code 11). This makes "space" different to \s, which does not include VT (for Perl compatibility). - The name "word" is a Perl extension, and "blank" is a GNU extension - from Perl 5.8. Another Perl extension is negation, which is indicated + The name "word" is a Perl extension, and "blank" is a GNU extension + from Perl 5.8. Another Perl extension is negation, which is indicated by a ^ character after the colon. For example, [12[:^digit:]] - matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the + matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. - By default, in UTF-8 mode, characters with values greater than 128 do - not match any of the POSIX character classes. However, if the PCRE_UCP - option is passed to pcre_compile(), some of the classes are changed so + By default, in UTF modes, characters with values greater than 128 do + not match any of the POSIX character classes. However, if the PCRE_UCP + option is passed to pcre_compile(), some of the classes are changed so that Unicode character properties are used. This is achieved by replac- ing the POSIX classes by other sequences, as follows: @@ -4174,31 +4905,31 @@ [:upper:] becomes \p{Lu} [:word:] becomes \p{Xwd} - Negated versions, such as [:^alpha:] use \P instead of \p. The other + Negated versions, such as [:^alpha:] use \P instead of \p. The other POSIX classes are unchanged, and match only characters with code points less than 128. VERTICAL BAR - Vertical bar characters are used to separate alternative patterns. For + Vertical bar characters are used to separate alternative patterns. For example, the pattern gilbert|sullivan - matches either "gilbert" or "sullivan". Any number of alternatives may - appear, and an empty alternative is permitted (matching the empty + matches either "gilbert" or "sullivan". Any number of alternatives may + appear, and an empty alternative is permitted (matching the empty string). The matching process tries each alternative in turn, from left - to right, and the first one that succeeds is used. If the alternatives - are within a subpattern (defined below), "succeeds" means matching the + to right, and the first one that succeeds is used. If the alternatives + are within a subpattern (defined below), "succeeds" means matching the rest of the main pattern as well as the alternative in the subpattern. INTERNAL OPTION SETTING - The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and - PCRE_EXTENDED options (which are Perl-compatible) can be changed from - within the pattern by a sequence of Perl option letters enclosed + The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and + PCRE_EXTENDED options (which are Perl-compatible) can be changed from + within the pattern by a sequence of Perl option letters enclosed between "(?" and ")". The option letters are i for PCRE_CASELESS @@ -4208,48 +4939,49 @@ For example, (?im) sets caseless, multiline matching. It is also possi- ble to unset these options by preceding the letter with a hyphen, and a - combined setting and unsetting such as (?im-sx), which sets PCRE_CASE- - LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, - is also permitted. If a letter appears both before and after the + combined setting and unsetting such as (?im-sx), which sets PCRE_CASE- + LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, + is also permitted. If a letter appears both before and after the hyphen, the option is unset. - The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA - can be changed in the same way as the Perl-compatible options by using + The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA + can be changed in the same way as the Perl-compatible options by using the characters J, U and X respectively. - When one of these option changes occurs at top level (that is, not - inside subpattern parentheses), the change applies to the remainder of + When one of these option changes occurs at top level (that is, not + inside subpattern parentheses), the change applies to the remainder of the pattern that follows. If the change is placed right at the start of a pattern, PCRE extracts it into the global options (and it will there- fore show up in data extracted by the pcre_fullinfo() function). - An option change within a subpattern (see below for a description of - subpatterns) affects only that part of the subpattern that follows it, + An option change within a subpattern (see below for a description of + subpatterns) affects only that part of the subpattern that follows it, so (a(?i)b)c matches abc and aBc and no other strings (assuming PCRE_CASELESS is not - used). By this means, options can be made to have different settings - in different parts of the pattern. Any changes made in one alternative - do carry on into subsequent branches within the same subpattern. For + used). By this means, options can be made to have different settings + in different parts of the pattern. Any changes made in one alternative + do carry on into subsequent branches within the same subpattern. For example, (a(?i)b|c) - matches "ab", "aB", "c", and "C", even though when matching "C" the - first branch is abandoned before the option setting. This is because - the effects of option settings happen at compile time. There would be + matches "ab", "aB", "c", and "C", even though when matching "C" the + first branch is abandoned before the option setting. This is because + the effects of option settings happen at compile time. There would be some very weird behaviour otherwise. - Note: There are other PCRE-specific options that can be set by the - application when the compile or match functions are called. In some - cases the pattern can contain special leading sequences such as (*CRLF) - to override what the application has set or what has been defaulted. - Details are given in the section entitled "Newline sequences" above. - There are also the (*UTF8) and (*UCP) leading sequences that can be - used to set UTF-8 and Unicode property modes; they are equivalent to - setting the PCRE_UTF8 and the PCRE_UCP options, respectively. + Note: There are other PCRE-specific options that can be set by the + application when the compiling or matching functions are called. In + some cases the pattern can contain special leading sequences such as + (*CRLF) to override what the application has set or what has been + defaulted. Details are given in the section entitled "Newline + sequences" above. There are also the (*UTF8), (*UTF16), and (*UCP) + leading sequences that can be used to set UTF and Unicode property + modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and + the PCRE_UCP options, respectively. SUBPATTERNS @@ -4267,22 +4999,25 @@ 2. It sets up the subpattern as a capturing subpattern. This means that, when the whole pattern matches, that portion of the subject string that matched the subpattern is passed back to the caller via the - ovector argument of pcre_exec(). Opening parentheses are counted from - left to right (starting from 1) to obtain numbers for the capturing - subpatterns. For example, if the string "the red king" is matched - against the pattern + ovector argument of the matching function. (This applies only to the + traditional matching functions; the DFA matching functions do not sup- + port capturing.) + + Opening parentheses are counted from left to right (starting from 1) to + obtain numbers for the capturing subpatterns. For example, if the + string "the red king" is matched against the pattern the ((red|white) (king|queen)) the captured substrings are "red king", "red", and "king", and are num- bered 1, 2, and 3, respectively. - The fact that plain parentheses fulfil two functions is not always - helpful. There are often times when a grouping subpattern is required - without a capturing requirement. If an opening parenthesis is followed - by a question mark and a colon, the subpattern does not do any captur- - ing, and is not counted when computing the number of any subsequent - capturing subpatterns. For example, if the string "the white queen" is + The fact that plain parentheses fulfil two functions is not always + helpful. There are often times when a grouping subpattern is required + without a capturing requirement. If an opening parenthesis is followed + by a question mark and a colon, the subpattern does not do any captur- + ing, and is not counted when computing the number of any subsequent + capturing subpatterns. For example, if the string "the white queen" is matched against the pattern the ((?:red|white) (king|queen)) @@ -4290,37 +5025,37 @@ the captured substrings are "white queen" and "queen", and are numbered 1 and 2. The maximum number of capturing subpatterns is 65535. - As a convenient shorthand, if any option settings are required at the - start of a non-capturing subpattern, the option letters may appear + As a convenient shorthand, if any option settings are required at the + start of a non-capturing subpattern, the option letters may appear between the "?" and the ":". Thus the two patterns (?i:saturday|sunday) (?:(?i)saturday|sunday) match exactly the same set of strings. Because alternative branches are - tried from left to right, and options are not reset until the end of - the subpattern is reached, an option setting in one branch does affect - subsequent branches, so the above patterns match "SUNDAY" as well as + tried from left to right, and options are not reset until the end of + the subpattern is reached, an option setting in one branch does affect + subsequent branches, so the above patterns match "SUNDAY" as well as "Saturday". DUPLICATE SUBPATTERN NUMBERS Perl 5.10 introduced a feature whereby each alternative in a subpattern - uses the same numbers for its capturing parentheses. Such a subpattern - starts with (?| and is itself a non-capturing subpattern. For example, + uses the same numbers for its capturing parentheses. Such a subpattern + starts with (?| and is itself a non-capturing subpattern. For example, consider this pattern: (?|(Sat)ur|(Sun))day - Because the two alternatives are inside a (?| group, both sets of cap- - turing parentheses are numbered one. Thus, when the pattern matches, - you can look at captured substring number one, whichever alternative - matched. This construct is useful when you want to capture part, but + Because the two alternatives are inside a (?| group, both sets of cap- + turing parentheses are numbered one. Thus, when the pattern matches, + you can look at captured substring number one, whichever alternative + matched. This construct is useful when you want to capture part, but not all, of one of a number of alternatives. Inside a (?| group, paren- - theses are numbered as usual, but the number is reset at the start of - each branch. The numbers of any capturing parentheses that follow the - subpattern start after the highest number used in any branch. The fol- + theses are numbered as usual, but the number is reset at the start of + each branch. The numbers of any capturing parentheses that follow the + subpattern start after the highest number used in any branch. The fol- lowing example is taken from the Perl documentation. The numbers under- neath show in which buffer the captured content will be stored. @@ -4328,58 +5063,58 @@ / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x # 1 2 2 3 2 3 4 - A back reference to a numbered subpattern uses the most recent value - that is set for that number by any subpattern. The following pattern + A back reference to a numbered subpattern uses the most recent value + that is set for that number by any subpattern. The following pattern matches "abcabc" or "defdef": /(?|(abc)|(def))\1/ - In contrast, a recursive or "subroutine" call to a numbered subpattern - always refers to the first one in the pattern with the given number. - The following pattern matches "abcabc" or "defabc": + In contrast, a subroutine call to a numbered subpattern always refers + to the first one in the pattern with the given number. The following + pattern matches "abcabc" or "defabc": /(?|(abc)|(def))(?1)/ - If a condition test for a subpattern's having matched refers to a non- - unique number, the test is true if any of the subpatterns of that num- + If a condition test for a subpattern's having matched refers to a non- + unique number, the test is true if any of the subpatterns of that num- ber have matched. - An alternative approach to using this "branch reset" feature is to use + An alternative approach to using this "branch reset" feature is to use duplicate named subpatterns, as described in the next section. NAMED SUBPATTERNS - Identifying capturing parentheses by number is simple, but it can be - very hard to keep track of the numbers in complicated regular expres- - sions. Furthermore, if an expression is modified, the numbers may - change. To help with this difficulty, PCRE supports the naming of sub- + Identifying capturing parentheses by number is simple, but it can be + very hard to keep track of the numbers in complicated regular expres- + sions. Furthermore, if an expression is modified, the numbers may + change. To help with this difficulty, PCRE supports the naming of sub- patterns. This feature was not added to Perl until release 5.10. Python - had the feature earlier, and PCRE introduced it at release 4.0, using - the Python syntax. PCRE now supports both the Perl and the Python syn- - tax. Perl allows identically numbered subpatterns to have different + had the feature earlier, and PCRE introduced it at release 4.0, using + the Python syntax. PCRE now supports both the Perl and the Python syn- + tax. Perl allows identically numbered subpatterns to have different names, but PCRE does not. - In PCRE, a subpattern can be named in one of three ways: (?...) - or (?'name'...) as in Perl, or (?P...) as in Python. References - to capturing parentheses from other parts of the pattern, such as back - references, recursion, and conditions, can be made by name as well as + In PCRE, a subpattern can be named in one of three ways: (?...) + or (?'name'...) as in Perl, or (?P...) as in Python. References + to capturing parentheses from other parts of the pattern, such as back + references, recursion, and conditions, can be made by name as well as by number. - Names consist of up to 32 alphanumeric characters and underscores. - Named capturing parentheses are still allocated numbers as well as - names, exactly as if the names were not present. The PCRE API provides + Names consist of up to 32 alphanumeric characters and underscores. + Named capturing parentheses are still allocated numbers as well as + names, exactly as if the names were not present. The PCRE API provides function calls for extracting the name-to-number translation table from a compiled pattern. There is also a convenience function for extracting a captured substring by name. - By default, a name must be unique within a pattern, but it is possible + By default, a name must be unique within a pattern, but it is possible to relax this constraint by setting the PCRE_DUPNAMES option at compile - time. (Duplicate names are also always permitted for subpatterns with - the same number, set up as described in the previous section.) Dupli- - cate names can be useful for patterns where only one instance of the - named parentheses can match. Suppose you want to match the name of a - weekday, either as a 3-letter abbreviation or as the full name, and in + time. (Duplicate names are also always permitted for subpatterns with + the same number, set up as described in the previous section.) Dupli- + cate names can be useful for patterns where only one instance of the + named parentheses can match. Suppose you want to match the name of a + weekday, either as a 3-letter abbreviation or as the full name, and in both cases you want to extract the abbreviation. This pattern (ignoring the line breaks) does the job: @@ -4389,62 +5124,62 @@ (?Thu)(?:rsday)?| (?Sat)(?:urday)? - There are five capturing substrings, but only one is ever set after a + There are five capturing substrings, but only one is ever set after a match. (An alternative way of solving this problem is to use a "branch reset" subpattern, as described in the previous section.) - The convenience function for extracting the data by name returns the - substring for the first (and in this example, the only) subpattern of - that name that matched. This saves searching to find which numbered + The convenience function for extracting the data by name returns the + substring for the first (and in this example, the only) subpattern of + that name that matched. This saves searching to find which numbered subpattern it was. - If you make a back reference to a non-unique named subpattern from - elsewhere in the pattern, the one that corresponds to the first occur- + If you make a back reference to a non-unique named subpattern from + elsewhere in the pattern, the one that corresponds to the first occur- rence of the name is used. In the absence of duplicate numbers (see the - previous section) this is the one with the lowest number. If you use a - named reference in a condition test (see the section about conditions - below), either to check whether a subpattern has matched, or to check - for recursion, all subpatterns with the same name are tested. If the - condition is true for any one of them, the overall condition is true. + previous section) this is the one with the lowest number. If you use a + named reference in a condition test (see the section about conditions + below), either to check whether a subpattern has matched, or to check + for recursion, all subpatterns with the same name are tested. If the + condition is true for any one of them, the overall condition is true. This is the same behaviour as testing by number. For further details of the interfaces for handling named subpatterns, see the pcreapi documen- tation. Warning: You cannot use different names to distinguish between two sub- - patterns with the same number because PCRE uses only the numbers when + patterns with the same number because PCRE uses only the numbers when matching. For this reason, an error is given at compile time if differ- - ent names are given to subpatterns with the same number. However, you - can give the same name to subpatterns with the same number, even when + ent names are given to subpatterns with the same number. However, you + can give the same name to subpatterns with the same number, even when PCRE_DUPNAMES is not set. REPETITION - Repetition is specified by quantifiers, which can follow any of the + Repetition is specified by quantifiers, which can follow any of the following items: a literal data character the dot metacharacter the \C escape sequence - the \X escape sequence (in UTF-8 mode with Unicode properties) + the \X escape sequence the \R escape sequence an escape such as \d or \pL that matches a single character a character class a back reference (see next section) - a parenthesized subpattern (unless it is an assertion) - a recursive or "subroutine" call to a subpattern + a parenthesized subpattern (including assertions) + a subroutine call to a subpattern (recursive or otherwise) - The general repetition quantifier specifies a minimum and maximum num- - ber of permitted matches, by giving the two numbers in curly brackets - (braces), separated by a comma. The numbers must be less than 65536, + The general repetition quantifier specifies a minimum and maximum num- + ber of permitted matches, by giving the two numbers in curly brackets + (braces), separated by a comma. The numbers must be less than 65536, and the first must be less than or equal to the second. For example: z{2,4} - matches "zz", "zzz", or "zzzz". A closing brace on its own is not a - special character. If the second number is omitted, but the comma is - present, there is no upper limit; if the second number and the comma - are both omitted, the quantifier specifies an exact number of required + matches "zz", "zzz", or "zzzz". A closing brace on its own is not a + special character. If the second number is omitted, but the comma is + present, there is no upper limit; if the second number and the comma + are both omitted, the quantifier specifies an exact number of required matches. Thus [aeiou]{3,} @@ -4453,17 +5188,16 @@ \d{8} - matches exactly 8 digits. An opening curly bracket that appears in a - position where a quantifier is not allowed, or one that does not match - the syntax of a quantifier, is taken as a literal character. For exam- + matches exactly 8 digits. An opening curly bracket that appears in a + position where a quantifier is not allowed, or one that does not match + the syntax of a quantifier, is taken as a literal character. For exam- ple, {,6} is not a quantifier, but a literal string of four characters. - In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to - individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 char- - acters, each of which is represented by a two-byte sequence. Similarly, - when Unicode property support is available, \X{3} matches three Unicode - extended sequences, each of which may be several bytes long (and they - may be of different lengths). + In UTF modes, quantifiers apply to characters rather than to individual + data units. Thus, for example, \x{100}{2} matches two characters, each + of which is represented by a two-byte sequence in a UTF-8 string. Simi- + larly, \X{3} matches three Unicode extended sequences, each of which + may be several data units long (and they may be of different lengths). The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be use- @@ -4769,8 +5503,8 @@ its following a backslash are taken as part of a potential back refer- ence number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the - PCRE_EXTENDED option is set, this can be whitespace. Otherwise, the \g{ - syntax or an empty comment (see "Comments" below) can be used. + PCRE_EXTENDED option is set, this can be white space. Otherwise, the + \g{ syntax or an empty comment (see "Comments" below) can be used. Recursive back references @@ -4807,13 +5541,29 @@ matched in the normal way, except that it does not cause the current matching position to be changed. - Assertion subpatterns are not capturing subpatterns, and may not be - repeated, because it makes no sense to assert the same thing several - times. If any kind of assertion contains capturing subpatterns within - it, these are counted for the purposes of numbering the capturing sub- - patterns in the whole pattern. However, substring capturing is carried - out only for positive assertions, because it does not make sense for - negative assertions. + Assertion subpatterns are not capturing subpatterns. If such an asser- + tion contains capturing subpatterns within it, these are counted for + the purposes of numbering the capturing subpatterns in the whole pat- + tern. However, substring capturing is carried out only for positive + assertions, because it does not make sense for negative assertions. + + For compatibility with Perl, assertion subpatterns may be repeated; + though it makes no sense to assert the same thing several times, the + side effect of capturing parentheses may occasionally be useful. In + practice, there only three cases: + + (1) If the quantifier is {0}, the assertion is never obeyed during + matching. However, it may contain internal capturing parenthesized + groups that are called from elsewhere via the subroutine mechanism. + + (2) If quantifier is {0,n} where n is greater than zero, it is treated + as if it were {0,1}. At run time, the rest of the pattern match is + tried with and without the assertion, the order depending on the greed- + iness of the quantifier. + + (3) If the minimum repetition is greater than zero, the quantifier is + ignored. The assertion is obeyed just once when encountered during + matching. Lookahead assertions @@ -4883,40 +5633,41 @@ then try to match. If there are insufficient characters before the cur- rent position, the assertion fails. - PCRE does not allow the \C escape (which matches a single byte in UTF-8 - mode) to appear in lookbehind assertions, because it makes it impossi- - ble to calculate the length of the lookbehind. The \X and \R escapes, - which can match different numbers of bytes, are also not permitted. + In a UTF mode, PCRE does not allow the \C escape (which matches a sin- + gle data unit even in a UTF mode) to appear in lookbehind assertions, + because it makes it impossible to calculate the length of the lookbe- + hind. The \X and \R escapes, which can match different numbers of data + units, are also not permitted. - "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in - lookbehinds, as long as the subpattern matches a fixed-length string. + "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in + lookbehinds, as long as the subpattern matches a fixed-length string. Recursion, however, is not supported. - Possessive quantifiers can be used in conjunction with lookbehind + Possessive quantifiers can be used in conjunction with lookbehind assertions to specify efficient matching of fixed-length strings at the end of subject strings. Consider a simple pattern such as abcd$ - when applied to a long string that does not match. Because matching + when applied to a long string that does not match. Because matching proceeds from left to right, PCRE will look for each "a" in the subject - and then see if what follows matches the rest of the pattern. If the + and then see if what follows matches the rest of the pattern. If the pattern is specified as ^.*abcd$ - the initial .* matches the entire string at first, but when this fails + the initial .* matches the entire string at first, but when this fails (because there is no following "a"), it backtracks to match all but the - last character, then all but the last two characters, and so on. Once - again the search for "a" covers the entire string, from right to left, + last character, then all but the last two characters, and so on. Once + again the search for "a" covers the entire string, from right to left, so we are no better off. However, if the pattern is written as ^.*+(?<=abcd) - there can be no backtracking for the .*+ item; it can match only the - entire string. The subsequent lookbehind assertion does a single test - on the last four characters. If it fails, the match fails immediately. - For long strings, this approach makes a significant difference to the + there can be no backtracking for the .*+ item; it can match only the + entire string. The subsequent lookbehind assertion does a single test + on the last four characters. If it fails, the match fails immediately. + For long strings, this approach makes a significant difference to the processing time. Using multiple assertions @@ -4925,18 +5676,18 @@ (?<=\d{3})(?)...) or (?('name')...) to test for a - used subpattern by name. For compatibility with earlier versions of - PCRE, which had this facility before Perl, the syntax (?(name)...) is - also recognized. However, there is a possible ambiguity with this syn- - tax, because subpattern names may consist entirely of digits. PCRE - looks first for a named subpattern; if it cannot find one and the name - consists entirely of digits, PCRE looks for a subpattern of that num- - ber, which must be greater than zero. Using subpattern names that con- + Perl uses the syntax (?()...) or (?('name')...) to test for a + used subpattern by name. For compatibility with earlier versions of + PCRE, which had this facility before Perl, the syntax (?(name)...) is + also recognized. However, there is a possible ambiguity with this syn- + tax, because subpattern names may consist entirely of digits. PCRE + looks first for a named subpattern; if it cannot find one and the name + consists entirely of digits, PCRE looks for a subpattern of that num- + ber, which must be greater than zero. Using subpattern names that con- sist entirely of digits is not recommended. Rewriting the above example to use a named subpattern gives this: (? \( )? [^()]+ (?() \) ) - If the name used in a condition of this kind is a duplicate, the test - is applied to all subpatterns of the same name, and is true if any one + If the name used in a condition of this kind is a duplicate, the test + is applied to all subpatterns of the same name, and is true if any one of them has matched. Checking for pattern recursion If the condition is the string (R), and there is no subpattern with the - name R, the condition is true if a recursive call to the whole pattern + name R, the condition is true if a recursive call to the whole pattern or any subpattern has been made. If digits or a name preceded by amper- sand follow the letter R, for example: @@ -5049,24 +5800,23 @@ the condition is true if the most recent recursion is into a subpattern whose number or name is given. This condition does not check the entire - recursion stack. If the name used in a condition of this kind is a + recursion stack. If the name used in a condition of this kind is a duplicate, the test is applied to all subpatterns of the same name, and is true if any one of them is the most recent recursion. - At "top level", all these recursion test conditions are false. The + At "top level", all these recursion test conditions are false. The syntax for recursive patterns is described below. Defining subpatterns for use by reference only - If the condition is the string (DEFINE), and there is no subpattern - with the name DEFINE, the condition is always false. In this case, - there may be only one alternative in the subpattern. It is always - skipped if control reaches this point in the pattern; the idea of - DEFINE is that it can be used to define "subroutines" that can be ref- - erenced from elsewhere. (The use of "subroutines" is described below.) - For example, a pattern to match an IPv4 address such as - "192.168.23.245" could be written like this (ignore whitespace and line - breaks): + If the condition is the string (DEFINE), and there is no subpattern + with the name DEFINE, the condition is always false. In this case, + there may be only one alternative in the subpattern. It is always + skipped if control reaches this point in the pattern; the idea of + DEFINE is that it can be used to define subroutines that can be refer- + enced from elsewhere. (The use of subroutines is described below.) For + example, a pattern to match an IPv4 address such as "192.168.23.245" + could be written like this (ignore white space and line breaks): (?(DEFINE) (? 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) \b (?&byte) (\.(?&byte)){3} \b @@ -5112,12 +5862,12 @@ comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which charac- ters are interpreted as newlines is controlled by the options passed to - pcre_compile() or by a special sequence at the start of the pattern, as - described in the section entitled "Newline conventions" above. Note - that the end of this type of comment is a literal newline sequence in - the pattern; escape sequences that happen to represent a newline do not - count. For example, consider this pattern when PCRE_EXTENDED is set, - and the default newline convention is in force: + a compiling function or by a special sequence at the start of the pat- + tern, as described in the section entitled "Newline conventions" above. + Note that the end of this type of comment is a literal newline sequence + in the pattern; escape sequences that happen to represent a newline do + not count. For example, consider this pattern when PCRE_EXTENDED is + set, and the default newline convention is in force: abc #comment \n still comment @@ -5153,11 +5903,11 @@ into Perl at release 5.10. A special item that consists of (? followed by a number greater than - zero and a closing parenthesis is a recursive call of the subpattern of - the given number, provided that it occurs inside that subpattern. (If - not, it is a "subroutine" call, which is described in the next sec- - tion.) The special item (?R) or (?0) is a recursive call of the entire - regular expression. + zero and a closing parenthesis is a recursive subroutine call of the + subpattern of the given number, provided that it occurs inside that + subpattern. (If not, it is a non-recursive subroutine call, which is + described in the next section.) The special item (?R) or (?0) is a + recursive call of the entire regular expression. This PCRE pattern solves the nested parentheses problem (assume the PCRE_EXTENDED option is set so that white space is ignored): @@ -5189,8 +5939,8 @@ It is also possible to refer to subsequently opened parentheses, by writing references such as (?+2). However, these cannot be recursive because the reference is not inside the parentheses that are refer- - enced. They are always "subroutine" calls, as described in the next - section. + enced. They are always non-recursive subroutine calls, as described in + the next section. An alternative approach is to use named parentheses instead. The Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also @@ -5223,28 +5973,30 @@ the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing sub- - pattern is not matched at the top level, its final value is unset, even - if it is (temporarily) set at a deeper level. + pattern is not matched at the top level, its final captured value is + unset, even if it was (temporarily) set at a deeper level during the + matching process. - If there are more than 15 capturing parentheses in a pattern, PCRE has - to obtain extra memory to store data during a recursion, which it does + If there are more than 15 capturing parentheses in a pattern, PCRE has + to obtain extra memory to store data during a recursion, which it does by using pcre_malloc, freeing it via pcre_free afterwards. If no memory can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error. - Do not confuse the (?R) item with the condition (R), which tests for - recursion. Consider this pattern, which matches text in angle brack- - ets, allowing for arbitrary nesting. Only digits are allowed in nested - brackets (that is, when recursing), whereas any characters are permit- + Do not confuse the (?R) item with the condition (R), which tests for + recursion. Consider this pattern, which matches text in angle brack- + ets, allowing for arbitrary nesting. Only digits are allowed in nested + brackets (that is, when recursing), whereas any characters are permit- ted at the outer level. < (?: (?(R) \d++ | [^<>]*+) | (?R)) * > - In this pattern, (?(R) is the start of a conditional subpattern, with - two different alternatives for the recursive and non-recursive cases. + In this pattern, (?(R) is the start of a conditional subpattern, with + two different alternatives for the recursive and non-recursive cases. The (?R) item is the actual recursive call. - Recursion difference from Perl + Differences in recursion processing between PCRE and Perl + Recursion processing in PCRE differs from Perl in two important ways. In PCRE (like Python, but unlike Perl), a recursive subpattern call is always treated as an atomic group. That is, once it has matched some of the subject string, it is never re-entered, even if it contains untried @@ -5317,14 +6069,30 @@ Once again, it cannot jump back into the recursion to try other alter- natives, so the entire match fails. + The second way in which PCRE and Perl differ in their recursion pro- + cessing is in the handling of captured values. In Perl, when a subpat- + tern is called recursively or as a subpattern (see the next section), + it has no access to any values that were captured outside the recur- + sion, whereas in PCRE these values can be referenced. Consider this + pattern: + + ^(.)(\1|a(?2)) + + In PCRE, this pattern matches "bab". The first capturing parentheses + match "b", then in the second group, when the back reference \1 fails + to match "b", the second alternative matches "a" and then recurses. In + the recursion, \1 does now match "b" and so the whole match succeeds. + In Perl, the pattern fails to match because inside the recursive call + \1 cannot access the externally set value. + SUBPATTERNS AS SUBROUTINES - If the syntax for a recursive subpattern reference (either by number or - by name) is used outside the parentheses to which it refers, it oper- - ates like a subroutine in a programming language. The "called" subpat- - tern may be defined before or after the reference. A numbered reference - can be absolute or relative, as in these examples: + If the syntax for a recursive subpattern call (either by number or by + name) is used outside the parentheses to which it refers, it operates + like a subroutine in a programming language. The called subpattern may + be defined before or after the reference. A numbered reference can be + absolute or relative, as in these examples: (...(absolute)...)...(?2)... (...(relative)...)...(?-1)... @@ -5343,15 +6111,15 @@ two strings. Another example is given in the discussion of DEFINE above. - Like recursive subpatterns, a subroutine call is always treated as an - atomic group. That is, once it has matched some of the subject string, - it is never re-entered, even if it contains untried alternatives and - there is a subsequent matching failure. Any capturing parentheses that - are set during the subroutine call revert to their previous values - afterwards. + All subroutine calls, whether recursive or not, are always treated as + atomic groups. That is, once a subroutine has matched some of the sub- + ject string, it is never re-entered, even if it contains untried alter- + natives and there is a subsequent matching failure. Any capturing + parentheses that are set during the subroutine call revert to their + previous values afterwards. - When a subpattern is used as a subroutine, processing options such as - case-independence are fixed when the subpattern is defined. They cannot + Processing options such as case-independence are fixed when a subpat- + tern is defined, so if it is used as a subroutine, such options cannot be changed for different calls. For example, consider this pattern: (abc)(?i:(?-1)) @@ -5392,8 +6160,8 @@ PCRE provides a similar feature, but of course it cannot obey arbitrary Perl code. The feature is called "callout". The caller of PCRE provides an external function by putting its entry point in the global variable - pcre_callout. By default, this variable contains NULL, which disables - all calling out. + pcre_callout (8-bit library) or pcre16_callout (16-bit library). By + default, this variable contains NULL, which disables all calling out. Within a regular expression, (?C) indicates the points at which the external function is to be called. If you want to identify different @@ -5403,17 +6171,17 @@ (?C1)abc(?C2)def - If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are - automatically installed before each item in the pattern. They are all - numbered 255. - - During matching, when PCRE reaches a callout point (and pcre_callout is - set), the external function is called. It is provided with the number - of the callout, the position in the pattern, and, optionally, one item - of data originally supplied by the caller of pcre_exec(). The callout - function may cause matching to proceed, to backtrack, or to fail alto- - gether. A complete description of the interface to the callout function - is given in the pcrecallout documentation. + If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call- + outs are automatically installed before each item in the pattern. They + are all numbered 255. + + During matching, when PCRE reaches a callout point, the external func- + tion is called. It is provided with the number of the callout, the + position in the pattern, and, optionally, one item of data originally + supplied by the caller of the matching function. The callout function + may cause matching to proceed, to backtrack, or to fail altogether. A + complete description of the interface to the callout function is given + in the pcrecallout documentation. BACKTRACKING CONTROL @@ -5426,25 +6194,33 @@ in this section. Since these verbs are specifically related to backtracking, most of - them can be used only when the pattern is to be matched using - pcre_exec(), which uses a backtracking algorithm. With the exception of - (*FAIL), which behaves like a failing negative assertion, they cause an - error if encountered by pcre_dfa_exec(). - - If any of these verbs are used in an assertion or subroutine subpattern - (including recursive subpatterns), their effect is confined to that - subpattern; it does not extend to the surrounding pattern. Note that - such subpatterns are processed as anchored at the point where they are - tested. + them can be used only when the pattern is to be matched using one of + the traditional matching functions, which use a backtracking algorithm. + With the exception of (*FAIL), which behaves like a failing negative + assertion, they cause an error if encountered by a DFA matching func- + tion. - The new verbs make use of what was previously invalid syntax: an open- + If any of these verbs are used in an assertion or in a subpattern that + is called as a subroutine (whether or not recursively), their effect is + confined to that subpattern; it does not extend to the surrounding pat- + tern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN) + that is encountered in a successful positive assertion is passed back + when a match succeeds (compare capturing parentheses in assertions). + Note that such subpatterns are processed as anchored at the point where + they are tested. Note also that Perl's treatment of subroutines and + assertions is different in some cases. + + The new verbs make use of what was previously invalid syntax: an open- ing parenthesis followed by an asterisk. They are generally of the form - (*VERB) or (*VERB:NAME). Some may take either form, with differing be- - haviour, depending on whether or not an argument is present. An name is - a sequence of letters, digits, and underscores. If the name is empty, - that is, if the closing parenthesis immediately follows the colon, the - effect is as if the colon were not there. Any number of these verbs may - occur in a pattern. + (*VERB) or (*VERB:NAME). Some may take either form, with differing be- + haviour, depending on whether or not an argument is present. A name is + any sequence of characters that does not include a closing parenthesis. + The maximum length of name is 255 in the 8-bit library and 65535 in the + 16-bit library. If the name is empty, that is, if the closing parenthe- + sis immediately follows the colon, the effect is as if the colon were + not there. Any number of these verbs may occur in a pattern. + + Optimizations that affect backtracking verbs PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it @@ -5454,60 +6230,64 @@ course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com- pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT). + There is more discussion of this option in the section entitled "Option + bits for pcre_exec()" in the pcreapi documentation. + + Experiments with Perl suggest that it too has similar optimizations, + sometimes leading to anomalous results. Verbs that act immediately - The following verbs act as soon as they are encountered. They may not + The following verbs act as soon as they are encountered. They may not be followed by a name. (*ACCEPT) - This verb causes the match to end successfully, skipping the remainder - of the pattern. When inside a recursion, only the innermost pattern is - ended immediately. If (*ACCEPT) is inside capturing parentheses, the - data so far is captured. (This feature was added to PCRE at release - 8.00.) For example: + This verb causes the match to end successfully, skipping the remainder + of the pattern. However, when it is inside a subpattern that is called + as a subroutine, only that subpattern is ended successfully. Matching + then continues at the outer level. If (*ACCEPT) is inside capturing + parentheses, the data so far is captured. For example: A((?:A|B(*ACCEPT)|C)D) - This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- + This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap- tured by the outer parentheses. (*FAIL) or (*F) - This verb causes the match to fail, forcing backtracking to occur. It - is equivalent to (?!) but easier to read. The Perl documentation notes - that it is probably useful only when combined with (?{}) or (??{}). - Those are, of course, Perl features that are not present in PCRE. The - nearest equivalent is the callout feature, as for example in this pat- + This verb causes a matching failure, forcing backtracking to occur. It + is equivalent to (?!) but easier to read. The Perl documentation notes + that it is probably useful only when combined with (?{}) or (??{}). + Those are, of course, Perl features that are not present in PCRE. The + nearest equivalent is the callout feature, as for example in this pat- tern: a+(?C)(*FAIL) - A match with the string "aaaa" always fails, but the callout is taken + A match with the string "aaaa" always fails, but the callout is taken before each backtrack happens (in this example, 10 times). Recording which path was taken - There is one verb whose main purpose is to track how a match was - arrived at, though it also has a secondary use in conjunction with + There is one verb whose main purpose is to track how a match was + arrived at, though it also has a secondary use in conjunction with advancing the match starting point (see (*SKIP) below). (*MARK:NAME) or (*:NAME) - A name is always required with this verb. There may be as many - instances of (*MARK) as you like in a pattern, and their names do not + A name is always required with this verb. There may be as many + instances of (*MARK) as you like in a pattern, and their names do not have to be unique. - When a match succeeds, the name of the last-encountered (*MARK) is - passed back to the caller via the pcre_extra data structure, as - described in the section on pcre_extra in the pcreapi documentation. No - data is returned for a partial match. Here is an example of pcretest - output, where the /K modifier requests the retrieval and outputting of - (*MARK) data: + When a match succeeds, the name of the last-encountered (*MARK) on the + matching path is passed back to the caller as described in the section + entitled "Extra data for pcre_exec()" in the pcreapi documentation. + Here is an example of pcretest output, where the /K modifier requests + the retrieval and outputting of (*MARK) data: - /X(*MARK:A)Y|X(*MARK:B)Z/K - XY + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XY 0: XY MK: A XZ @@ -5519,98 +6299,86 @@ efficient way of obtaining this information than putting each alterna- tive in its own capturing parentheses. - A name may also be returned after a failed match if the final path - through the pattern involves (*MARK). However, unless (*MARK) used in - conjunction with (*COMMIT), this is unlikely to happen for an unan- - chored pattern because, as the starting point for matching is advanced, - the final check is often with an empty string, causing a failure before - (*MARK) is reached. For example: - - /X(*MARK:A)Y|X(*MARK:B)Z/K - XP - No match + If (*MARK) is encountered in a positive assertion, its name is recorded + and passed back if it is the last-encountered. This does not happen for + negative assertions. - There are three potential starting points for this match (starting with - X, starting with P, and with an empty string). If the pattern is - anchored, the result is different: + After a partial match or a failed match, the name of the last encoun- + tered (*MARK) in the entire match process is returned. For example: - /^X(*MARK:A)Y|^X(*MARK:B)Z/K - XP + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XP No match, mark = B - PCRE's start-of-match optimizations can also interfere with this. For - example, if, as a result of a call to pcre_study(), it knows the mini- - mum subject length for a match, a shorter subject will not be scanned - at all. - - Note that similar anomalies (though different in detail) exist in Perl, - no doubt for the same reasons. The use of (*MARK) data after a failed - match of an unanchored pattern is not recommended, unless (*COMMIT) is - involved. + Note that in this unanchored example the mark is retained from the + match attempt that started at the letter "X" in the subject. Subsequent + match attempts starting at "P" and then with an empty string do not get + as far as the (*MARK) item, but nevertheless do not reset it. + + If you are interested in (*MARK) values after failed matches, you + should probably set the PCRE_NO_START_OPTIMIZE option (see above) to + ensure that the match is always attempted. Verbs that act after backtracking The following verbs do nothing when they are encountered. Matching con- - tinues with what follows, but if there is no subsequent match, causing - a backtrack to the verb, a failure is forced. That is, backtracking - cannot pass to the left of the verb. However, when one of these verbs - appears inside an atomic group, its effect is confined to that group, - because once the group has been matched, there is never any backtrack- - ing into it. In this situation, backtracking can "jump back" to the - left of the entire atomic group. (Remember also, as stated above, that + tinues with what follows, but if there is no subsequent match, causing + a backtrack to the verb, a failure is forced. That is, backtracking + cannot pass to the left of the verb. However, when one of these verbs + appears inside an atomic group, its effect is confined to that group, + because once the group has been matched, there is never any backtrack- + ing into it. In this situation, backtracking can "jump back" to the + left of the entire atomic group. (Remember also, as stated above, that this localization also applies in subroutine calls and assertions.) - These verbs differ in exactly what kind of failure occurs when back- + These verbs differ in exactly what kind of failure occurs when back- tracking reaches them. (*COMMIT) - This verb, which may not be followed by a name, causes the whole match + This verb, which may not be followed by a name, causes the whole match to fail outright if the rest of the pattern does not match. Even if the pattern is unanchored, no further attempts to find a match by advancing the starting point take place. Once (*COMMIT) has been passed, - pcre_exec() is committed to finding a match at the current starting + pcre_exec() is committed to finding a match at the current starting point, or not at all. For example: a+(*COMMIT)b - This matches "xxaab" but not "aacaab". It can be thought of as a kind + This matches "xxaab" but not "aacaab". It can be thought of as a kind of dynamic anchor, or "I've started, so I must finish." The name of the - most recently passed (*MARK) in the path is passed back when (*COMMIT) + most recently passed (*MARK) in the path is passed back when (*COMMIT) forces a match failure. - Note that (*COMMIT) at the start of a pattern is not the same as an - anchor, unless PCRE's start-of-match optimizations are turned off, as + Note that (*COMMIT) at the start of a pattern is not the same as an + anchor, unless PCRE's start-of-match optimizations are turned off, as shown in this pcretest example: - /(*COMMIT)abc/ - xyzabc + re> /(*COMMIT)abc/ + data> xyzabc 0: abc xyzabc\Y No match - PCRE knows that any match must start with "a", so the optimization - skips along the subject to "a" before running the first match attempt, - which succeeds. When the optimization is disabled by the \Y escape in + PCRE knows that any match must start with "a", so the optimization + skips along the subject to "a" before running the first match attempt, + which succeeds. When the optimization is disabled by the \Y escape in the second subject, the match starts at "x" and so the (*COMMIT) causes it to fail without trying any other starting points. (*PRUNE) or (*PRUNE:NAME) - This verb causes the match to fail at the current starting position in - the subject if the rest of the pattern does not match. If the pattern - is unanchored, the normal "bumpalong" advance to the next starting - character then happens. Backtracking can occur as usual to the left of - (*PRUNE), before it is reached, or when matching to the right of - (*PRUNE), but if there is no match to the right, backtracking cannot - cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter- - native to an atomic group or possessive quantifier, but there are some + This verb causes the match to fail at the current starting position in + the subject if the rest of the pattern does not match. If the pattern + is unanchored, the normal "bumpalong" advance to the next starting + character then happens. Backtracking can occur as usual to the left of + (*PRUNE), before it is reached, or when matching to the right of + (*PRUNE), but if there is no match to the right, backtracking cannot + cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter- + native to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. The behav- - iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the - match fails completely; the name is passed back if this is the final - attempt. (*PRUNE:NAME) does not pass back a name if the match suc- - ceeds. In an anchored pattern (*PRUNE) has the same effect as (*COM- - MIT). + iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an + anchored pattern (*PRUNE) has the same effect as (*COMMIT). (*SKIP) @@ -5637,49 +6405,85 @@ is searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that cor- responds to that (*MARK) instead of to where (*SKIP) was encountered. - If no (*MARK) with a matching name is found, normal "bumpalong" of one - character happens (the (*SKIP) is ignored). + If no (*MARK) with a matching name is found, the (*SKIP) is ignored. (*THEN) or (*THEN:NAME) - This verb causes a skip to the next alternation in the innermost - enclosing group if the rest of the pattern does not match. That is, it - cancels pending backtracking, but only within the current alternation. - Its name comes from the observation that it can be used for a pattern- - based if-then-else block: + This verb causes a skip to the next innermost alternative if the rest + of the pattern does not match. That is, it cancels pending backtrack- + ing, but only within the current alternative. Its name comes from the + observation that it can be used for a pattern-based if-then-else block: ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... If the COND1 pattern matches, FOO is tried (and possibly further items - after the end of the group if FOO succeeds); on failure the matcher + after the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The behaviour of (*THEN:NAME) is exactly the same as - (*MARK:NAME)(*THEN) if the overall match fails. If (*THEN) is not - directly inside an alternation, it acts like (*PRUNE). + (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts + like (*PRUNE). - The above verbs provide four different "strengths" of control when sub- - sequent matching fails. (*THEN) is the weakest, carrying on the match - at the next alternation. (*PRUNE) comes next, failing the match at the - current starting position, but allowing an advance to the next charac- - ter (for an unanchored pattern). (*SKIP) is similar, except that the - advance may be more than one character. (*COMMIT) is the strongest, + Note that a subpattern that does not contain a | character is just a + part of the enclosing alternative; it is not a nested alternation with + only one alternative. The effect of (*THEN) extends beyond such a sub- + pattern to the enclosing alternative. Consider this pattern, where A, + B, etc. are complex pattern fragments that do not contain any | charac- + ters at this level: + + A (B(*THEN)C) | D + + If A and B are matched, but there is a failure in C, matching does not + backtrack into A; instead it moves to the next alternative, that is, D. + However, if the subpattern containing (*THEN) is given an alternative, + it behaves differently: + + A (B(*THEN)C | (*FAIL)) | D + + The effect of (*THEN) is now confined to the inner subpattern. After a + failure in C, matching moves to (*FAIL), which causes the whole subpat- + tern to fail because there are no more alternatives to try. In this + case, matching does now backtrack into A. + + Note also that a conditional subpattern is not considered as having two + alternatives, because only one is ever used. In other words, the | + character in a conditional subpattern has a different meaning. Ignoring + white space, consider: + + ^.*? (?(?=a) a | b(*THEN)c ) + + If the subject is "ba", this pattern does not match. Because .*? is + ungreedy, it initially matches zero characters. The condition (?=a) + then fails, the character "b" is matched, but "c" is not. At this + point, matching does not backtrack to .*? as might perhaps be expected + from the presence of the | character. The conditional subpattern is + part of the single alternative that comprises the whole pattern, and so + the match fails. (If there was a backtrack into .*?, allowing it to + match "b", the match would succeed.) + + The verbs just described provide four different "strengths" of control + when subsequent matching fails. (*THEN) is the weakest, carrying on the + match at the next alternative. (*PRUNE) comes next, failing the match + at the current starting position, but allowing an advance to the next + character (for an unanchored pattern). (*SKIP) is similar, except that + the advance may be more than one character. (*COMMIT) is the strongest, causing the entire match to fail. - If more than one is present in a pattern, the "stongest" one wins. For - example, consider this pattern, where A, B, etc. are complex pattern - fragments: + If more than one such verb is present in a pattern, the "strongest" one + wins. For example, consider this pattern, where A, B, etc. are complex + pattern fragments: (A(*COMMIT)B(*THEN)C|D) - Once A has matched, PCRE is committed to this match, at the current - starting position. If subsequently B matches, but C does not, the nor- - mal (*THEN) action of trying the next alternation (that is, D) does not + Once A has matched, PCRE is committed to this match, at the current + starting position. If subsequently B matches, but C does not, the nor- + mal (*THEN) action of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides. SEE ALSO - pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3). + pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3), + pcre16(3). AUTHOR @@ -5691,8 +6495,8 @@ REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 17 June 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -5707,7 +6511,7 @@ The full syntax and semantics of the regular expressions that are sup- ported by PCRE are described in the pcrepattern documentation. This - document contains just a quick-reference summary of the syntax. + document contains a quick-reference summary of the syntax. QUOTING @@ -5721,7 +6525,7 @@ \a alarm, that is, the BEL character (hex 07) \cx "control-x", where x is any ASCII character \e escape (hex 1B) - \f formfeed (hex 0C) + \f form feed (hex 0C) \n newline (hex 0A) \r carriage return (hex 0D) \t tab (hex 09) @@ -5734,25 +6538,25 @@ . any character except newline; in dotall mode, any character whatsoever - \C one byte, even in UTF-8 mode (best avoided) + \C one data unit, even in UTF mode (best avoided) \d a decimal digit \D a character that is not a decimal digit - \h a horizontal whitespace character - \H a character that is not a horizontal whitespace character + \h a horizontal white space character + \H a character that is not a horizontal white space character \N a character that is not a newline \p{xx} a character with the xx property \P{xx} a character without the xx property \R a newline sequence - \s a whitespace character - \S a character that is not a whitespace character - \v a vertical whitespace character - \V a character that is not a vertical whitespace character + \s a white space character + \S a character that is not a white space character + \v a vertical white space character + \V a character that is not a vertical white space character \w a "word" character \W a "non-word" character \X an extended Unicode sequence In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII - characters, even in UTF-8 mode. However, this can be changed by setting + characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option. @@ -5814,20 +6618,22 @@ SCRIPT NAMES FOR \p AND \P - Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille, - Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common, - Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp- - tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, - Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe- - rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian, - Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao, - Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam, - Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic, - Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya, - Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian, - Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, - Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, - Ugaritic, Vai, Yi. + Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, + Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma, + Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, + Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, + Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira- + gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip- + tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li, + Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, + Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive, + Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko, + Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic, + Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari- + tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese, + Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, + Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, + Yi. CHARACTER CLASSES @@ -5848,7 +6654,7 @@ lower lower case letter print printing, including space punct printing, excluding alphanumeric - space whitespace + space white space upper upper case letter word same as \w xdigit hexadecimal digit @@ -5939,7 +6745,8 @@ one of the newline-setting options with similar syntax: (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) - (*UTF8) set UTF-8 mode (PCRE_UTF8) + (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) + (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UCP) set PCRE_UCP (use Unicode properties for \d etc) @@ -6008,6 +6815,7 @@ (*ACCEPT) force successful match (*FAIL) force backtrack; synonym (*F) + (*MARK:NAME) set name to be passed back; synonym (*:NAME) The following act only when a subsequent match failure causes a back- track to reach them. They all force a match failure, but they differ in @@ -6016,14 +6824,18 @@ (*COMMIT) overall failure, no advance of starting point (*PRUNE) advance to next starting character - (*SKIP) advance start to current matching position + (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE) + (*SKIP) advance to current matching position + (*SKIP:NAME) advance to position corresponding to an earlier + (*MARK:NAME); if not found, the (*SKIP) is ignored (*THEN) local failure, backtrack to next alternation + (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) NEWLINE CONVENTIONS These are recognized only at the very start of the pattern or after a - (*BSR_...) or (*UTF8) or (*UCP) option. + (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option. (*CR) carriage return only (*LF) linefeed only @@ -6035,7 +6847,7 @@ WHAT \R MATCHES These are recognized only at the very start of the pattern or after a - (*...) option that sets the newline convention or UTF-8 or UCP mode. + (*...) option that sets the newline convention or a UTF or UCP mode. (*BSR_ANYCRLF) CR, LF, or CRLF (*BSR_UNICODE) any Unicode newline sequence @@ -6061,8 +6873,594 @@ REVISION - Last updated: 21 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREUNICODE(3) PCREUNICODE(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT + + From Release 8.30, in addition to its previous UTF-8 support, PCRE also + supports UTF-16 by means of a separate 16-bit library. This can be + built as well as, or instead of, the 8-bit library. + + +UTF-8 SUPPORT + + In order process UTF-8 strings, you must build PCRE's 8-bit library + with UTF support, and, in addition, you must call pcre_compile() with + the PCRE_UTF8 option flag, or the pattern must start with the sequence + (*UTF8). When either of these is the case, both the pattern and any + subject strings that are matched against it are treated as UTF-8 + strings instead of strings of 1-byte characters. + + +UTF-16 SUPPORT + + In order process UTF-16 strings, you must build PCRE's 16-bit library + with UTF support, and, in addition, you must call pcre16_compile() with + the PCRE_UTF16 option flag, or the pattern must start with the sequence + (*UTF16). When either of these is the case, both the pattern and any + subject strings that are matched against it are treated as UTF-16 + strings instead of strings of 16-bit characters. + + +UTF SUPPORT OVERHEAD + + If you compile PCRE with UTF support, but do not use it at run time, + the library will be a bit bigger, but the additional run time overhead + is limited to testing the PCRE_UTF8/16 flag occasionally, so should not + be very big. + + +UNICODE PROPERTY SUPPORT + + If PCRE is built with Unicode character property support (which implies + UTF support), the escape sequences \p{..}, \P{..}, and \X can be used. + The available properties that can be tested are limited to the general + category properties such as Lu for an upper case letter or Nd for a + decimal number, the Unicode script names such as Arabic or Han, and the + derived properties Any and L&. A full list is given in the pcrepattern + documentation. Only the short names for properties are supported. For + example, \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not + supported. Furthermore, in Perl, many properties may optionally be + prefixed by "Is", for compatibility with Perl 5.6. PCRE does not sup- + port this. + + Validity of UTF-8 strings + + When you set the PCRE_UTF8 flag, the byte strings passed as patterns + and subjects are (by default) checked for validity on entry to the rel- + evant functions. The entire string is checked before any other process- + ing takes place. From release 7.3 of PCRE, the check is according the + rules of RFC 3629, which are themselves derived from the Unicode speci- + fication. Earlier releases of PCRE followed the rules of RFC 2279, + which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The + current check allows only values in the range U+0 to U+10FFFF, exclud- + ing U+D800 to U+DFFF. + + The excluded code points are the "Surrogate Area" of Unicode. They are + reserved for use by UTF-16, where they are used in pairs to encode + codepoints with values greater than 0xFFFF. The code points that are + encoded by UTF-16 pairs are available independently in the UTF-8 encod- + ing. (In other words, the whole surrogate thing is a fudge for UTF-16 + which unfortunately messes up UTF-8.) + + If an invalid UTF-8 string is passed to PCRE, an error return is given. + At compile time, the only additional information is the offset to the + first byte of the failing character. The run-time functions pcre_exec() + and pcre_dfa_exec() also pass back this information, as well as a more + detailed reason code if the caller has provided memory in which to do + this. + + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance, for example in the case of a long subject string that is being + scanned repeatedly with different patterns. If you set the + PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes + that the pattern or subject it is given (respectively) contains only + valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8 + string. + + If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, + what happens depends on why the string is invalid. If the string con- + forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a + string of characters in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() + and the interpreted version of pcre_exec(). In other words, apart from + the initial validity test, these functions (when in UTF-8 mode) handle + strings according to the more liberal rules of RFC 2279. However, the + just-in-time (JIT) optimization for pcre_exec() supports only RFC 3629. + If you are using JIT optimization, or if the string does not even con- + form to RFC 2279, the result is undefined. Your program may crash. + + If you want to process strings of values in the full range 0 to + 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can + set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in + this situation, you will have to apply your own validity check, and + avoid the use of JIT optimization. + + Validity of UTF-16 strings + + When you set the PCRE_UTF16 flag, the strings of 16-bit data units that + are passed as patterns and subjects are (by default) checked for valid- + ity on entry to the relevant functions. Values other than those in the + surrogate range U+D800 to U+DFFF are independent code points. Values in + the surrogate range must be used in pairs in the correct manner. + + If an invalid UTF-16 string is passed to PCRE, an error return is + given. At compile time, the only additional information is the offset + to the first data unit of the failing character. The run-time functions + pcre16_exec() and pcre16_dfa_exec() also pass back this information, as + well as a more detailed reason code if the caller has provided memory + in which to do this. + + In some situations, you may already know that your strings are valid, + and therefore want to skip these checks in order to improve perfor- + mance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at + run time, PCRE assumes that the pattern or subject it is given (respec- + tively) contains only valid UTF-16 sequences. In this case, it does not + diagnose an invalid UTF-16 string. + + General comments about UTF modes + + 1. Codepoints less than 256 can be specified by either braced or + unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3). + Larger values have to use braced sequences. + + 2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they + match two-byte characters for values greater than \177. + + 3. Repeat quantifiers apply to complete UTF characters, not to individ- + ual data units, for example: \x{100}{3}. + + 4. The dot metacharacter matches one UTF character instead of a single + data unit. + + 5. The escape sequence \C can be used to match a single byte in UTF-8 + mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead + to some strange effects because it breaks up multi-unit characters (see + the description of \C in the pcrepattern documentation). The use of \C + is not supported in the alternative matching function + pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT opti- + mization of pcre[16]_exec(). If JIT optimization is requested for a UTF + pattern that contains \C, it will not succeed, and so the matching will + be carried out by the normal interpretive function. + + 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly + test characters of any code value, but, by default, the characters that + PCRE recognizes as digits, spaces, or word characters remain the same + set as in non-UTF mode, all with values less than 256. This remains + true even when PCRE is built to include Unicode property support, + because to do otherwise would slow down PCRE in many common cases. Note + in particular that this applies to \b and \B, because they are defined + in terms of \w and \W. If you really want to test for a wider sense of, + say, "digit", you can use explicit Unicode property tests such as + \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the + character escapes work is changed so that Unicode properties are used + to determine which characters match. There are more details in the sec- + tion on generic character types in the pcrepattern documentation. + + 7. Similarly, characters that match the POSIX named character classes + are all low-valued characters, unless the PCRE_UCP option is set. + + 8. However, the horizontal and vertical white space matching escapes + (\h, \H, \v, and \V) do match all the appropriate Unicode characters, + whether or not PCRE_UCP is set. + + 9. Case-insensitive matching applies only to characters whose values + are less than 128, unless PCRE is built with Unicode property support. + Even when Unicode property support is available, PCRE still uses its + own character tables when checking the case of low-valued characters, + so as not to degrade performance. The Unicode property information is + used only for characters with higher values. Furthermore, PCRE supports + case-insensitive matching only when there is a one-to-one mapping + between a letter's cases. There are a small number of many-to-one map- + pings in Unicode; these are not supported by PCRE. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 14 April 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + +PCREJIT(3) PCREJIT(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +PCRE JUST-IN-TIME COMPILER SUPPORT + + Just-in-time compiling is a heavyweight optimization that can greatly + speed up pattern matching. However, it comes at the cost of extra pro- + cessing before the match is performed. Therefore, it is of most benefit + when the same pattern is going to be matched many times. This does not + necessarily mean many calls of a matching function; if the pattern is + not anchored, matching attempts may take place many times at various + positions in the subject, even for a single call. Therefore, if the + subject string is very long, it may still pay to use JIT for one-off + matches. + + JIT support applies only to the traditional Perl-compatible matching + function. It does not apply when the DFA matching function is being + used. The code for this support was written by Zoltan Herczeg. + + +8-BIT and 16-BIT SUPPORT + + JIT support is available for both the 8-bit and 16-bit PCRE libraries. + To keep this documentation simple, only the 8-bit interface is + described in what follows. If you are using the 16-bit library, substi- + tute the 16-bit functions and 16-bit structures (for example, + pcre16_jit_stack instead of pcre_jit_stack). + + +AVAILABILITY OF JIT SUPPORT + + JIT support is an optional feature of PCRE. The "configure" option + --enable-jit (or equivalent CMake option) must be set when PCRE is + built if you want to use JIT. The support is limited to the following + hardware platforms: + + ARM v5, v7, and Thumb2 + Intel x86 32-bit and 64-bit + MIPS 32-bit + Power PC 32-bit and 64-bit + + If --enable-jit is set on an unsupported platform, compilation fails. + + A program that is linked with PCRE 8.20 or later can tell if JIT sup- + port is available by calling pcre_config() with the PCRE_CONFIG_JIT + option. The result is 1 when JIT is available, and 0 otherwise. How- + ever, a simple program does not need to check this in order to use JIT. + The API is implemented in a way that falls back to the interpretive + code if JIT is not available. + + If your program may sometimes be linked with versions of PCRE that are + older than 8.20, but you want to use JIT when it is available, you can + test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT + macro such as PCRE_CONFIG_JIT, for compile-time control of your code. + + +SIMPLE USE OF JIT + + You have to do two things to make use of the JIT support in the sim- + plest way: + + (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for + each compiled pattern, and pass the resulting pcre_extra block to + pcre_exec(). + + (2) Use pcre_free_study() to free the pcre_extra block when it is + no longer needed, instead of just freeing it yourself. This + ensures that any JIT data is also freed. + + For a program that may be linked with pre-8.20 versions of PCRE, you + can insert + + #ifndef PCRE_STUDY_JIT_COMPILE + #define PCRE_STUDY_JIT_COMPILE 0 + #endif + + so that no option is passed to pcre_study(), and then use something + like this to free the study data: + + #ifdef PCRE_CONFIG_JIT + pcre_free_study(study_ptr); + #else + pcre_free(study_ptr); + #endif + + PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for + complete matches. If you want to run partial matches using the + PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you + should set one or both of the following options in addition to, or + instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study(): + + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + The JIT compiler generates different optimized code for each of the + three modes (normal, soft partial, hard partial). When pcre_exec() is + called, the appropriate code is run if it is available. Otherwise, the + pattern is matched using interpretive code. + + In some circumstances you may need to call additional functions. These + are described in the section entitled "Controlling the JIT stack" + below. + + If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are + ignored, and no JIT data is created. Otherwise, the compiled pattern is + passed to the JIT compiler, which turns it into machine code that exe- + cutes much faster than the normal interpretive code. When pcre_exec() + is passed a pcre_extra block containing a pointer to JIT code of the + appropriate mode (normal or hard/soft partial), it obeys that code + instead of running the interpreter. The result is identical, but the + compiled JIT code runs much faster. + + There are some pcre_exec() options that are not supported for JIT exe- + cution. There are also some pattern items that JIT cannot handle. + Details are given below. In both cases, execution automatically falls + back to the interpretive code. If you want to know whether JIT was + actually used for a particular match, you should arrange for a JIT + callback function to be set up as described in the section entitled + "Controlling the JIT stack" below, even if you do not need to supply a + non-default JIT stack. Such a callback function is called whenever JIT + code is about to be obeyed. If the execution options are not right for + JIT execution, the callback function is not obeyed. + + If the JIT compiler finds an unsupported item, no JIT data is gener- + ated. You can find out if JIT execution is available after studying a + pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A + result of 1 means that JIT compilation was successful. A result of 0 + means that JIT support is not available, or the pattern was not studied + with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to + handle the pattern. + + Once a pattern has been studied, with or without JIT, it can be used as + many times as you like for matching different subject strings. + + +UNSUPPORTED OPTIONS AND PATTERN ITEMS + + The only pcre_exec() options that are supported for JIT execution are + PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, + PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PAR- + TIAL_SOFT. + + The unsupported pattern items are: + + \C match a single byte; not supported in UTF-8 mode + (?Cn) callouts + (*PRUNE) ) + (*SKIP) ) backtracking control verbs + (*THEN) ) + + Support for some of these may be added in future. + + +RETURN VALUES FROM JIT EXECUTION + + When a pattern is matched using JIT execution, the return values are + the same as those given by the interpretive pcre_exec() code, with the + addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means + that the memory used for the JIT stack was insufficient. See "Control- + ling the JIT stack" below for a discussion of JIT stack usage. For com- + patibility with the interpretive pcre_exec() code, no more than two- + thirds of the ovector argument is used for passing back captured sub- + strings. + + The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if + searching a very large pattern tree goes on for too long, as it is in + the same circumstance when JIT is not used, but the details of exactly + what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error + code is never returned by JIT execution. + + +SAVING AND RESTORING COMPILED PATTERNS + + The code that is generated by the JIT compiler is architecture-spe- + cific, and is also position dependent. For those reasons it cannot be + saved (in a file or database) and restored later like the bytecode and + other data of a compiled pattern. Saving and restoring compiled pat- + terns is not something many people do. More detail about this facility + is given in the pcreprecompile documentation. It should be possible to + run pcre_study() on a saved and restored pattern, and thereby recreate + the JIT data, but because JIT compilation uses significant resources, + it is probably not worth doing this; you might as well recompile the + original pattern. + + +CONTROLLING THE JIT STACK + + When the compiled JIT code runs, it needs a block of memory to use as a + stack. By default, it uses 32K on the machine stack. However, some + large or complicated patterns need more than this. The error + PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack. + Three functions are provided for managing blocks of memory for use as + JIT stacks. There is further discussion about the use of JIT stacks in + the section entitled "JIT stack FAQ" below. + + The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments + are a starting size and a maximum size, and it returns a pointer to an + opaque structure of type pcre_jit_stack, or NULL if there is an error. + The pcre_jit_stack_free() function can be used to free a stack that is + no longer needed. (For the technically minded: the address space is + allocated by mmap or VirtualAlloc.) + + JIT uses far less memory for recursion than the interpretive code, and + a maximum stack size of 512K to 1M should be more than enough for any + pattern. + + The pcre_assign_jit_stack() function specifies which stack JIT code + should use. Its arguments are as follows: + + pcre_extra *extra + pcre_jit_callback callback + void *data + + The extra argument must be the result of studying a pattern with + PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the + other two options: + + (1) If callback is NULL and data is NULL, an internal 32K block + on the machine stack is used. + + (2) If callback is NULL and data is not NULL, data must be + a valid JIT stack, the result of calling pcre_jit_stack_alloc(). + + (3) If callback is not NULL, it must point to a function that is + called with data as an argument at the start of matching, in + order to set up a JIT stack. If the return from the callback + function is NULL, the internal 32K stack is used; otherwise the + return value must be a valid JIT stack, the result of calling + pcre_jit_stack_alloc(). + + A callback function is obeyed whenever JIT code is about to be run; it + is not obeyed when pcre_exec() is called with options that are incom- + patible for JIT execution. A callback function can therefore be used to + determine whether a match operation was executed by JIT or by the + interpreter. + + You may safely use the same JIT stack for more than one pattern (either + by assigning directly or by callback), as long as the patterns are all + matched sequentially in the same thread. In a multithread application, + if you do not specify a JIT stack, or if you assign or pass back NULL + from a callback, that is thread-safe, because each thread has its own + machine stack. However, if you assign or pass back a non-NULL JIT + stack, this must be a different stack for each thread so that the + application is thread-safe. + + Strictly speaking, even more is allowed. You can assign the same non- + NULL stack to any number of patterns as long as they are not used for + matching by multiple threads at the same time. For example, you can + assign the same stack to all compiled patterns, and use a global mutex + in the callback to wait until the stack is available for use. However, + this is an inefficient solution, and not recommended. + + This is a suggestion for how a multithreaded program that needs to set + up non-default JIT stacks might operate: + + During thread initalization + thread_local_var = pcre_jit_stack_alloc(...) + + During thread exit + pcre_jit_stack_free(thread_local_var) + + Use a one-line callback function + return thread_local_var + + All the functions described in this section do nothing if JIT is not + available, and pcre_assign_jit_stack() does nothing unless the extra + argument is non-NULL and points to a pcre_extra block that is the + result of a successful study with PCRE_STUDY_JIT_COMPILE etc. + + +JIT STACK FAQ + + (1) Why do we need JIT stacks? + + PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack + where the local data of the current node is pushed before checking its + child nodes. Allocating real machine stack on some platforms is diffi- + cult. For example, the stack chain needs to be updated every time if we + extend the stack on PowerPC. Although it is possible, its updating + time overhead decreases performance. So we do the recursion in memory. + + (2) Why don't we simply allocate blocks of memory with malloc()? + + Modern operating systems have a nice feature: they can reserve an + address space instead of allocating memory. We can safely allocate mem- + ory pages inside this address space, so the stack could grow without + moving memory data (this is important because of pointers). Thus we can + allocate 1M address space, and use only a single memory page (usually + 4K) if that is enough. However, we can still grow up to 1M anytime if + needed. + + (3) Who "owns" a JIT stack? + + The owner of the stack is the user program, not the JIT studied pattern + or anything else. The user program must ensure that if a stack is used + by pcre_exec(), (that is, it is assigned to the pattern currently run- + ning), that stack must not be used by any other threads (to avoid over- + writing the same memory area). The best practice for multithreaded pro- + grams is to allocate a stack for each thread, and return this stack + through the JIT callback function. + + (4) When should a JIT stack be freed? + + You can free a JIT stack at any time, as long as it will not be used by + pcre_exec() again. When you assign the stack to a pattern, only a + pointer is set. There is no reference counting or any other magic. You + can free the patterns and stacks in any order, anytime. Just do not + call pcre_exec() with a pattern pointing to an already freed stack, as + that will cause SEGFAULT. (Also, do not free a stack currently used by + pcre_exec() in another thread). You can also replace the stack for a + pattern at any time. You can even free the previous stack before + assigning a replacement. + + (5) Should I allocate/free a stack every time before/after calling + pcre_exec()? + + No, because this is too costly in terms of resources. However, you + could implement some clever idea which release the stack if it is not + used in let's say two minutes. The JIT callback can help to achive this + without keeping a list of the currently JIT studied patterns. + + (6) OK, the stack is for long term memory allocation. But what happens + if a pattern causes stack overflow with a stack of 1M? Is that 1M kept + until the stack is freed? + + Especially on embedded sytems, it might be a good idea to release mem- + ory sometimes without freeing the stack. There is no API for this at + the moment. Probably a function call which returns with the currently + allocated memory for any stack and another which allows releasing mem- + ory (shrinking the stack) would be a good idea if someone needs this. + + (7) This is too much of a headache. Isn't there any better solution for + JIT stack handling? + + No, thanks to Windows. If POSIX threads were used everywhere, we could + throw out this complicated API. + + +EXAMPLE CODE + + This is a single-threaded example that specifies a JIT stack without + using a callback. + + int rc; + int ovector[30]; + pcre *re; + pcre_extra *extra; + pcre_jit_stack *jit_stack; + + re = pcre_compile(pattern, 0, &error, &erroffset, NULL); + /* Check for errors */ + extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); + jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); + /* Check for error (NULL) */ + pcre_assign_jit_stack(extra, NULL, jit_stack); + rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30); + /* Check results */ + pcre_free(re); + pcre_free_study(extra); + pcre_jit_stack_free(jit_stack); + + +SEE ALSO + + pcreapi(3) + + +AUTHOR + + Philip Hazel (FAQ by Zoltan Herczeg) + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 04 May 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6075,11 +7473,11 @@ PARTIAL MATCHING IN PCRE - In normal use of PCRE, if the subject string that is passed to - pcre_exec() or pcre_dfa_exec() matches as far as it goes, but is too - short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. - There are circumstances where it might be helpful to distinguish this - case from other cases in which there is no match. + In normal use of PCRE, if the subject string that is passed to a match- + ing function matches as far as it goes, but is too short to match the + entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances + where it might be helpful to distinguish this case from other cases in + which there is no match. Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example @@ -6097,41 +7495,52 @@ available at once. PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and - PCRE_PARTIAL_HARD options, which can be set when calling pcre_exec() or - pcre_dfa_exec(). For backwards compatibility, PCRE_PARTIAL is a synonym - for PCRE_PARTIAL_SOFT. The essential difference between the two options - is whether or not a partial match is preferred to an alternative com- - plete match, though the details differ between the two matching func- - tions. If both options are set, PCRE_PARTIAL_HARD takes precedence. - - Setting a partial matching option disables two of PCRE's optimizations. - PCRE remembers the last literal byte in a pattern, and abandons match- - ing immediately if such a byte is not present in the subject string. - This optimization cannot be used for a subject string that might match - only partially. If the pattern was studied, PCRE knows the minimum - length of a matching string, and does not bother to run the matching - function on shorter strings. This optimization is also disabled for - partial matching. - - -PARTIAL MATCHING USING pcre_exec() - - A partial match occurs during a call to pcre_exec() when the end of the - subject string is reached successfully, but matching cannot continue - because more characters are needed. However, at least one character in - the subject must have been inspected. This character need not form part - of the final matched string; lookbehind assertions and the \K escape - sequence provide ways of inspecting characters before the start of a - matched substring. The requirement for inspecting at least one charac- - ter exists because an empty string can always be matched; without such - a restriction there would always be a partial match of an empty string - at the end of the subject. - - If there are at least two slots in the offsets vector when pcre_exec() - returns with a partial match, the first slot is set to the offset of - the earliest character that was inspected when the partial match was - found. For convenience, the second offset points to the end of the sub- - ject so that a substring can easily be identified. + PCRE_PARTIAL_HARD options, which can be set when calling any of the + matching functions. For backwards compatibility, PCRE_PARTIAL is a syn- + onym for PCRE_PARTIAL_SOFT. The essential difference between the two + options is whether or not a partial match is preferred to an alterna- + tive complete match, though the details differ between the two types of + matching function. If both options are set, PCRE_PARTIAL_HARD takes + precedence. + + If you want to use partial matching with just-in-time optimized code, + you must call pcre_study() or pcre16_study() with one or both of these + options: + + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + + PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non- + partial matches on the same pattern. If the appropriate JIT study mode + has not been set for a match, the interpretive matching code is used. + + Setting a partial matching option disables two of PCRE's standard opti- + mizations. PCRE remembers the last literal data unit in a pattern, and + abandons matching immediately if it is not present in the subject + string. This optimization cannot be used for a subject string that + might match only partially. If the pattern was studied, PCRE knows the + minimum length of a matching string, and does not bother to run the + matching function on shorter strings. This optimization is also dis- + abled for partial matching. + + +PARTIAL MATCHING USING pcre_exec() OR pcre16_exec() + + A partial match occurs during a call to pcre_exec() or pcre16_exec() + when the end of the subject string is reached successfully, but match- + ing cannot continue because more characters are needed. However, at + least one character in the subject must have been inspected. This char- + acter need not form part of the final matched string; lookbehind asser- + tions and the \K escape sequence provide ways of inspecting characters + before the start of a matched substring. The requirement for inspecting + at least one character exists because an empty string can always be + matched; without such a restriction there would always be a partial + match of an empty string at the end of the subject. + + If there are at least two slots in the offsets vector when a partial + match is returned, the first slot is set to the offset of the earliest + character that was inspected. For convenience, the second offset points + to the end of the subject so that a substring can easily be identified. For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain look- @@ -6148,13 +7557,13 @@ What happens when a partial match is identified depends on which of the two partial matching options are set. - PCRE_PARTIAL_SOFT with pcre_exec() + PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec() - If PCRE_PARTIAL_SOFT is set when pcre_exec() identifies a partial - match, the partial match is remembered, but matching continues as nor- - mal, and other alternatives in the pattern are tried. If no complete - match can be found, pcre_exec() returns PCRE_ERROR_PARTIAL instead of - PCRE_ERROR_NOMATCH. + If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() identi- + fies a partial match, the partial match is remembered, but matching + continues as normal, and other alternatives in the pattern are tried. + If no complete match can be found, PCRE_ERROR_PARTIAL is returned + instead of PCRE_ERROR_NOMATCH. This option is "soft" because it prefers a complete match over a par- tial match. All the various matching items in a pattern behave as if @@ -6174,22 +7583,24 @@ (In this example, there are two partial matches, because "dog" on its own partially matches the second alternative.) - PCRE_PARTIAL_HARD with pcre_exec() + PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec() - If PCRE_PARTIAL_HARD is set for pcre_exec(), it returns PCRE_ERROR_PAR- - TIAL as soon as a partial match is found, without continuing to search - for possible complete matches. This option is "hard" because it prefers - an earlier partial match over a later complete match. For this reason, - the assumption is made that the end of the supplied subject string may - not be the true end of the available data, and so, if \z, \Z, \b, \B, - or $ are encountered at the end of the subject, the result is - PCRE_ERROR_PARTIAL. - - Setting PCRE_PARTIAL_HARD also affects the way pcre_exec() checks UTF-8 - subject strings for validity. Normally, an invalid UTF-8 sequence - causes the error PCRE_ERROR_BADUTF8. However, in the special case of a - truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT- - UTF8 is returned when PCRE_PARTIAL_HARD is set. + If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(), + PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, + without continuing to search for possible complete matches. This option + is "hard" because it prefers an earlier partial match over a later com- + plete match. For this reason, the assumption is made that the end of + the supplied subject string may not be the true end of the available + data, and so, if \z, \Z, \b, \B, or $ are encountered at the end of the + subject, the result is PCRE_ERROR_PARTIAL, provided that at least one + character in the subject has been inspected. + + Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject + strings are checked for validity. Normally, an invalid sequence causes + the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the + special case of a truncated character at the end of the subject, + PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when + PCRE_PARTIAL_HARD is set. Comparing hard and soft partial matching @@ -6207,25 +7618,25 @@ /dog(sbody)??/ - In this case the result is always a complete match because pcre_exec() - finds that first, and it never continues after finding a match. It - might be easier to follow this explanation by thinking of the two pat- - terns like this: + In this case the result is always a complete match because that is + found first, and matching never continues after finding a complete + match. It might be easier to follow this explanation by thinking of the + two patterns like this: /dog(sbody)?/ is the same as /dogsbody|dog/ /dog(sbody)??/ is the same as /dog|dogsbody/ - The second pattern will never match "dogsbody" when pcre_exec() is - used, because it will always find the shorter match first. + The second pattern will never match "dogsbody", because it will always + find the shorter match first. -PARTIAL MATCHING USING pcre_dfa_exec() +PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec() - The pcre_dfa_exec() function moves along the subject string character - by character, without backtracking, searching for all possible matches - simultaneously. If the end of the subject is reached before the end of - the pattern, there is the possibility of a partial match, again pro- - vided that at least one character has been inspected. + The DFA functions move along the subject string character by character, + without backtracking, searching for all possible matches simultane- + ously. If the end of the subject is reached before the end of the pat- + tern, there is the possibility of a partial match, again provided that + at least one character has been inspected. When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches @@ -6235,17 +7646,17 @@ the first matching string, provided there are at least two slots in the offsets vector. - Because pcre_dfa_exec() always searches for all possible matches, and - there is no difference between greedy and ungreedy repetition, its be- - haviour is different from pcre_exec when PCRE_PARTIAL_HARD is set. Con- - sider the string "dog" matched against the ungreedy pattern shown - above: + Because the DFA functions always search for all possible matches, and + there is no difference between greedy and ungreedy repetition, their + behaviour is different from the standard functions when PCRE_PAR- + TIAL_HARD is set. Consider the string "dog" matched against the + ungreedy pattern shown above: /dog(sbody)??/ - Whereas pcre_exec() stops as soon as it finds the complete match for - "dog", pcre_dfa_exec() also finds the partial match for "dogsbody", and - so returns that when PCRE_PARTIAL_HARD is set. + Whereas the standard functions stop as soon as they find the complete + match for "dog", the DFA functions also find the partial match for + "dogsbody", and so return that when PCRE_PARTIAL_HARD is set. PARTIAL MATCHING AND WORD BOUNDARIES @@ -6259,37 +7670,34 @@ This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following character cannot take place, so a partial match is found. - However, pcre_exec() carries on with normal matching, which matches \b - at the end of the subject when the last character is a letter, thus - finding a complete match. The result, therefore, is not PCRE_ERROR_PAR- - TIAL. The same thing happens with pcre_dfa_exec(), because it also - finds the complete match. - - Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, - because then the partial match takes precedence. + However, normal matching carries on, and \b matches at the end of the + subject when the last character is a letter, so a complete match is + found. The result, therefore, is not PCRE_ERROR_PARTIAL. Using + PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because + then the partial match takes precedence. FORMERLY RESTRICTED PATTERNS For releases of PCRE prior to 8.00, because of the way certain internal - optimizations were implemented in the pcre_exec() function, the - PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be - used with all patterns. From release 8.00 onwards, the restrictions no - longer apply, and partial matching with pcre_exec() can be requested - for any pattern. + optimizations were implemented in the pcre_exec() function, the + PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be + used with all patterns. From release 8.00 onwards, the restrictions no + longer apply, and partial matching with can be requested for any pat- + tern. Items that were formerly restricted were repeated single characters and - repeated metasequences. If PCRE_PARTIAL was set for a pattern that did - not conform to the restrictions, pcre_exec() returned the error code - PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The - PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled + repeated metasequences. If PCRE_PARTIAL was set for a pattern that did + not conform to the restrictions, pcre_exec() returned the error code + PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The + PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled pattern can be used for partial matching now always returns 1. EXAMPLE OF PARTIAL MATCHING USING PCRETEST - If the escape sequence \P is present in a pcretest data line, the - PCRE_PARTIAL_SOFT option is used for the match. Here is a run of + If the escape sequence \P is present in a pcretest data line, the + PCRE_PARTIAL_SOFT option is used for the match. Here is a run of pcretest that uses the date example quoted above: re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ @@ -6305,25 +7713,25 @@ data> j\P No match - The first data string is matched completely, so pcretest shows the - matched substrings. The remaining four strings do not match the com- + The first data string is matched completely, so pcretest shows the + matched substrings. The remaining four strings do not match the com- plete pattern, but the first two are partial matches. Similar output is - obtained when pcre_dfa_exec() is used. + obtained if DFA matching is used. - If the escape sequence \P is present more than once in a pcretest data + If the escape sequence \P is present more than once in a pcretest data line, the PCRE_PARTIAL_HARD option is set for the match. -MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() +MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec() - When a partial match has been found using pcre_dfa_exec(), it is possi- - ble to continue the match by providing additional subject data and - calling pcre_dfa_exec() again with the same compiled regular expres- - sion, this time setting the PCRE_DFA_RESTART option. You must pass the + When a partial match has been found using a DFA matching function, it + is possible to continue the match by providing additional subject data + and calling the function again with the same compiled regular expres- + sion, this time setting the PCRE_DFA_RESTART option. You must pass the same working space as before, because this is where details of the pre- - vious partial match are stored. Here is an example using pcretest, - using the \R escape sequence to set the PCRE_DFA_RESTART option (\D - specifies the use of pcre_dfa_exec()): + vious partial match are stored. Here is an example using pcretest, + using the \R escape sequence to set the PCRE_DFA_RESTART option (\D + specifies the use of the DFA matching function): re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/ data> 23ja\P\D @@ -6331,46 +7739,49 @@ data> n05\R\D 0: n05 - The first call has "23ja" as the subject, and requests partial match- - ing; the second call has "n05" as the subject for the continued - (restarted) match. Notice that when the match is complete, only the - last part is shown; PCRE does not retain the previously partially- - matched string. It is up to the calling program to do that if it needs + The first call has "23ja" as the subject, and requests partial match- + ing; the second call has "n05" as the subject for the continued + (restarted) match. Notice that when the match is complete, only the + last part is shown; PCRE does not retain the previously partially- + matched string. It is up to the calling program to do that if it needs to. - You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with - PCRE_DFA_RESTART to continue partial matching over multiple segments. - This facility can be used to pass very long subject strings to - pcre_dfa_exec(). - - -MULTI-SEGMENT MATCHING WITH pcre_exec() - - From release 8.00, pcre_exec() can also be used to do multi-segment - matching. Unlike pcre_dfa_exec(), it is not possible to restart the - previous match with a new segment of data. Instead, new data must be - added to the previous subject string, and the entire match re-run, - starting from the point where the partial match occurred. Earlier data - can be discarded. It is best to use PCRE_PARTIAL_HARD in this situa- - tion, because it does not treat the end of a segment as the end of the - subject when matching \z, \Z, \b, \B, and $. Consider an unanchored - pattern that matches dates: + You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with + PCRE_DFA_RESTART to continue partial matching over multiple segments. + This facility can be used to pass very long subject strings to the DFA + matching functions. + + +MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec() + + From release 8.00, the standard matching functions can also be used to + do multi-segment matching. Unlike the DFA functions, it is not possible + to restart the previous match with a new segment of data. Instead, new + data must be added to the previous subject string, and the entire match + re-run, starting from the point where the partial match occurred. Ear- + lier data can be discarded. + + It is best to use PCRE_PARTIAL_HARD in this situation, because it does + not treat the end of a segment as the end of the subject when matching + \z, \Z, \b, \B, and $. Consider an unanchored pattern that matches + dates: re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/ data> The date is 23ja\P\P Partial match: 23ja - At this stage, an application could discard the text preceding "23ja", - add on text from the next segment, and call pcre_exec() again. Unlike - pcre_dfa_exec(), the entire matching string must always be available, - and the complete matching process occurs for each call, so more memory - and more processing time is needed. - - Note: If the pattern contains lookbehind assertions, or \K, or starts - with \b or \B, the string that is returned for a partial match will - include characters that precede the partially matched string itself, - because these must be retained when adding on more characters for a - subsequent matching attempt. + At this stage, an application could discard the text preceding "23ja", + add on text from the next segment, and call the matching function + again. Unlike the DFA matching functions, the entire matching string + must always be available, and the complete matching process occurs for + each call, so more memory and more processing time is needed. + + Note: If the pattern contains lookbehind assertions, or \K, or starts + with \b or \B, the string that is returned for a partial match includes + characters that precede the partially matched string itself, because + these must be retained when adding on more characters for a subsequent + matching attempt. However, in some cases you may need to retain even + earlier characters, as discussed in the next section. ISSUES WITH MULTI-SEGMENT MATCHING @@ -6384,23 +7795,40 @@ option, but in practice when doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. - 2. Lookbehind assertions at the start of a pattern are catered for in - the offsets that are returned for a partial match. However, in theory, - a lookbehind assertion later in the pattern could require even earlier - characters to be inspected, and it might not have been reached when a - partial match occurs. This is probably an extremely unlikely case; you - could guard against it to a certain extent by always including extra - characters at the start. - - 3. Matching a subject string that is split into multiple segments may - not always produce exactly the same result as matching over one single - long string, especially when PCRE_PARTIAL_SOFT is used. The section - "Partial Matching and Word Boundaries" above describes an issue that - arises if the pattern ends with \b or \B. Another kind of difference - may occur when there are multiple matching possibilities, because (for - PCRE_PARTIAL_SOFT) a partial match result is given only when there are + 2. Lookbehind assertions that have already been obeyed are catered for + in the offsets that are returned for a partial match. However a lookbe- + hind assertion later in the pattern could require even earlier charac- + ters to be inspected. You can handle this case by using the + PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or + pcre16_fullinfo() functions to obtain the length of the largest lookbe- + hind in the pattern. This length is given in characters, not bytes. If + you always retain at least that many characters before the partially + matched string, all should be well. (Of course, near the start of the + subject, fewer characters may be present; in that case all characters + should be retained.) + + 3. Because a partial match must always contain at least one character, + what might be considered a partial match of an empty string actually + gives a "no match" result. For example: + + re> /c(?<=abc)x/ + data> ab\P + No match + + If the next segment begins "cx", a match should be found, but this will + only happen if characters from the previous segment are retained. For + this reason, a "no match" result should be interpreted as "partial + match of an empty string" when the pattern contains lookbehinds. + + 4. Matching a subject string that is split into multiple segments may + not always produce exactly the same result as matching over one single + long string, especially when PCRE_PARTIAL_SOFT is used. The section + "Partial Matching and Word Boundaries" above describes an issue that + arises if the pattern ends with \b or \B. Another kind of difference + may occur when there are multiple matching possibilities, because (for + PCRE_PARTIAL_SOFT) a partial match result is given only when there are no completed matches. This means that as soon as the shortest match has - been found, continuation to a new subject segment is no longer possi- + been found, continuation to a new subject segment is no longer possi- ble. Consider again this pcretest example: re> /dog(sbody)?/ @@ -6414,14 +7842,15 @@ 0: dogsbody 1: dog - The first data line passes the string "dogsb" to pcre_exec(), setting - the PCRE_PARTIAL_SOFT option. Although the string is a partial match - for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the - shorter string "dog" is a complete match. Similarly, when the subject - is presented to pcre_dfa_exec() in several parts ("do" and "gsb" being - the first two) the match stops when "dog" has been found, and it is not - possible to continue. On the other hand, if "dogsbody" is presented as - a single string, pcre_dfa_exec() finds both matches. + The first data line passes the string "dogsb" to a standard matching + function, setting the PCRE_PARTIAL_SOFT option. Although the string is + a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL, + because the shorter string "dog" is a complete match. Similarly, when + the subject is presented to a DFA matching function in several parts + ("do" and "gsb" being the first two) the match stops when "dog" has + been found, and it is not possible to continue. On the other hand, if + "dogsbody" is presented as a single string, a DFA matching function + finds both matches. Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differ- @@ -6435,28 +7864,27 @@ data> gsb\R\P\P\D Partial match: gsb - 4. Patterns that contain alternatives at the top level which do not all + 5. Patterns that contain alternatives at the top level which do not all start with the same pattern item may not work as expected when - PCRE_DFA_RESTART is used with pcre_dfa_exec(). For example, consider - this pattern: + PCRE_DFA_RESTART is used. For example, consider this pattern: 1234|3789 - If the first part of the subject is "ABC123", a partial match of the - first alternative is found at offset 3. There is no partial match for + If the first part of the subject is "ABC123", a partial match of the + first alternative is found at offset 3. There is no partial match for the second alternative, because such a match does not start at the same - point in the subject string. Attempting to continue with the string - "7890" does not yield a match because only those alternatives that - match at one point in the subject are remembered. The problem arises - because the start of the second alternative matches within the first - alternative. There is no problem with anchored patterns or patterns + point in the subject string. Attempting to continue with the string + "7890" does not yield a match because only those alternatives that + match at one point in the subject are remembered. The problem arises + because the start of the second alternative matches within the first + alternative. There is no problem with anchored patterns or patterns such as: 1234|ABCD - where no string can be a partial match for both alternatives. This is - not a problem if pcre_exec() is used, because the entire match has to - be rerun each time: + where no string can be a partial match for both alternatives. This is + not a problem if a standard matching function is used, because the + entire match has to be rerun each time: re> /1234|3789/ data> ABC123\P\P @@ -6465,11 +7893,11 @@ 0: 3789 Of course, instead of using PCRE_DFA_RESTART, the same technique of re- - running the entire match can also be used with pcre_dfa_exec(). Another - possibility is to work with two buffers. If a partial match at offset n - in the first buffer is followed by "no match" when PCRE_DFA_RESTART is - used on the second buffer, you can then try a new match starting at - offset n+1 in the first buffer. + running the entire match can also be used with the DFA matching func- + tions. Another possibility is to work with two buffers. If a partial + match at offset n in the first buffer is followed by "no match" when + PCRE_DFA_RESTART is used on the second buffer, you can then try a new + match starting at offset n+1 in the first buffer. AUTHOR @@ -6481,8 +7909,8 @@ REVISION - Last updated: 07 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 24 February 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6500,26 +7928,32 @@ form instead of having to compile them every time the application is run. If you are not using any private character tables (see the pcre_maketables() documentation), this is relatively straightforward. - If you are using private tables, it is a little bit more complicated. + If you are using private tables, it is a little bit more complicated. + However, if you are using the just-in-time optimization feature, it is + not possible to save and reload the JIT data. If you save compiled patterns to a file, you can copy them to a differ- - ent host and run them there. This works even if the new host has the - opposite endianness to the one on which the patterns were compiled. - There may be a small performance penalty, but it should be insignifi- - cant. However, compiling regular expressions with one version of PCRE - for use with a different version is not guaranteed to work and may - cause crashes. + ent host and run them there. If the two hosts have different endianness + (byte order), you should run the pcre[16]_pattern_to_host_byte_order() + function on the new host before trying to match the pattern. The match- + ing functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern + with the wrong endianness. + + Compiling regular expressions with one version of PCRE for use with a + different version is not guaranteed to work and may cause crashes, and + saving and restoring a compiled pattern loses any JIT optimization + data. SAVING A COMPILED PATTERN - The value returned by pcre_compile() points to a single block of memory - that holds the compiled pattern and associated data. You can find the - length of this block in bytes by calling pcre_fullinfo() with an argu- - ment of PCRE_INFO_SIZE. You can then save the data in any appropriate - manner. Here is sample code that compiles a pattern and writes it to a - file. It assumes that the variable fd refers to a file that is open for - output: + The value returned by pcre[16]_compile() points to a single block of + memory that holds the compiled pattern and associated data. You can + find the length of this block in bytes by calling pcre[16]_fullinfo() + with an argument of PCRE_INFO_SIZE. You can then save the data in any + appropriate manner. Here is sample code for the 8-bit library that com- + piles a pattern and writes it to a file. It assumes that the variable + fd refers to a file that is open for output: int erroroffset, rc, size; char *error; @@ -6549,45 +7983,49 @@ in the memory of some daemon process that passes them via sockets to the processes that want them. - If the pattern has been studied, it is also possible to save the study - data in a similar way to the compiled pattern itself. When studying - generates additional information, pcre_study() returns a pointer to a - pcre_extra data block. Its format is defined in the section on matching - a pattern in the pcreapi documentation. The study_data field points to - the binary study data, and this is what you must save (not the - pcre_extra block itself). The length of the study data can be obtained - by calling pcre_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. - Remember to check that pcre_study() did return a non-NULL value before - trying to save the study data. + If the pattern has been studied, it is also possible to save the normal + study data in a similar way to the compiled pattern itself. However, if + the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is cre- + ated cannot be saved because it is too dependent on the current envi- + ronment. When studying generates additional information, + pcre[16]_study() returns a pointer to a pcre[16]_extra data block. Its + format is defined in the section on matching a pattern in the pcreapi + documentation. The study_data field points to the binary study data, + and this is what you must save (not the pcre[16]_extra block itself). + The length of the study data can be obtained by calling + pcre[16]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remember + to check that pcre[16]_study() did return a non-NULL value before try- + ing to save the study data. RE-USING A PRECOMPILED PATTERN - Re-using a precompiled pattern is straightforward. Having reloaded it - into main memory, you pass its pointer to pcre_exec() or - pcre_dfa_exec() in the usual way. This should work even on another - host, and even if that host has the opposite endianness to the one - where the pattern was compiled. + Re-using a precompiled pattern is straightforward. Having reloaded it + into main memory, called pcre[16]_pattern_to_host_byte_order() if nec- + essary, you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() + in the usual way. However, if you passed a pointer to custom character tables when the - pattern was compiled (the tableptr argument of pcre_compile()), you - must now pass a similar pointer to pcre_exec() or pcre_dfa_exec(), - because the value saved with the compiled pattern will obviously be - nonsense. A field in a pcre_extra() block is used to pass this data, as - described in the section on matching a pattern in the pcreapi documen- - tation. + pattern was compiled (the tableptr argument of pcre[16]_compile()), you + must now pass a similar pointer to pcre[16]_exec() or + pcre[16]_dfa_exec(), because the value saved with the compiled pattern + will obviously be nonsense. A field in a pcre[16]_extra() block is used + to pass this data, as described in the section on matching a pattern in + the pcreapi documentation. If you did not provide custom character tables when the pattern was - compiled, the pointer in the compiled pattern is NULL, which causes - pcre_exec() to use PCRE's internal tables. Thus, you do not need to - take any special action at run time in this case. + compiled, the pointer in the compiled pattern is NULL, which causes the + matching functions to use PCRE's internal tables. Thus, you do not need + to take any special action at run time in this case. If you saved study data with the compiled pattern, you need to create - your own pcre_extra data block and set the study_data field to point to - the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA - bit in the flags field to indicate that study data is present. Then - pass the pcre_extra block to pcre_exec() or pcre_dfa_exec() in the - usual way. + your own pcre[16]_extra data block and set the study_data field to + point to the reloaded study data. You must also set the + PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study + data is present. Then pass the pcre[16]_extra block to the matching + function in the usual way. If the pattern was studied for just-in-time + optimization, that data cannot be saved, and so is lost by a + save/restore cycle. COMPATIBILITY WITH DIFFERENT PCRE RELEASES @@ -6606,8 +8044,8 @@ REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6627,12 +8065,12 @@ COMPILED PATTERN MEMORY USAGE - Patterns are compiled by PCRE into a reasonably efficient byte code, so - that most simple patterns do not use much memory. However, there is one - case where the memory usage of a compiled pattern can be unexpectedly - large. If a parenthesized subpattern has a quantifier with a minimum - greater than 1 and/or a limited maximum, the whole subpattern is - repeated in the compiled code. For example, the pattern + Patterns are compiled by PCRE into a reasonably efficient interpretive + code, so that most simple patterns do not use much memory. However, + there is one case where the memory usage of a compiled pattern can be + unexpectedly large. If a parenthesized subpattern has a quantifier with + a minimum greater than 1 and/or a limited maximum, the whole subpattern + is repeated in the compiled code. For example, the pattern (abc|def){2,4} @@ -6650,64 +8088,66 @@ ((ab){1,1000}c){1,3} - uses 51K bytes when compiled. When PCRE is compiled with its default - internal pointer size of two bytes, the size limit on a compiled pat- - tern is 64K, and this is reached with the above pattern if the outer - repetition is increased from 3 to 4. PCRE can be compiled to use larger - internal pointers and thus handle larger compiled patterns, but it is - better to try to rewrite your pattern to use less memory if you can. + uses 51K bytes when compiled using the 8-bit library. When PCRE is com- + piled with its default internal pointer size of two bytes, the size + limit on a compiled pattern is 64K data units, and this is reached with + the above pattern if the outer repetition is increased from 3 to 4. + PCRE can be compiled to use larger internal pointers and thus handle + larger compiled patterns, but it is better to try to rewrite your pat- + tern to use less memory if you can. - One way of reducing the memory usage for such patterns is to make use + One way of reducing the memory usage for such patterns is to make use of PCRE's "subroutine" facility. Re-writing the above pattern as ((ab)(?2){0,999}c)(?1){0,2} reduces the memory requirements to 18K, and indeed it remains under 20K - even with the outer repetition increased to 100. However, this pattern - is not exactly equivalent, because the "subroutine" calls are treated - as atomic groups into which there can be no backtracking if there is a - subsequent matching failure. Therefore, PCRE cannot do this kind of - rewriting automatically. Furthermore, there is a noticeable loss of - speed when executing the modified pattern. Nevertheless, if the atomic - grouping is not a problem and the loss of speed is acceptable, this - kind of rewriting will allow you to process patterns that PCRE cannot + even with the outer repetition increased to 100. However, this pattern + is not exactly equivalent, because the "subroutine" calls are treated + as atomic groups into which there can be no backtracking if there is a + subsequent matching failure. Therefore, PCRE cannot do this kind of + rewriting automatically. Furthermore, there is a noticeable loss of + speed when executing the modified pattern. Nevertheless, if the atomic + grouping is not a problem and the loss of speed is acceptable, this + kind of rewriting will allow you to process patterns that PCRE cannot otherwise handle. STACK USAGE AT RUN TIME - When pcre_exec() is used for matching, certain kinds of pattern can - cause it to use large amounts of the process stack. In some environ- - ments the default process stack is quite small, and if it runs out the - result is often SIGSEGV. This issue is probably the most frequently - raised problem with PCRE. Rewriting your pattern can often help. The - pcrestack documentation discusses this issue in detail. + When pcre_exec() or pcre16_exec() is used for matching, certain kinds + of pattern can cause it to use large amounts of the process stack. In + some environments the default process stack is quite small, and if it + runs out the result is often SIGSEGV. This issue is probably the most + frequently raised problem with PCRE. Rewriting your pattern can often + help. The pcrestack documentation discusses this issue in detail. PROCESSING TIME - Certain items in regular expression patterns are processed more effi- + Certain items in regular expression patterns are processed more effi- ciently than others. It is more efficient to use a character class like - [aeiou] than a set of single-character alternatives such as - (a|e|i|o|u). In general, the simplest construction that provides the + [aeiou] than a set of single-character alternatives such as + (a|e|i|o|u). In general, the simplest construction that provides the required behaviour is usually the most efficient. Jeffrey Friedl's book - contains a lot of useful general discussion about optimizing regular - expressions for efficient performance. This document contains a few + contains a lot of useful general discussion about optimizing regular + expressions for efficient performance. This document contains a few observations about PCRE. - Using Unicode character properties (the \p, \P, and \X escapes) is - slow, because PCRE has to scan a structure that contains data for over - fifteen thousand characters whenever it needs a character's property. - If you can find an alternative pattern that does not use character + Using Unicode character properties (the \p, \P, and \X escapes) is + slow, because PCRE has to scan a structure that contains data for over + fifteen thousand characters whenever it needs a character's property. + If you can find an alternative pattern that does not use character properties, it will probably be faster. - By default, the escape sequences \b, \d, \s, and \w, and the POSIX - character classes such as [:alpha:] do not use Unicode properties, + By default, the escape sequences \b, \d, \s, and \w, and the POSIX + character classes such as [:alpha:] do not use Unicode properties, partly for backwards compatibility, and partly for performance reasons. - However, you can set PCRE_UCP if you want Unicode character properties - to be used. This can double the matching time for items such as \d, - when matched with pcre_exec(); the performance loss is less with - pcre_dfa_exec(), and in both cases there is not much difference for \b. + However, you can set PCRE_UCP if you want Unicode character properties + to be used. This can double the matching time for items such as \d, + when matched with a traditional matching function; the performance loss + is less with a DFA matching function, and in both cases there is not + much difference for \b. When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option @@ -6774,8 +8214,8 @@ REVISION - Last updated: 16 May 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 09 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -6804,51 +8244,52 @@ DESCRIPTION - This set of functions provides a POSIX-style API to the PCRE regular - expression package. See the pcreapi documentation for a description of - PCRE's native API, which contains much additional functionality. + This set of functions provides a POSIX-style API for the PCRE regular + expression 8-bit library. See the pcreapi documentation for a descrip- + tion of PCRE's native API, which contains much additional functional- + ity. There is no POSIX-style wrapper for PCRE's 16-bit library. The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the - pcreposix.h header file, and on Unix systems the library itself is - called pcreposix.a, so can be accessed by adding -lpcreposix to the - command for linking an application that uses them. Because the POSIX + pcreposix.h header file, and on Unix systems the library itself is + called pcreposix.a, so can be accessed by adding -lpcreposix to the + command for linking an application that uses them. Because the POSIX functions call the native ones, it is also necessary to add -lpcre. - I have implemented only those POSIX option bits that can be reasonably - mapped to PCRE native options. In addition, the option REG_EXTENDED is - defined with the value zero. This has no effect, but since programs - that are written to the POSIX interface often use it, this makes it - easier to slot in PCRE as a replacement library. Other POSIX options + I have implemented only those POSIX option bits that can be reasonably + mapped to PCRE native options. In addition, the option REG_EXTENDED is + defined with the value zero. This has no effect, but since programs + that are written to the POSIX interface often use it, this makes it + easier to slot in PCRE as a replacement library. Other POSIX options are not even defined. - There are also some other options that are not defined by POSIX. These + There are also some other options that are not defined by POSIX. These have been added at the request of users who want to make use of certain PCRE-specific features via the POSIX calling interface. - When PCRE is called via these functions, it is only the API that is - POSIX-like in style. The syntax and semantics of the regular expres- - sions themselves are still those of Perl, subject to the setting of - various PCRE options, as described below. "POSIX-like in style" means - that the API approximates to the POSIX definition; it is not fully - POSIX-compatible, and in multi-byte encoding domains it is probably + When PCRE is called via these functions, it is only the API that is + POSIX-like in style. The syntax and semantics of the regular expres- + sions themselves are still those of Perl, subject to the setting of + various PCRE options, as described below. "POSIX-like in style" means + that the API approximates to the POSIX definition; it is not fully + POSIX-compatible, and in multi-byte encoding domains it is probably even less compatible. - The header for these functions is supplied as pcreposix.h to avoid any - potential clash with other POSIX libraries. It can, of course, be + The header for these functions is supplied as pcreposix.h to avoid any + potential clash with other POSIX libraries. It can, of course, be renamed or aliased as regex.h, which is the "correct" name. It provides - two structure types, regex_t for compiled internal forms, and reg- - match_t for returning captured substrings. It also defines some con- - stants whose names start with "REG_"; these are used for setting + two structure types, regex_t for compiled internal forms, and reg- + match_t for returning captured substrings. It also defines some con- + stants whose names start with "REG_"; these are used for setting options and identifying error codes. COMPILING A PATTERN - The function regcomp() is called to compile a pattern into an internal - form. The pattern is a C string terminated by a binary zero, and is - passed in the argument pattern. The preg argument is a pointer to a - regex_t structure that is used as a base for storing information about + The function regcomp() is called to compile a pattern into an internal + form. The pattern is a C string terminated by a binary zero, and is + passed in the argument pattern. The preg argument is a pointer to a + regex_t structure that is used as a base for storing information about the compiled regular expression. The argument cflags is either zero, or contains one or more of the bits @@ -6862,58 +8303,58 @@ REG_ICASE - The PCRE_CASELESS option is set when the regular expression is passed + The PCRE_CASELESS option is set when the regular expression is passed for compilation to the native function. REG_NEWLINE - The PCRE_MULTILINE option is set when the regular expression is passed - for compilation to the native function. Note that this does not mimic - the defined POSIX behaviour for REG_NEWLINE (see the following sec- + The PCRE_MULTILINE option is set when the regular expression is passed + for compilation to the native function. Note that this does not mimic + the defined POSIX behaviour for REG_NEWLINE (see the following sec- tion). REG_NOSUB - The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is + The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is passed for compilation to the native function. In addition, when a pat- - tern that is compiled with this flag is passed to regexec() for match- - ing, the nmatch and pmatch arguments are ignored, and no captured + tern that is compiled with this flag is passed to regexec() for match- + ing, the nmatch and pmatch arguments are ignored, and no captured strings are returned. REG_UCP - The PCRE_UCP option is set when the regular expression is passed for - compilation to the native function. This causes PCRE to use Unicode - properties when matchine \d, \w, etc., instead of just recognizing + The PCRE_UCP option is set when the regular expression is passed for + compilation to the native function. This causes PCRE to use Unicode + properties when matchine \d, \w, etc., instead of just recognizing ASCII values. Note that REG_UTF8 is not part of the POSIX standard. REG_UNGREEDY - The PCRE_UNGREEDY option is set when the regular expression is passed - for compilation to the native function. Note that REG_UNGREEDY is not + The PCRE_UNGREEDY option is set when the regular expression is passed + for compilation to the native function. Note that REG_UNGREEDY is not part of the POSIX standard. REG_UTF8 - The PCRE_UTF8 option is set when the regular expression is passed for - compilation to the native function. This causes the pattern itself and - all data strings used for matching it to be treated as UTF-8 strings. + The PCRE_UTF8 option is set when the regular expression is passed for + compilation to the native function. This causes the pattern itself and + all data strings used for matching it to be treated as UTF-8 strings. Note that REG_UTF8 is not part of the POSIX standard. - In the absence of these flags, no options are passed to the native - function. This means the the regex is compiled with PCRE default - semantics. In particular, the way it handles newline characters in the - subject string is the Perl way, not the POSIX way. Note that setting - PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. - It does not affect the way newlines are matched by . (they are not) or + In the absence of these flags, no options are passed to the native + function. This means the the regex is compiled with PCRE default + semantics. In particular, the way it handles newline characters in the + subject string is the Perl way, not the POSIX way. Note that setting + PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE. + It does not affect the way newlines are matched by . (they are not) or by a negative class such as [^a] (they are). - The yield of regcomp() is zero on success, and non-zero otherwise. The + The yield of regcomp() is zero on success, and non-zero otherwise. The preg structure is filled in on success, and one member of the structure - is public: re_nsub contains the number of capturing subpatterns in the + is public: re_nsub contains the number of capturing subpatterns in the regular expression. Various error codes are defined in the header file. - NOTE: If the yield of regcomp() is non-zero, you must not attempt to + NOTE: If the yield of regcomp() is non-zero, you must not attempt to use the contents of the preg structure. If, for example, you pass it to regexec(), the result is undefined and your program is likely to crash. @@ -6921,9 +8362,9 @@ MATCHING NEWLINE CHARACTERS This area is not simple, because POSIX and Perl take different views of - things. It is not possible to get PCRE to obey POSIX semantics, but - then PCRE was never intended to be a POSIX engine. The following table - lists the different possibilities for matching newline characters in + things. It is not possible to get PCRE to obey POSIX semantics, but + then PCRE was never intended to be a POSIX engine. The following table + lists the different possibilities for matching newline characters in PCRE: Default Change with @@ -6945,19 +8386,19 @@ ^ matches \n in middle no REG_NEWLINE PCRE's behaviour is the same as Perl's, except that there is no equiva- - lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is + lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is no way to stop newline from matching [^a]. - The default POSIX newline handling can be obtained by setting - PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE + The default POSIX newline handling can be obtained by setting + PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE behave exactly as for the REG_NEWLINE action. MATCHING A PATTERN - The function regexec() is called to match a compiled pattern preg - against a given string, which is by default terminated by a zero byte - (but see REG_STARTEND below), subject to the options in eflags. These + The function regexec() is called to match a compiled pattern preg + against a given string, which is by default terminated by a zero byte + (but see REG_STARTEND below), subject to the options in eflags. These can be: REG_NOTBOL @@ -6979,17 +8420,17 @@ REG_STARTEND - The string is considered to start at string + pmatch[0].rm_so and to - have a terminating NUL located at string + pmatch[0].rm_eo (there need - not actually be a NUL at that location), regardless of the value of - nmatch. This is a BSD extension, compatible with but not specified by - IEEE Standard 1003.2 (POSIX.2), and should be used with caution in + The string is considered to start at string + pmatch[0].rm_so and to + have a terminating NUL located at string + pmatch[0].rm_eo (there need + not actually be a NUL at that location), regardless of the value of + nmatch. This is a BSD extension, compatible with but not specified by + IEEE Standard 1003.2 (POSIX.2), and should be used with caution in software intended to be portable to other systems. Note that a non-zero rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location of the string, not how it is matched. - If the pattern was compiled with the REG_NOSUB flag, no data about any - matched strings is returned. The nmatch and pmatch arguments of + If the pattern was compiled with the REG_NOSUB flag, no data about any + matched strings is returned. The nmatch and pmatch arguments of regexec() are ignored. If the value of nmatch is zero, or if the value pmatch is NULL, no data @@ -6997,34 +8438,34 @@ Otherwise,the portion of the string that was matched, and also any cap- tured substrings, are returned via the pmatch argument, which points to - an array of nmatch structures of type regmatch_t, containing the mem- - bers rm_so and rm_eo. These contain the offset to the first character - of each substring and the offset to the first character after the end - of each substring, respectively. The 0th element of the vector relates - to the entire portion of string that was matched; subsequent elements - relate to the capturing subpatterns of the regular expression. Unused + an array of nmatch structures of type regmatch_t, containing the mem- + bers rm_so and rm_eo. These contain the offset to the first character + of each substring and the offset to the first character after the end + of each substring, respectively. The 0th element of the vector relates + to the entire portion of string that was matched; subsequent elements + relate to the capturing subpatterns of the regular expression. Unused entries in the array have both structure members set to -1. - A successful match yields a zero return; various error codes are - defined in the header file, of which REG_NOMATCH is the "expected" + A successful match yields a zero return; various error codes are + defined in the header file, of which REG_NOMATCH is the "expected" failure code. ERROR MESSAGES The regerror() function maps a non-zero errorcode from either regcomp() - or regexec() to a printable message. If preg is not NULL, the error + or regexec() to a printable message. If preg is not NULL, the error should have arisen from the use of that structure. A message terminated - by a binary zero is placed in errbuf. The length of the message, - including the zero, is limited to errbuf_size. The yield of the func- + by a binary zero is placed in errbuf. The length of the message, + including the zero, is limited to errbuf_size. The yield of the func- tion is the size of buffer needed to hold the whole message. MEMORY USAGE - Compiling a regular expression causes memory to be allocated and asso- - ciated with the preg structure. The function regfree() frees all such - memory, after which preg may no longer be used as a compiled expres- + Compiling a regular expression causes memory to be allocated and asso- + ciated with the preg structure. The function regfree() frees all such + memory, after which preg may no longer be used as a compiled expres- sion. @@ -7037,8 +8478,8 @@ REVISION - Last updated: 16 May 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 09 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ @@ -7059,13 +8500,14 @@ The C++ wrapper for PCRE was provided by Google Inc. Some additional functionality was added by Giuseppe Maxia. This brief man page was con- structed from the notes in the pcrecpp.h file, which should be con- - sulted for further details. + sulted for further details. Note that the C++ wrapper supports only the + original 8-bit PCRE library. There is no 16-bit support at present. MATCHING INTERFACE - The "FullMatch" operation checks that supplied text matches a supplied - pattern exactly. If pointer arguments are supplied, it copies matched + The "FullMatch" operation checks that supplied text matches a supplied + pattern exactly. If pointer arguments are supplied, it copies matched sub-strings that match sub-patterns into them. Example: successful match @@ -7079,10 +8521,10 @@ Example: creating a temporary RE object: pcrecpp::RE("h.*o").FullMatch("hello"); - You can pass in a "const char*" or a "string" for "text". The examples - below tend to use a const char*. You can, as in the different examples - above, store the RE object explicitly in a variable or use a temporary - RE object. The examples below use one mode or the other arbitrarily. + You can pass in a "const char*" or a "string" for "text". The examples + below tend to use a const char*. You can, as in the different examples + above, store the RE object explicitly in a variable or use a temporary + RE object. The examples below use one mode or the other arbitrarily. Either could correctly be used for any of these examples. You must supply extra pointer arguments to extract matched subpieces. @@ -7108,7 +8550,7 @@ Example: fails because string cannot be stored in integer !pcrecpp::RE("(.*)").FullMatch("ruby", &i); - The provided pointer arguments can be pointers to any scalar numeric + The provided pointer arguments can be pointers to any scalar numeric type, or one of: string (matched piece is copied to string) @@ -7116,7 +8558,7 @@ T (where "bool T::ParseFrom(const char*, int)" exists) NULL (the corresponding matched sub-pattern is not copied) - The function returns true iff all of the following conditions are sat- + The function returns true iff all of the following conditions are sat- isfied: a. "text" matches "pattern" exactly; @@ -7131,41 +8573,41 @@ number of sub-patterns, "i"th captured sub-pattern is ignored. - CAVEAT: An optional sub-pattern that does not exist in the matched - string is assigned the empty string. Therefore, the following will + CAVEAT: An optional sub-pattern that does not exist in the matched + string is assigned the empty string. Therefore, the following will return false (because the empty string is not a valid number): int number; pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); - The matching interface supports at most 16 arguments per call. If you - need more, consider using the more general interface + The matching interface supports at most 16 arguments per call. If you + need more, consider using the more general interface pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch. - NOTE: Do not use no_arg, which is used internally to mark the end of a - list of optional arguments, as a placeholder for missing arguments, as + NOTE: Do not use no_arg, which is used internally to mark the end of a + list of optional arguments, as a placeholder for missing arguments, as this can lead to segfaults. QUOTING METACHARACTERS - You can use the "QuoteMeta" operation to insert backslashes before all - potentially meaningful characters in a string. The returned string, + You can use the "QuoteMeta" operation to insert backslashes before all + potentially meaningful characters in a string. The returned string, used as a regular expression, will exactly match the original string. Example: string quoted = RE::QuoteMeta(unquoted); - Note that it's legal to escape a character even if it has no special - meaning in a regular expression -- so this function does that. (This - also makes it identical to the perl function of the same name; see - "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes + Note that it's legal to escape a character even if it has no special + meaning in a regular expression -- so this function does that. (This + also makes it identical to the perl function of the same name; see + "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes "1\.5\-2\.0\?". PARTIAL MATCHES - You can use the "PartialMatch" operation when you want the pattern to + You can use the "PartialMatch" operation when you want the pattern to match any substring of the text. Example: simple search for a string: @@ -7180,13 +8622,13 @@ UTF-8 AND THE MATCHING INTERFACE - By default, pattern and text are plain text, one byte per character. - The UTF8 flag, passed to the constructor, causes both pattern and + By default, pattern and text are plain text, one byte per character. + The UTF8 flag, passed to the constructor, causes both pattern and string to be treated as UTF-8 text, still a byte stream but potentially - multiple bytes per character. In practice, the text is likelier to be - UTF-8 than the pattern, but the match returned may depend on the UTF8 - flag, so always use it when matching UTF8 text. For example, "." will - match one byte normally but with UTF8 set may match up to three bytes + multiple bytes per character. In practice, the text is likelier to be + UTF-8 than the pattern, but the match returned may depend on the UTF8 + flag, so always use it when matching UTF8 text. For example, "." will + match one byte normally but with UTF8 set may match up to three bytes of a multi-byte character. Example: @@ -7205,9 +8647,9 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE - PCRE defines some modifiers to change the behavior of the regular - expression engine. The C++ wrapper defines an auxiliary class, - RE_Options, as a vehicle to pass such modifiers to a RE class. Cur- + PCRE defines some modifiers to change the behavior of the regular + expression engine. The C++ wrapper defines an auxiliary class, + RE_Options, as a vehicle to pass such modifiers to a RE class. Cur- rently, the following modifiers are supported: modifier description Perl corresponding @@ -7217,20 +8659,20 @@ PCRE_DOTALL dot matches newlines /s PCRE_DOLLAR_ENDONLY $ matches only at end N/A PCRE_EXTRA strict escape parsing N/A - PCRE_EXTENDED ignore whitespaces /x + PCRE_EXTENDED ignore white spaces /x PCRE_UTF8 handles UTF8 chars built-in PCRE_UNGREEDY reverses * and *? N/A PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*) - (*) Both Perl and PCRE allow non capturing parentheses by means of the - "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap- + (*) Both Perl and PCRE allow non capturing parentheses by means of the + "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap- ture, while (ab|cd) does. - For a full account on how each modifier works, please check the PCRE + For a full account on how each modifier works, please check the PCRE API reference page. - For each modifier, there are two member functions whose name is made - out of the modifier in lowercase, without the "PCRE_" prefix. For + For each modifier, there are two member functions whose name is made + out of the modifier in lowercase, without the "PCRE_" prefix. For instance, PCRE_CASELESS is handled by bool caseless() @@ -7240,28 +8682,28 @@ RE_Options & set_caseless(bool) which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can - be accessed through the set_match_limit() and match_limit() member - functions. Setting match_limit to a non-zero value will limit the exe- - cution of pcre to keep it from doing bad things like blowing the stack - or taking an eternity to return a result. A value of 5000 is good - enough to stop stack blowup in a 2MB thread stack. Setting match_limit - to zero disables match limiting. Alternatively, you can call - match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to - limit how much PCRE recurses. match_limit() limits the number of + be accessed through the set_match_limit() and match_limit() member + functions. Setting match_limit to a non-zero value will limit the exe- + cution of pcre to keep it from doing bad things like blowing the stack + or taking an eternity to return a result. A value of 5000 is good + enough to stop stack blowup in a 2MB thread stack. Setting match_limit + to zero disables match limiting. Alternatively, you can call + match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to + limit how much PCRE recurses. match_limit() limits the number of matches PCRE does; match_limit_recursion() limits the depth of internal recursion, and therefore the amount of stack that is used. - Normally, to pass one or more modifiers to a RE class, you declare a + Normally, to pass one or more modifiers to a RE class, you declare a RE_Options object, set the appropriate options, and pass this object to a RE constructor. Example: - RE_options opt; + RE_Options opt; opt.set_caseless(true); if (RE("HELLO", opt).PartialMatch("hello world")) ... RE_options has two constructors. The default constructor takes no argu- - ments and creates a set of flags that are off by default. The optional - parameter option_flags is to facilitate transfer of legacy code from C + ments and creates a set of flags that are off by default. The optional + parameter option_flags is to facilitate transfer of legacy code from C programs. This lets you do RE(pattern, @@ -7275,15 +8717,15 @@ If you are going to pass one of the most used modifiers, there are some convenience functions that return a RE_Options class with the appropri- - ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), + ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(), and EXTENDED(). - If you need to set several options at once, and you don't want to go - through the pains of declaring a RE_Options object and setting several - options, there is a parallel method that give you such ability on the - fly. You can concatenate several set_xxxxx() member functions, since - each of them returns a reference to its class object. For example, to - pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one + If you need to set several options at once, and you don't want to go + through the pains of declaring a RE_Options object and setting several + options, there is a parallel method that give you such ability on the + fly. You can concatenate several set_xxxxx() member functions, since + each of them returns a reference to its class object. For example, to + pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one statement, you may write: RE(" ^ xyz \\s+ .* blah$", @@ -7295,10 +8737,10 @@ SCANNING TEXT INCREMENTALLY - The "Consume" operation may be useful if you want to repeatedly match + The "Consume" operation may be useful if you want to repeatedly match regular expressions at the front of a string and skip over them as they - match. This requires use of the "StringPiece" type, which represents a - sub-range of a real string. Like RE, StringPiece is defined in the + match. This requires use of the "StringPiece" type, which represents a + sub-range of a real string. Like RE, StringPiece is defined in the pcrecpp namespace. Example: read lines of the form "var = value" from a string. @@ -7312,11 +8754,11 @@ ...; } - Each successful call to "Consume" will set "var/value", and also + Each successful call to "Consume" will set "var/value", and also advance "input" so it points past the matched text. - The "FindAndConsume" operation is similar to "Consume" but does not - anchor your match at the beginning of the string. For example, you + The "FindAndConsume" operation is similar to "Consume" but does not + anchor your match at the beginning of the string. For example, you could extract all words from a string by repeatedly calling pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) @@ -7325,10 +8767,10 @@ PARSING HEX/OCTAL/C-RADIX NUMBERS By default, if you pass a pointer to a numeric value, the corresponding - text is interpreted as a base-10 number. You can instead wrap the + text is interpreted as a base-10 number. You can instead wrap the pointer with a call to one of the operators Hex(), Octal(), or CRadix() - to interpret the text in another base. The CRadix operator interprets - C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to + to interpret the text in another base. The CRadix operator interprets + C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to base-10. Example: @@ -7343,30 +8785,30 @@ REPLACING PARTS OF STRINGS - You can replace the first match of "pattern" in "str" with "rewrite". - Within "rewrite", backslash-escaped digits (\1 to \9) can be used to - insert text matching corresponding parenthesized group from the pat- + You can replace the first match of "pattern" in "str" with "rewrite". + Within "rewrite", backslash-escaped digits (\1 to \9) can be used to + insert text matching corresponding parenthesized group from the pat- tern. \0 in "rewrite" refers to the entire matching text. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").Replace("d", &s); - will leave "s" containing "yada dabba doo". The result is true if the + will leave "s" containing "yada dabba doo". The result is true if the pattern matches and a replacement occurs, false otherwise. - GlobalReplace is like Replace except that it replaces all occurrences - of the pattern in the string with the rewrite. Replacements are not + GlobalReplace is like Replace except that it replaces all occurrences + of the pattern in the string with the rewrite. Replacements are not subject to re-matching. For example: string s = "yabba dabba doo"; pcrecpp::RE("b+").GlobalReplace("d", &s); - will leave "s" containing "yada dada doo". It returns the number of + will leave "s" containing "yada dada doo". It returns the number of replacements made. - Extract is like Replace, except that if the pattern matches, "rewrite" - is copied into "out" (an additional argument) with substitutions. The - non-matching portions of "text" are ignored. Returns true iff a match + Extract is like Replace, except that if the pattern matches, "rewrite" + is copied into "out" (an additional argument) with substitutions. The + non-matching portions of "text" are ignored. Returns true iff a match occurred and the extraction happened successfully; if no match occurs, the string is left unaffected. @@ -7379,7 +8821,7 @@ REVISION - Last updated: 17 March 2009 + Last updated: 08 January 2012 ------------------------------------------------------------------------------ @@ -7398,57 +8840,58 @@ do not have a copy of the PCRE distribution, you can save this listing to re-create pcredemo.c. - The program compiles the regular expression that is its first argument, - and matches it against the subject string in its second argument. No - PCRE options are set, and default character tables are used. If match- - ing succeeds, the program outputs the portion of the subject that - matched, together with the contents of any captured substrings. + The demonstration program, which uses the original PCRE 8-bit library, + compiles the regular expression that is its first argument, and matches + it against the subject string in its second argument. No PCRE options + are set, and default character tables are used. If matching succeeds, + the program outputs the portion of the subject that matched, together + with the contents of any captured substrings. If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same - subject string. The logic is a little bit tricky because of the possi- - bility of matching an empty string. Comments in the code explain what + subject string. The logic is a little bit tricky because of the possi- + bility of matching an empty string. Comments in the code explain what is going on. - If PCRE is installed in the standard include and library directories + If PCRE is installed in the standard include and library directories for your operating system, you should be able to compile the demonstra- tion program using this command: gcc -o pcredemo pcredemo.c -lpcre - If PCRE is installed elsewhere, you may need to add additional options - to the command line. For example, on a Unix-like system that has PCRE - installed in /usr/local, you can compile the demonstration program + If PCRE is installed elsewhere, you may need to add additional options + to the command line. For example, on a Unix-like system that has PCRE + installed in /usr/local, you can compile the demonstration program using a command like this: gcc -o pcredemo -I/usr/local/include pcredemo.c \ -L/usr/local/lib -lpcre - In a Windows environment, if you want to statically link the program + In a Windows environment, if you want to statically link the program against a non-dll pcre.a file, you must uncomment the line that defines - PCRE_STATIC before including pcre.h, because otherwise the pcre_mal- + PCRE_STATIC before including pcre.h, because otherwise the pcre_mal- loc() and pcre_free() exported functions will be declared __declspec(dllimport), with unwanted results. - Once you have compiled and linked the demonstration program, you can + Once you have compiled and linked the demonstration program, you can run simple tests like this: ./pcredemo 'cat|dog' 'the cat sat on the mat' ./pcredemo -g 'cat|dog' 'the dog sat on the cat' - Note that there is a much more comprehensive test program, called - pcretest, which supports many more facilities for testing regular - expressions and the PCRE library. The pcredemo program is provided as a - simple coding example. + Note that there is a much more comprehensive test program, called + pcretest, which supports many more facilities for testing regular + expressions and both PCRE libraries. The pcredemo program is provided + as a simple coding example. - If you try to run pcredemo when PCRE is not installed in the standard - library directory, you may get an error like this on some operating + If you try to run pcredemo when PCRE is not installed in the standard + library directory, you may get an error like this on some operating systems (e.g. Solaris): - ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or + ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or directory - This is caused by the way shared library support works on those sys- + This is caused by the way shared library support works on those sys- tems. You need to add -R/usr/local/lib @@ -7465,9 +8908,71 @@ REVISION - Last updated: 17 November 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 10 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ +PCRELIMITS(3) PCRELIMITS(3) + + +NAME + PCRE - Perl-compatible regular expressions + + +SIZE AND OTHER LIMITATIONS + + There are some size limitations in PCRE but it is hoped that they will + never in practice be relevant. + + The maximum length of a compiled pattern is approximately 64K data + units (bytes for the 8-bit library, 16-bit units for the 16-bit + library) if PCRE is compiled with the default internal linkage size of + 2 bytes. If you want to process regular expressions that are truly + enormous, you can compile PCRE with an internal linkage size of 3 or 4 + (when building the 16-bit library, 3 is rounded up to 4). See the + README file in the source distribution and the pcrebuild documentation + for details. In these cases the limit is substantially larger. How- + ever, the speed of execution is slower. + + All values in repeating quantifiers must be less than 65536. + + There is no limit to the number of parenthesized subpatterns, but there + can be no more than 65535 capturing subpatterns. + + There is a limit to the number of forward references to subsequent sub- + patterns of around 200,000. Repeated forward references with fixed + upper limits, for example, (?2){0,100} when subpattern number 2 is to + the right, are included in the count. There is no limit to the number + of backward references. + + The maximum length of name for a named subpattern is 32 characters, and + the maximum number of named subpatterns is 10000. + + The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or + (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit + library. + + The maximum length of a subject string is the largest positive number + that an integer variable can hold. However, when using the traditional + matching function, PCRE uses recursion to handle subpatterns and indef- + inite repetition. This means that the available stack space may limit + the size of a subject string that can be processed by certain patterns. + For a discussion of stack issues, see the pcrestack documentation. + + +AUTHOR + + Philip Hazel + University Computing Service + Cambridge CB2 3QH, England. + + +REVISION + + Last updated: 04 May 2012 + Copyright (c) 1997-2012 University of Cambridge. +------------------------------------------------------------------------------ + + PCRESTACK(3) PCRESTACK(3) @@ -7477,12 +8982,14 @@ PCRE DISCUSSION OF STACK USAGE - When you call pcre_exec(), it makes use of an internal function called - match(). This calls itself recursively at branch points in the pattern, - in order to remember the state of the match so that it can back up and - try a different alternative if the first one fails. As matching pro- - ceeds deeper and deeper into the tree of possibilities, the recursion - depth increases. + When you call pcre[16]_exec(), it makes use of an internal function + called match(). This calls itself recursively at branch points in the + pattern, in order to remember the state of the match so that it can + back up and try a different alternative if the first one fails. As + matching proceeds deeper and deeper into the tree of possibilities, the + recursion depth increases. The match() function is also called in other + circumstances, for example, whenever a parenthesized sub-pattern is + entered, and in certain cases of repetition. Not all calls of match() increase the recursion depth; for an item such as a* it may be called several times at the same level, after matching @@ -7491,20 +8998,28 @@ result of the current call (a "tail recursion"), the function is just restarted instead. - The pcre_dfa_exec() function operates in an entirely different way, and - uses recursion only when there is a regular expression recursion or + The above comments apply when pcre[16]_exec() is run in its normal + interpretive manner. If the pattern was studied with the + PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was success- + ful, and the options passed to pcre[16]_exec() were not incompatible, + the matching process uses the JIT-compiled code instead of the match() + function. In this case, the memory requirements are handled entirely + differently. See the pcrejit documentation for details. + + The pcre[16]_dfa_exec() function operates in an entirely different way, + and uses recursion only when there is a regular expression recursion or subroutine call in the pattern. This includes the processing of asser- tion and "once-only" subpatterns, which are handled like subroutine calls. Normally, these are never very deep, and the limit on the com- - plexity of pcre_dfa_exec() is controlled by the amount of workspace it - is given. However, it is possible to write patterns with runaway infi- - nite recursions; such patterns will cause pcre_dfa_exec() to run out of - stack. At present, there is no protection against this. + plexity of pcre[16]_dfa_exec() is controlled by the amount of workspace + it is given. However, it is possible to write patterns with runaway + infinite recursions; such patterns will cause pcre[16]_dfa_exec() to + run out of stack. At present, there is no protection against this. - The comments that follow do NOT apply to pcre_dfa_exec(); they are rel- - evant only for pcre_exec(). + The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are + relevant only for pcre[16]_exec() without the JIT optimization. - Reducing pcre_exec()'s stack usage + Reducing pcre[16]_exec()'s stack usage Each time that match() is actually called recursively, it uses memory from the process stack. For certain kinds of pattern and data, very @@ -7537,31 +9052,31 @@ ing long subject strings is to write repeated parenthesized subpatterns to match more than one character whenever possible. - Compiling PCRE to use heap instead of stack for pcre_exec() + Compiling PCRE to use heap instead of stack for pcre[16]_exec() In environments where stack memory is constrained, you might want to compile PCRE to use heap memory instead of stack for remembering back- - up points when pcre_exec() is running. This makes it run a lot more + up points when pcre[16]_exec() is running. This makes it run a lot more slowly, however. Details of how to do this are given in the pcrebuild documentation. When built in this way, instead of using the stack, PCRE obtains and frees memory by calling the functions that are pointed to - by the pcre_stack_malloc and pcre_stack_free variables. By default, - these point to malloc() and free(), but you can replace the pointers to - cause PCRE to use your own functions. Since the block sizes are always - the same, and are always freed in reverse order, it may be possible to - implement customized memory handlers that are more efficient than the - standard functions. + by the pcre[16]_stack_malloc and pcre[16]_stack_free variables. By + default, these point to malloc() and free(), but you can replace the + pointers to cause PCRE to use your own functions. Since the block sizes + are always the same, and are always freed in reverse order, it may be + possible to implement customized memory handlers that are more effi- + cient than the standard functions. - Limiting pcre_exec()'s stack usage + Limiting pcre[16]_exec()'s stack usage You can set limits on the number of times that match() is called, both - in total and recursively. If a limit is exceeded, pcre_exec() returns - an error code. Setting suitable limits should prevent it from running - out of stack. The default values of the limits are very large, and - unlikely ever to operate. They can be changed when PCRE is built, and - they can also be set when pcre_exec() is called. For details of these - interfaces, see the pcrebuild documentation and the section on extra - data for pcre_exec() in the pcreapi documentation. + in total and recursively. If a limit is exceeded, pcre[16]_exec() + returns an error code. Setting suitable limits should prevent it from + running out of stack. The default values of the limits are very large, + and unlikely ever to operate. They can be changed when PCRE is built, + and they can also be set when pcre[16]_exec() is called. For details of + these interfaces, see the pcrebuild documentation and the section on + extra data for pcre[16]_exec() in the pcreapi documentation. As a very rough rule of thumb, you should reckon on about 500 bytes per recursion. Thus, if you want to limit your stack usage to 8Mb, you @@ -7572,9 +9087,33 @@ option (-S) that can be used to increase the size of its stack. As long as the stack is large enough, another option (-M) can be used to find the smallest limits that allow a particular pattern to match a given - subject string. This is done by calling pcre_exec() repeatedly with + subject string. This is done by calling pcre[16]_exec() repeatedly with different limits. + Obtaining an estimate of stack usage + + The actual amount of stack used per recursion can vary quite a lot, + depending on the compiler that was used to build PCRE and the optimiza- + tion or debugging options that were set for it. The rule of thumb value + of 500 bytes mentioned above may be larger or smaller than what is + actually needed. A better approximation can be obtained by running this + command: + + pcretest -m -C + + The -C option causes pcretest to output information about the options + with which PCRE was compiled. When -m is also given (before -C), infor- + mation about stack use is given in a line like this: + + Match recursion uses stack: approximate frame size = 640 bytes + + The value is approximate because some recursions need a bit more (up to + perhaps 16 more bytes). + + If the above command is given when PCRE is compiled to use the heap + instead of the stack for recursion, the value that is output is the + size of each block that is obtained from the heap. + Changing stack size in Unix-like systems In Unix-like environments, there is not often a problem with the stack @@ -7595,7 +9134,7 @@ This reads the current limits (soft and hard) using getrlimit(), then attempts to increase the soft limit to 100Mb using setrlimit(). You - must do this before calling pcre_exec(). + must do this before calling pcre[16]_exec(). Changing stack size in Mac OS X @@ -7614,8 +9153,8 @@ REVISION - Last updated: 03 January 2010 - Copyright (c) 1997-2010 University of Cambridge. + Last updated: 21 January 2012 + Copyright (c) 1997-2012 University of Cambridge. ------------------------------------------------------------------------------ diff -Nru pcre3-8.12/doc/pcre16.3 pcre3-8.31/doc/pcre16.3 --- pcre3-8.12/doc/pcre16.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre16.3 2012-06-02 10:55:17.000000000 +0000 @@ -0,0 +1,389 @@ +.TH PCRE 3 "14 April 2012" "PCRE 8.31" +.SH NAME +PCRE - Perl-compatible regular expressions +.sp +.B #include +. +. +.SH "PCRE 16-BIT API BASIC FUNCTIONS" +.rs +.sp +.SM +.B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP, int *\fIerroffset\fP, +.ti +5n +.B const unsigned char *\fItableptr\fP); +.PP +.B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, +.ti +5n +.B int *\fIerrorcodeptr\fP, +.ti +5n +.B const char **\fIerrptr\fP, int *\fIerroffset\fP, +.ti +5n +.B const unsigned char *\fItableptr\fP); +.PP +.B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP); +.PP +.B void pcre16_free_study(pcre16_extra *\fIextra\fP); +.PP +.B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.PP +.B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, +.ti +5n +.B int *\fIworkspace\fP, int \fIwscount\fP); +. +. +.SH "PCRE 16-BIT API STRING EXTRACTION FUNCTIONS" +.rs +.sp +.B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, +.ti +5n +.B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP); +.PP +.B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); +.PP +.B int pcre16_get_named_substring(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, +.ti +5n +.B PCRE_SPTR16 *\fIstringptr\fP); +.PP +.B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIname\fP); +.PP +.B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP); +.PP +.B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B PCRE_SPTR16 *\fIstringptr\fP); +.PP +.B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP, +.ti +5n +.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);" +.PP +.B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); +.PP +.B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); +. +. +.SH "PCRE 16-BIT API AUXILIARY FUNCTIONS" +.rs +.sp +.B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); +.PP +.B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP); +.PP +.B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, +.ti +5n +.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); +.PP +.B const unsigned char *pcre16_maketables(void); +.PP +.B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); +.PP +.B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B const char *pcre16_version(void); +.PP +.B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, +.ti +5n +.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); +. +. +.SH "PCRE 16-BIT API INDIRECTED FUNCTIONS" +.rs +.sp +.B void *(*pcre16_malloc)(size_t); +.PP +.B void (*pcre16_free)(void *); +.PP +.B void *(*pcre16_stack_malloc)(size_t); +.PP +.B void (*pcre16_stack_free)(void *); +.PP +.B int (*pcre16_callout)(pcre16_callout_block *); +. +. +.SH "PCRE 16-BIT API 16-BIT-ONLY FUNCTION" +.rs +.sp +.B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP, +.ti +5n +.B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP, +.ti +5n +.B int \fIkeep_boms\fP); +. +. +.SH "THE PCRE 16-BIT LIBRARY" +.rs +.sp +Starting with release 8.30, it is possible to compile a PCRE library that +supports 16-bit character strings, including UTF-16 strings, as well as or +instead of the original 8-bit library. The majority of the work to make this +possible was done by Zoltan Herczeg. The two libraries contain identical sets +of functions, used in exactly the same way. Only the names of the functions and +the data types of their arguments and results are different. To avoid +over-complication and reduce the documentation maintenance load, most of the +PCRE documentation describes the 8-bit library, with only occasional references +to the 16-bit library. This page describes what is different when you use the +16-bit library. +.P +WARNING: A single application can be linked with both libraries, but you must +take care when processing any particular pattern to use functions from just one +library. For example, if you want to study a pattern that was compiled with +\fBpcre16_compile()\fP, you must do so with \fBpcre16_study()\fP, not +\fBpcre_study()\fP, and you must free the study data with +\fBpcre16_free_study()\fP. +. +. +.SH "THE HEADER FILE" +.rs +.sp +There is only one header file, \fBpcre.h\fP. It contains prototypes for all the +functions in both libraries, as well as definitions of flags, structures, error +codes, etc. +. +. +.SH "THE LIBRARY NAME" +.rs +.sp +In Unix-like systems, the 16-bit library is called \fBlibpcre16\fP, and can +normally be accesss by adding \fB-lpcre16\fP to the command for linking an +application that uses PCRE. +. +. +.SH "STRING TYPES" +.rs +.sp +In the 8-bit library, strings are passed to PCRE library functions as vectors +of bytes with the C type "char *". In the 16-bit library, strings are passed as +vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an +appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In +very many environments, "short int" is a 16-bit data type. When PCRE is built, +it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit +data type. If it is not, the build fails with an error message telling the +maintainer to modify the definition appropriately. +. +. +.SH "STRUCTURE TYPES" +.rs +.sp +The types of the opaque structures that are used for compiled 16-bit patterns +and JIT stacks are \fBpcre16\fP and \fBpcre16_jit_stack\fP respectively. The +type of the user-accessible structure that is returned by \fBpcre16_study()\fP +is \fBpcre16_extra\fP, and the type of the structure that is used for passing +data to a callout function is \fBpcre16_callout_block\fP. These structures +contain the same fields, with the same names, as their 8-bit counterparts. The +only difference is that pointers to character strings are 16-bit instead of +8-bit types. +. +. +.SH "16-BIT FUNCTIONS" +.rs +.sp +For every function in the 8-bit library there is a corresponding function in +the 16-bit library with a name that starts with \fBpcre16_\fP instead of +\fBpcre_\fP. The prototypes are listed above. In addition, there is one extra +function, \fBpcre16_utf16_to_host_byte_order()\fP. This is a utility function +that converts a UTF-16 character string to host byte order if necessary. The +other 16-bit functions expect the strings they are passed to be in host byte +order. +.P +The \fIinput\fP and \fIoutput\fP arguments of +\fBpcre16_utf16_to_host_byte_order()\fP may point to the same address, that is, +conversion in place is supported. The output buffer must be at least as long as +the input. +.P +The \fIlength\fP argument specifies the number of 16-bit data units in the +input string; a negative value specifies a zero-terminated string. +.P +If \fIbyte_order\fP is NULL, it is assumed that the string starts off in host +byte order. This may be changed by byte-order marks (BOMs) anywhere in the +string (commonly as the first character). +.P +If \fIbyte_order\fP is not NULL, a non-zero value of the integer to which it +points means that the input starts off in host byte order, otherwise the +opposite order is assumed. Again, BOMs in the string can change this. The final +byte order is passed back at the end of processing. +.P +If \fIkeep_boms\fP is not zero, byte-order mark characters (0xfeff) are copied +into the output string. Otherwise they are discarded. +.P +The result of the function is the number of 16-bit units placed into the output +buffer, including the zero terminator if the string was zero-terminated. +. +. +.SH "SUBJECT STRING OFFSETS" +.rs +.sp +The offsets within subject strings that are returned by the matching functions +are in 16-bit units rather than bytes. +. +. +.SH "NAMED SUBPATTERNS" +.rs +.sp +The name-to-number translation table that is maintained for named subpatterns +uses 16-bit characters. The \fBpcre16_get_stringtable_entries()\fP function +returns the length of each entry in the table as the number of 16-bit data +units. +. +. +.SH "OPTION NAMES" +.rs +.sp +There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK, +which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In +fact, these new options define the same bits in the options word. There is a +discussion about the +.\" HTML +.\" +validity of UTF-16 strings +.\" +in the +.\" HREF +\fBpcreunicode\fP +.\" +page. +.P +For the \fBpcre16_config()\fP function there is an option PCRE_CONFIG_UTF16 +that returns 1 if UTF-16 support is configured, otherwise 0. If this option is +given to \fBpcre_config()\fP, or if the PCRE_CONFIG_UTF8 option is given to +\fBpcre16_config()\fP, the result is the PCRE_ERROR_BADOPTION error. +. +. +.SH "CHARACTER CODES" +.rs +.sp +In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the +same way as in 8-bit, non UTF-8 mode, except, of course, that they can range +from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than +0xff can therefore be influenced by the locale in the same way as before. +Characters greater than 0xff have only one case, and no "type" (such as letter +or digit). +.P +In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with +the exception of values in the range 0xd800 to 0xdfff because those are +"surrogate" values that are used in pairs to encode values greater than 0xffff. +.P +A UTF-16 string can indicate its endianness by special code knows as a +byte-order mark (BOM). The PCRE functions do not handle this, expecting strings +to be in host byte order. A utility function called +\fBpcre16_utf16_to_host_byte_order()\fP is provided to help with this (see +above). +. +. +.SH "ERROR NAMES" +.rs +.sp +The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to +their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled +pattern is passed to a function that processes patterns in the other +mode, for example, if a pattern compiled with \fBpcre_compile()\fP is passed to +\fBpcre16_exec()\fP. +.P +There are new error codes whose names begin with PCRE_UTF16_ERR for invalid +UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that +are described in the section entitled +.\" HTML +.\" +"Reason codes for invalid UTF-8 strings" +.\" +in the main +.\" HREF +\fBpcreapi\fP +.\" +page. The UTF-16 errors are: +.sp + PCRE_UTF16_ERR1 Missing low surrogate at end of string + PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate + PCRE_UTF16_ERR3 Isolated low surrogate + PCRE_UTF16_ERR4 Invalid character 0xfffe +. +. +.SH "ERROR TEXTS" +.rs +.sp +If there is an error while compiling a pattern, the error text that is passed +back by \fBpcre16_compile()\fP or \fBpcre16_compile2()\fP is still an 8-bit +character string, zero-terminated. +. +. +.SH "CALLOUTS" +.rs +.sp +The \fIsubject\fP and \fImark\fP fields in the callout block that is passed to +a callout function point to 16-bit vectors. +. +. +.SH "TESTING" +.rs +.sp +The \fBpcretest\fP program continues to operate with 8-bit input and output +files, but it can be used for testing the 16-bit library. If it is run with the +command line option \fB-16\fP, patterns and subject strings are converted from +8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions +are used instead of the 8-bit ones. Returned 16-bit strings are converted to +8-bit for output. If the 8-bit library was not compiled, \fBpcretest\fP +defaults to 16-bit and the \fB-16\fP option is ignored. +.P +When PCRE is being built, the \fBRunTest\fP script that is called by "make +check" uses the \fBpcretest\fP \fB-C\fP option to discover which of the 8-bit +and 16-bit libraries has been built, and runs the tests appropriately. +. +. +.SH "NOT SUPPORTED IN 16-BIT MODE" +.rs +.sp +Not all the features of the 8-bit library are available with the 16-bit +library. The C++ and POSIX wrapper functions support only the 8-bit library, +and the \fBpcregrep\fP program is at present 8-bit only. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 14 April 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff -Nru pcre3-8.12/doc/pcre_assign_jit_stack.3 pcre3-8.31/doc/pcre_assign_jit_stack.3 --- pcre3-8.12/doc/pcre_assign_jit_stack.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_assign_jit_stack.3 2012-05-26 14:21:10.000000000 +0000 @@ -0,0 +1,57 @@ +.TH PCRE_ASSIGN_JIT_STACK 3 "13 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, +.ti +5n +.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); +.PP +.B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP, +.ti +5n +.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP); +. +.SH DESCRIPTION +.rs +.sp +This function provides control over the memory used as a stack at run-time by a +call to \fBpcre[16]_exec()\fP with a pattern that has been successfully +compiled with JIT optimization. The arguments are: +.sp + extra the data pointer returned by \fBpcre[16]_study()\fP + callback a callback function + data a JIT stack or a value to be passed to the callback + function +.P +If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block on +the machine stack is used. +.P +If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must +be a valid JIT stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP. +.P +If \fIcallback\fP not NULL, it is called with \fIdata\fP as an argument at +the start of matching, in order to set up a JIT stack. If the result is NULL, +the internal 32K stack is used; otherwise the return value must be a valid JIT +stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP. +.P +You may safely assign the same JIT stack to multiple patterns, as long as they +are all matched in the same thread. In a multithread application, each thread +must use its own JIT stack. For more details, see the +.\" HREF +\fBpcrejit\fP +.\" +page. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_compile.3 pcre3-8.31/doc/pcre_compile.3 --- pcre3-8.12/doc/pcre_compile.3 2011-01-11 16:29:57.000000000 +0000 +++ pcre3-8.31/doc/pcre_compile.3 2012-05-26 14:21:10.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_COMPILE 3 +.TH PCRE_COMPILE 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -12,13 +12,19 @@ .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); +.PP +.B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP, int *\fIerroffset\fP, +.ti +5n +.B const unsigned char *\fItableptr\fP); . .SH DESCRIPTION .rs .sp This function compiles a regular expression into an internal form. It is the -same as \fBpcre_compile2()\fP, except for the absence of the \fIerrorcodeptr\fP -argument. Its arguments are: +same as \fBpcre[16]_compile2()\fP, except for the absence of the +\fIerrorcodeptr\fP argument. Its arguments are: .sp \fIpattern\fP A zero-terminated string containing the regular expression to be compiled @@ -38,7 +44,7 @@ PCRE_DOLLAR_ENDONLY $ not to match newline at end PCRE_DOTALL . matches anything including NL PCRE_DUPNAMES Allow duplicate names for subpatterns - PCRE_EXTENDED Ignore whitespace and # comments + PCRE_EXTENDED Ignore white space and # comments PCRE_EXTRA PCRE extra features (not much use currently) PCRE_FIRSTLINE Force matching to be before newline @@ -52,15 +58,19 @@ PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 + validity (only relevant if + PCRE_UTF16 is set) PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) PCRE_UCP Use Unicode properties for \ed, \ew, etc. PCRE_UNGREEDY Invert greediness of quantifiers - PCRE_UTF8 Run in UTF-8 mode + PCRE_UTF16 Run in \fBpcre16_compile()\fP UTF-16 mode + PCRE_UTF8 Run in \fBpcre_compile()\fP UTF-8 mode .sp -PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and -PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used. +PCRE must be built with UTF support in order to use PCRE_UTF8/16 and +PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used. .P The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that diff -Nru pcre3-8.12/doc/pcre_compile2.3 pcre3-8.31/doc/pcre_compile2.3 --- pcre3-8.12/doc/pcre_compile2.3 2011-01-11 16:30:43.000000000 +0000 +++ pcre3-8.31/doc/pcre_compile2.3 2012-05-26 14:21:10.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_COMPILE2 3 +.TH PCRE_COMPILE2 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -14,13 +14,21 @@ .B const char **\fIerrptr\fP, int *\fIerroffset\fP, .ti +5n .B const unsigned char *\fItableptr\fP); +.PP +.B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP, +.ti +5n +.B int *\fIerrorcodeptr\fP, +.ti +5n +.B const char **\fIerrptr\fP, int *\fIerroffset\fP, +.ti +5n +.B const unsigned char *\fItableptr\fP); . .SH DESCRIPTION .rs .sp This function compiles a regular expression into an internal form. It is the -same as \fBpcre_compile()\fP, except for the addition of the \fIerrorcodeptr\fP -argument. The arguments are: +same as \fBpcre[16]_compile()\fP, except for the addition of the +\fIerrorcodeptr\fP argument. The arguments are: . .sp \fIpattern\fP A zero-terminated string containing the @@ -42,7 +50,7 @@ PCRE_DOLLAR_ENDONLY $ not to match newline at end PCRE_DOTALL . matches anything including NL PCRE_DUPNAMES Allow duplicate names for subpatterns - PCRE_EXTENDED Ignore whitespace and # comments + PCRE_EXTENDED Ignore white space and # comments PCRE_EXTRA PCRE extra features (not much use currently) PCRE_FIRSTLINE Force matching to be before newline @@ -56,15 +64,19 @@ PCRE_NEWLINE_LF Set LF as the newline sequence PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren- theses (named ones available) + PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16 + validity (only relevant if + PCRE_UTF16 is set) PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) PCRE_UCP Use Unicode properties for \ed, \ew, etc. PCRE_UNGREEDY Invert greediness of quantifiers - PCRE_UTF8 Run in UTF-8 mode + PCRE_UTF16 Run \fBpcre16_compile()\fP in UTF-16 mode + PCRE_UTF8 Run \fBpcre_compile()\fP in UTF-8 mode .sp -PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and -PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used. +PCRE must be built with UTF support in order to use PCRE_UTF8/16 and +PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used. .P The yield of the function is a pointer to a private data structure that contains the compiled pattern, or NULL if an error was detected. Note that diff -Nru pcre3-8.12/doc/pcre_config.3 pcre3-8.31/doc/pcre_config.3 --- pcre3-8.12/doc/pcre_config.3 2011-01-11 16:31:34.000000000 +0000 +++ pcre3-8.31/doc/pcre_config.3 2012-03-31 16:35:31.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_CONFIG 3 +.TH PCRE_CONFIG 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,19 +8,28 @@ .PP .SM .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP); . .SH DESCRIPTION .rs .sp This function makes it possible for a client program to find out which optional -features are available in the version of the PCRE library it is using. Its +features are available in the version of the PCRE library it is using. The arguments are as follows: .sp \fIwhat\fP A code specifying what information is required \fIwhere\fP Points to where to put the data .sp -The available codes are: -.sp +The \fIwhere\fP argument must point to an integer variable, except for +PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must +point to an unsigned long integer. The available codes are: +.sp + PCRE_CONFIG_JIT Availability of just-in-time compiler + support (1=yes 0=no) + PCRE_CONFIG_JITTARGET String containing information about the + target architecture for the JIT compiler, + or NULL if there is no JIT support PCRE_CONFIG_LINK_SIZE Internal link size: 2, 3, or 4 PCRE_CONFIG_MATCH_LIMIT Internal resource limit PCRE_CONFIG_MATCH_LIMIT_RECURSION @@ -35,16 +44,20 @@ 0 all Unicode line endings 1 CR, LF, or CRLF only PCRE_CONFIG_POSIX_MALLOC_THRESHOLD - Threshold of return slots, above - which \fBmalloc()\fP is used by - the POSIX API + Threshold of return slots, above which + \fBmalloc()\fP is used by the POSIX API PCRE_CONFIG_STACKRECURSE Recursion implementation (1=stack 0=heap) - PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no) + PCRE_CONFIG_UTF16 Availability of UTF-16 support (1=yes + 0=no); option for \fBpcre16_config()\fP + PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no); + option for \fBpcre_config()\fP PCRE_CONFIG_UNICODE_PROPERTIES Availability of Unicode property support (1=yes 0=no) .sp -The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. +The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error +is also given if PCRE_CONFIG_UTF16 is passed to \fBpcre_config()\fP or if +PCRE_CONFIG_UTF8 is passed to \fBpcre16_config()\fP. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_copy_named_substring.3 pcre3-8.31/doc/pcre_copy_named_substring.3 --- pcre3-8.12/doc/pcre_copy_named_substring.3 2007-03-06 11:45:55.000000000 +0000 +++ pcre3-8.31/doc/pcre_copy_named_substring.3 2012-03-31 16:36:06.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_COPY_NAMED_SUBSTRING 3 +.TH PCRE_COPY_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -14,6 +14,14 @@ .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B char *\fIbuffer\fP, int \fIbuffersize\fP); +.PP +.B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, +.ti +5n +.B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP); . .SH DESCRIPTION .rs @@ -23,8 +31,8 @@ .sp \fIcode\fP Pattern that was successfully matched \fIsubject\fP Subject that has been successfully matched - \fIovector\fP Offset vector that \fBpcre_exec()\fP used - \fIstringcount\fP Value returned by \fBpcre_exec()\fP + \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringname\fP Name of the required substring \fIbuffer\fP Buffer to receive the string \fIbuffersize\fP Size of buffer diff -Nru pcre3-8.12/doc/pcre_copy_substring.3 pcre3-8.31/doc/pcre_copy_substring.3 --- pcre3-8.12/doc/pcre_copy_substring.3 2007-03-06 11:45:49.000000000 +0000 +++ pcre3-8.31/doc/pcre_copy_substring.3 2012-03-31 16:36:26.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_COPY_SUBSTRING 3 +.TH PCRE_COPY_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -12,6 +12,12 @@ .B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP, .ti +5n .B int \fIbuffersize\fP); +.PP +.B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP, +.ti +5n +.B int \fIbuffersize\fP); . .SH DESCRIPTION .rs @@ -20,8 +26,8 @@ buffer. The arguments are: .sp \fIsubject\fP Subject that has been successfully matched - \fIovector\fP Offset vector that \fBpcre_exec()\fP used - \fIstringcount\fP Value returned by \fBpcre_exec()\fP + \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringnumber\fP Number of the required substring \fIbuffer\fP Buffer to receive the string \fIbuffersize\fP Size of buffer diff -Nru pcre3-8.12/doc/pcre_dfa_exec.3 pcre3-8.31/doc/pcre_dfa_exec.3 --- pcre3-8.12/doc/pcre_dfa_exec.3 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/doc/pcre_dfa_exec.3 2012-03-31 16:36:55.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_DFA_EXEC 3 +.TH PCRE_DFA_EXEC 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -14,6 +14,14 @@ .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); +.PP +.B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, +.ti +5n +.B int *\fIworkspace\fP, int \fIwscount\fP); . .SH DESCRIPTION .rs @@ -21,10 +29,11 @@ This function matches a compiled regular expression against a given subject string, using an alternative matching algorithm that scans the subject string just once (\fInot\fP Perl-compatible). Note that the main, Perl-compatible, -matching function is \fBpcre_exec()\fP. The arguments for this function are: +matching function is \fBpcre[16]_exec()\fP. The arguments for this function +are: .sp \fIcode\fP Points to the compiled pattern - \fIextra\fP Points to an associated \fBpcre_extra\fP structure, + \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string \fIlength\fP Length of the subject string, in bytes @@ -52,6 +61,9 @@ PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject is not a valid match PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations + PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16 + validity (only relevant if PCRE_UTF16 + was set at compile time) PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8 validity (only relevant if PCRE_UTF8 was set at compile time) @@ -73,19 +85,23 @@ .\" page. .P -A \fBpcre_extra\fP structure contains the following fields: +A \fBpcre[16]_extra\fP structure contains the following fields: .sp - \fIflags\fP Bits indicating which fields are set - \fIstudy_data\fP Opaque data from \fBpcre_study()\fP - \fImatch_limit\fP Limit on internal resource use + \fIflags\fP Bits indicating which fields are set + \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP + \fImatch_limit\fP Limit on internal resource use \fImatch_limit_recursion\fP Limit on internal recursion depth - \fIcallout_data\fP Opaque data passed back to callouts - \fItables\fP Points to character tables or is NULL + \fIcallout_data\fP Opaque data passed back to callouts + \fItables\fP Points to character tables or is NULL + \fImark\fP For passing back a *MARK pointer + \fIexecutable_jit\fP Opaque data from JIT compilation .sp The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, -PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and -PCRE_EXTRA_TABLES. For this matching function, the \fImatch_limit\fP and -\fImatch_limit_recursion\fP fields are not used, and must not be set. +PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this +matching function, the \fImatch_limit\fP and \fImatch_limit_recursion\fP fields +are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and +the corresponding variable are ignored. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_exec.3 pcre3-8.31/doc/pcre_exec.3 --- pcre3-8.12/doc/pcre_exec.3 2010-10-22 10:13:55.000000000 +0000 +++ pcre3-8.31/doc/pcre_exec.3 2012-03-31 16:37:09.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_EXEC 3 +.TH PCRE_EXEC 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -12,6 +12,12 @@ .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, .ti +5n .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); +.PP +.B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, +.ti +5n +.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP); . .SH DESCRIPTION .rs @@ -21,7 +27,7 @@ offsets to captured substrings. Its arguments are: .sp \fIcode\fP Points to the compiled pattern - \fIextra\fP Points to an associated \fBpcre_extra\fP structure, + \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, or is NULL \fIsubject\fP Points to the subject string \fIlength\fP Length of the subject string, in bytes @@ -47,6 +53,9 @@ PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject is not a valid match PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations + PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16 + validity (only relevant if PCRE_UTF16 + was set at compile time) PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8 validity (only relevant if PCRE_UTF8 was set at compile time) @@ -61,16 +70,18 @@ .\" page. A \fBpcre_extra\fP structure contains the following fields: .sp - \fIflags\fP Bits indicating which fields are set - \fIstudy_data\fP Opaque data from \fBpcre_study()\fP - \fImatch_limit\fP Limit on internal resource use + \fIflags\fP Bits indicating which fields are set + \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP + \fImatch_limit\fP Limit on internal resource use \fImatch_limit_recursion\fP Limit on internal recursion depth - \fIcallout_data\fP Opaque data passed back to callouts - \fItables\fP Points to character tables or is NULL + \fIcallout_data\fP Opaque data passed back to callouts + \fItables\fP Points to character tables or is NULL + \fImark\fP For passing back a *MARK pointer + \fIexecutable_jit\fP Opaque data from JIT compilation .sp The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT, -PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and -PCRE_EXTRA_TABLES. +PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, +PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_free_study.3 pcre3-8.31/doc/pcre_free_study.3 --- pcre3-8.12/doc/pcre_free_study.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_free_study.3 2012-03-31 16:37:20.000000000 +0000 @@ -0,0 +1,29 @@ +.TH PCRE_FREE_STUDY 3 "13 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B void pcre_free_study(pcre_extra *\fIextra\fP); +.PP +.B void pcre16_free_study(pcre16_extra *\fIextra\fP); +. +.SH DESCRIPTION +.rs +.sp +This function is used to free the memory used for the data generated by a call +to \fBpcre[16]_study()\fP when it is no longer needed. The argument must be the +result of such a call. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_free_substring.3 pcre3-8.31/doc/pcre_free_substring.3 --- pcre3-8.12/doc/pcre_free_substring.3 2007-03-06 11:45:22.000000000 +0000 +++ pcre3-8.31/doc/pcre_free_substring.3 2012-03-31 16:37:38.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_FREE_SUBSTRING 3 +.TH PCRE_FREE_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,13 +8,15 @@ .PP .SM .B void pcre_free_substring(const char *\fIstringptr\fP); +.PP +.B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for freeing the store obtained by a previous -call to \fBpcre_get_substring()\fP or \fBpcre_get_named_substring()\fP. Its -only argument is a pointer to the string. +call to \fBpcre[16]_get_substring()\fP or \fBpcre[16]_get_named_substring()\fP. +Its only argument is a pointer to the string. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_free_substring_list.3 pcre3-8.31/doc/pcre_free_substring_list.3 --- pcre3-8.12/doc/pcre_free_substring_list.3 2007-03-06 11:45:13.000000000 +0000 +++ pcre3-8.31/doc/pcre_free_substring_list.3 2012-03-31 16:37:46.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_FREE_SUBSTRING_LIST 3 +.TH PCRE_FREE_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,13 +8,15 @@ .PP .SM .B void pcre_free_substring_list(const char **\fIstringptr\fP); +.PP +.B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs .sp This is a convenience function for freeing the store obtained by a previous -call to \fBpcre_get_substring_list()\fP. Its only argument is a pointer to the -list of string pointers. +call to \fBpcre[16]_get_substring_list()\fP. Its only argument is a pointer to +the list of string pointers. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_fullinfo.3 pcre3-8.31/doc/pcre_fullinfo.3 --- pcre3-8.12/doc/pcre_fullinfo.3 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/doc/pcre_fullinfo.3 2012-03-31 16:38:07.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_FULLINFO 3 +.TH PCRE_FULLINFO 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -10,6 +10,10 @@ .B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); +.PP +.B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP," +.ti +5n +.B int \fIwhat\fP, void *\fIwhere\fP); . .SH DESCRIPTION .rs @@ -17,7 +21,7 @@ This function returns information about a compiled pattern. Its arguments are: .sp \fIcode\fP Compiled regular expression - \fIextra\fP Result of \fBpcre_study()\fP or NULL + \fIextra\fP Result of \fBpcre[16]_study()\fP or NULL \fIwhat\fP What information is required \fIwhere\fP Where to put the information .sp @@ -26,13 +30,16 @@ PCRE_INFO_BACKREFMAX Number of highest back reference PCRE_INFO_CAPTURECOUNT Number of capturing subpatterns PCRE_INFO_DEFAULT_TABLES Pointer to default tables - PCRE_INFO_FIRSTBYTE Fixed first byte for a match, or + PCRE_INFO_FIRSTBYTE Fixed first data unit for a match, or -1 for start of string or after newline, or -2 otherwise - PCRE_INFO_FIRSTTABLE Table of first bytes (after studying) + PCRE_INFO_FIRSTTABLE Table of first data units (after studying) + PCRE_INFO_HASCRORLF Return 1 if explicit CR or LF matches exist PCRE_INFO_JCHANGED Return 1 if (?J) or (?-J) was used - PCRE_INFO_LASTLITERAL Literal last byte required + PCRE_INFO_JIT Return 1 after successful JIT compilation + PCRE_INFO_JITSIZE Size of JIT compiled code + PCRE_INFO_LASTLITERAL Literal last data unit required PCRE_INFO_MINLENGTH Lower bound length of matching strings PCRE_INFO_NAMECOUNT Number of named subpatterns PCRE_INFO_NAMEENTRYSIZE Size of name table entry @@ -43,6 +50,16 @@ PCRE_INFO_SIZE Size of compiled pattern PCRE_INFO_STUDYSIZE Size of study data .sp +The \fIwhere\fP argument must point to an integer variable, except for the +following \fIwhat\fP values: +.sp + PCRE_INFO_DEFAULT_TABLES const unsigned char * + PCRE_INFO_FIRSTTABLE const unsigned char * + PCRE_INFO_NAMETABLE PCRE_SPTR16 (16-bit library) + PCRE_INFO_NAMETABLE const unsigned char * (8-bit library) + PCRE_INFO_OPTIONS unsigned long int + PCRE_INFO_SIZE size_t +.sp The yield of the function is zero on success or: .sp PCRE_ERROR_NULL the argument \fIcode\fP was NULL diff -Nru pcre3-8.12/doc/pcre_get_named_substring.3 pcre3-8.31/doc/pcre_get_named_substring.3 --- pcre3-8.12/doc/pcre_get_named_substring.3 2007-03-06 11:45:03.000000000 +0000 +++ pcre3-8.31/doc/pcre_get_named_substring.3 2012-03-31 16:38:26.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_GET_NAMED_SUBSTRING 3 +.TH PCRE_GET_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -14,6 +14,14 @@ .B int \fIstringcount\fP, const char *\fIstringname\fP, .ti +5n .B const char **\fIstringptr\fP); +.PP +.B int pcre16_get_named_substring(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP, +.ti +5n +.B PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs @@ -23,16 +31,17 @@ .sp \fIcode\fP Compiled pattern \fIsubject\fP Subject that has been successfully matched - \fIovector\fP Offset vector that \fBpcre_exec()\fP used - \fIstringcount\fP Value returned by \fBpcre_exec()\fP + \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringname\fP Name of the required substring \fIstringptr\fP Where to put the string pointer .sp The memory in which the substring is placed is obtained by calling -\fBpcre_malloc()\fP. The convenience function \fBpcre_free_substring()\fP can -be used to free it when it is no longer needed. The yield of the function is -the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory -could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid. +\fBpcre[16]_malloc()\fP. The convenience function +\fBpcre[16]_free_substring()\fP can be used to free it when it is no longer +needed. The yield of the function is the length of the extracted substring, +PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or +PCRE_ERROR_NOSUBSTRING if the string name is invalid. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_get_stringnumber.3 pcre3-8.31/doc/pcre_get_stringnumber.3 --- pcre3-8.12/doc/pcre_get_stringnumber.3 2007-03-06 11:44:53.000000000 +0000 +++ pcre3-8.31/doc/pcre_get_stringnumber.3 2012-03-31 16:38:38.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_GET_STRINGNUMBER 3 +.TH PCRE_GET_STRINGNUMBER 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -10,6 +10,10 @@ .B int pcre_get_stringnumber(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP); +.PP +.B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIname\fP); . .SH DESCRIPTION .rs @@ -23,8 +27,8 @@ The yield of the function is the number of the parenthesis if the name is found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed (PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by -\fBpcre_get_stringnumber()\fP. You can obtain the complete list by calling -\fBpcre_get_stringtable_entries()\fP. +\fBpcre[16]_get_stringnumber()\fP. You can obtain the complete list by calling +\fBpcre[16]_get_stringtable_entries()\fP. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_get_stringtable_entries.3 pcre3-8.31/doc/pcre_get_stringtable_entries.3 --- pcre3-8.12/doc/pcre_get_stringtable_entries.3 2007-03-06 11:44:45.000000000 +0000 +++ pcre3-8.31/doc/pcre_get_stringtable_entries.3 2012-03-31 16:38:56.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_GET_STRINGTABLE_ENTRIES 3 +.TH PCRE_GET_STRINGTABLE_ENTRIES 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -10,6 +10,10 @@ .B int pcre_get_stringtable_entries(const pcre *\fIcode\fP, .ti +5n .B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP); +.PP +.B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP, +.ti +5n +.B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP); . .SH DESCRIPTION .rs @@ -17,7 +21,7 @@ This convenience function finds, for a compiled pattern, the first and last entries for a given name in the table that translates capturing parenthesis names into numbers. When names are required to be unique (PCRE_DUPNAMES is -\fInot\fP set), it is usually easier to use \fBpcre_get_stringnumber()\fP +\fInot\fP set), it is usually easier to use \fBpcre[16]_get_stringnumber()\fP instead. .sp \fIcode\fP Compiled regular expression diff -Nru pcre3-8.12/doc/pcre_get_substring.3 pcre3-8.31/doc/pcre_get_substring.3 --- pcre3-8.12/doc/pcre_get_substring.3 2007-03-06 11:44:37.000000000 +0000 +++ pcre3-8.31/doc/pcre_get_substring.3 2012-03-31 16:39:09.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_GET_SUBSTRING 3 +.TH PCRE_GET_SUBSTRING 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -12,6 +12,12 @@ .B int \fIstringcount\fP, int \fIstringnumber\fP, .ti +5n .B const char **\fIstringptr\fP); +.PP +.B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP, +.ti +5n +.B int \fIstringcount\fP, int \fIstringnumber\fP, +.ti +5n +.B PCRE_SPTR16 *\fIstringptr\fP); . .SH DESCRIPTION .rs @@ -20,16 +26,17 @@ arguments are: .sp \fIsubject\fP Subject that has been successfully matched - \fIovector\fP Offset vector that \fBpcre_exec()\fP used - \fIstringcount\fP Value returned by \fBpcre_exec()\fP + \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used + \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP \fIstringnumber\fP Number of the required substring \fIstringptr\fP Where to put the string pointer .sp The memory in which the substring is placed is obtained by calling -\fBpcre_malloc()\fP. The convenience function \fBpcre_free_substring()\fP can -be used to free it when it is no longer needed. The yield of the function is -the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not -be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid. +\fBpcre[16]_malloc()\fP. The convenience function +\fBpcre[16]_free_substring()\fP can be used to free it when it is no longer +needed. The yield of the function is the length of the substring, +PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or +PCRE_ERROR_NOSUBSTRING if the string number is invalid. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_get_substring_list.3 pcre3-8.31/doc/pcre_get_substring_list.3 --- pcre3-8.12/doc/pcre_get_substring_list.3 2007-03-06 11:44:30.000000000 +0000 +++ pcre3-8.31/doc/pcre_get_substring_list.3 2012-03-31 16:39:22.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_GET_SUBSTRING_LIST 3 +.TH PCRE_GET_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -10,6 +10,10 @@ .B int pcre_get_substring_list(const char *\fIsubject\fP, .ti +5n .B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);" +.PP +.B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP, +.ti +5n +.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);" . .SH DESCRIPTION .rs @@ -18,17 +22,17 @@ substrings. The arguments are: .sp \fIsubject\fP Subject that has been successfully matched - \fIovector\fP Offset vector that \fBpcre_exec\fP used - \fIstringcount\fP Value returned by \fBpcre_exec\fP + \fIovector\fP Offset vector that \fBpcre[16]_exec\fP used + \fIstringcount\fP Value returned by \fBpcre[16]_exec\fP \fIlistptr\fP Where to put a pointer to the list .sp The memory in which the substrings and the list are placed is obtained by -calling \fBpcre_malloc()\fP. The convenience function -\fBpcre_free_substring_list()\fP can be used to free it when it is no longer -needed. A pointer to a list of pointers is put in the variable whose address is -in \fIlistptr\fP. The list is terminated by a NULL pointer. The yield of the -function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could -not be obtained. +calling \fBpcre[16]_malloc()\fP. The convenience function +\fBpcre[16]_free_substring_list()\fP can be used to free it when it is no +longer needed. A pointer to a list of pointers is put in the variable whose +address is in \fIlistptr\fP. The list is terminated by a NULL pointer. The +yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient +memory could not be obtained. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_info.3 pcre3-8.31/doc/pcre_info.3 --- pcre3-8.12/doc/pcre_info.3 2007-03-06 11:44:22.000000000 +0000 +++ pcre3-8.31/doc/pcre_info.3 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -.TH PCRE_INFO 3 -.SH NAME -PCRE - Perl-compatible regular expressions -.SH SYNOPSIS -.rs -.sp -.B #include -.PP -.SM -.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int -.B *\fIfirstcharptr\fP); -. -.SH DESCRIPTION -.rs -.sp -This function is obsolete. You should be using \fBpcre_fullinfo()\fP instead. -.P -There is a complete description of the PCRE native API in the -.\" HREF -\fBpcreapi\fP -.\" -page and a description of the POSIX API in the -.\" HREF -\fBpcreposix\fP -.\" -page. diff -Nru pcre3-8.12/doc/pcre_jit_stack_alloc.3 pcre3-8.31/doc/pcre_jit_stack_alloc.3 --- pcre3-8.12/doc/pcre_jit_stack_alloc.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_jit_stack_alloc.3 2012-05-26 14:21:10.000000000 +0000 @@ -0,0 +1,41 @@ +.TH PCRE_JIT_STACK_ALLOC 3 "21 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, +.ti +5n +.B int \fImaxsize\fP); +.PP +.B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, +.ti +5n +.B int \fImaxsize\fP); +. +.SH DESCRIPTION +.rs +.sp +This function is used to create a stack for use by the code compiled by the JIT +optimization of \fBpcre[16]_study()\fP. The arguments are a starting size for +the stack, and a maximum size to which it is allowed to grow. The result can be +passed to the JIT run-time code by \fBpcre[16]_assign_jit_stack()\fP, or that +function can set up a callback for obtaining a stack. A maximum stack size of +512K to 1M should be more than enough for any pattern. For more details, see +the +.\" HREF +\fBpcrejit\fP +.\" +page. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_jit_stack_free.3 pcre3-8.31/doc/pcre_jit_stack_free.3 --- pcre3-8.12/doc/pcre_jit_stack_free.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_jit_stack_free.3 2012-03-31 16:40:02.000000000 +0000 @@ -0,0 +1,33 @@ +.TH PCRE_JIT_STACK_FREE 3 "13 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP); +.PP +.B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP); +. +.SH DESCRIPTION +.rs +.sp +This function is used to free a JIT stack that was created by +\fBpcre[16]_jit_stack_alloc()\fP when it is no longer needed. For more details, +see the +.\" HREF +\fBpcrejit\fP +.\" +page. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_maketables.3 pcre3-8.31/doc/pcre_maketables.3 --- pcre3-8.12/doc/pcre_maketables.3 2007-03-06 11:44:14.000000000 +0000 +++ pcre3-8.31/doc/pcre_maketables.3 2012-03-31 16:40:18.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_MAKETABLES 3 +.TH PCRE_MAKETABLES 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,15 +8,17 @@ .PP .SM .B const unsigned char *pcre_maketables(void); +.PP +.B const unsigned char *pcre16_maketables(void); . .SH DESCRIPTION .rs .sp This function builds a set of character tables for character values less than -256. These can be passed to \fBpcre_compile()\fP to override PCRE's internal, -built-in tables (which were made by \fBpcre_maketables()\fP when PCRE was -compiled). You might want to do this if you are using a non-standard locale. -The function yields a pointer to the tables. +256. These can be passed to \fBpcre[16]_compile()\fP to override PCRE's +internal, built-in tables (which were made by \fBpcre[16]_maketables()\fP when +PCRE was compiled). You might want to do this if you are using a non-standard +locale. The function yields a pointer to the tables. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_pattern_to_host_byte_order.3 pcre3-8.31/doc/pcre_pattern_to_host_byte_order.3 --- pcre3-8.12/doc/pcre_pattern_to_host_byte_order.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_pattern_to_host_byte_order.3 2012-03-31 16:40:42.000000000 +0000 @@ -0,0 +1,43 @@ +.TH PCRE_PATTERN_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP, +.ti +5n +.B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP); +.PP +.B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP, +.ti +5n +.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP); +. +. +.SH DESCRIPTION +.rs +.sp +This function ensures that the bytes in 2-byte and 4-byte values in a compiled +pattern are in the correct order for the current host. It is useful when a +pattern that has been compiled on one host is transferred to another that might +have different endianness. The arguments are: +.sp + \fIcode\fP A compiled regular expression + \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure, + or is NULL + \fItables\fP Pointer to character tables, or NULL to + set the built-in default +.sp +The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_refcount.3 pcre3-8.31/doc/pcre_refcount.3 --- pcre3-8.12/doc/pcre_refcount.3 2007-03-06 11:44:03.000000000 +0000 +++ pcre3-8.31/doc/pcre_refcount.3 2012-03-31 16:40:58.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_REFCOUNT 3 +.TH PCRE_REFCOUNT 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,6 +8,8 @@ .PP .SM .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); +.PP +.B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP); . .SH DESCRIPTION .rs diff -Nru pcre3-8.12/doc/pcre_study.3 pcre3-8.31/doc/pcre_study.3 --- pcre3-8.12/doc/pcre_study.3 2007-03-06 11:43:47.000000000 +0000 +++ pcre3-8.31/doc/pcre_study.3 2012-03-31 16:41:07.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_STUDY 3 +.TH PCRE_STUDY 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -10,6 +10,10 @@ .B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP, .ti +5n .B const char **\fIerrptr\fP); +.PP +.B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP, +.ti +5n +.B const char **\fIerrptr\fP); . .SH DESCRIPTION .rs @@ -18,18 +22,24 @@ be extracted that might speed up matching. Its arguments are: .sp \fIcode\fP A compiled regular expression - \fIoptions\fP Options for \fBpcre_study()\fP + \fIoptions\fP Options for \fBpcre[16]_study()\fP \fIerrptr\fP Where to put an error message .sp If the function succeeds, it returns a value that can be passed to -\fBpcre_exec()\fP via its \fIextra\fP argument. +\fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP via their \fIextra\fP +arguments. .P If the function returns NULL, either it could not find any additional information, or there was an error. You can tell the difference by looking at the error value. It is NULL in first case. .P -There are currently no options defined; the value of the second argument should -always be zero. +The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation +if possible. If PCRE has been compiled without JIT support, this option is +ignored. See the +.\" HREF +\fBpcrejit\fP +.\" +page for further details. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcre_utf16_to_host_byte_order.3 pcre3-8.31/doc/pcre_utf16_to_host_byte_order.3 --- pcre3-8.12/doc/pcre_utf16_to_host_byte_order.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcre_utf16_to_host_byte_order.3 2012-03-31 16:41:25.000000000 +0000 @@ -0,0 +1,46 @@ +.TH PCRE_UTF16_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH SYNOPSIS +.rs +.sp +.B #include +.PP +.SM +.B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP, +.ti +5n +.B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP, +.ti +5n +.B int \fIkeep_boms\fP); +. +. +.SH DESCRIPTION +.rs +.sp +This function, which exists only in the 16-bit library, converts a UTF-16 +string to the correct order for the current host, taking account of any byte +order marks (BOMs) within the string. Its arguments are: +.sp + \fIoutput\fP pointer to output buffer, may be the same as \fIinput\fP + \fIinput\fP pointer to input buffer + \fIlength\fP number of 16-bit units in the input, or negative for + a zero-terminated string + \fIhost_byte_order\fP a NULL value or a non-zero value pointed to means + start in host byte order + \fIkeep_boms\fP if non-zero, BOMs are copied to the output string +.sp +The result of the function is the number of 16-bit units placed into the output +buffer, including the zero terminator if the string was zero-terminated. +.P +If \fIhost_byte_order\fP is not NULL, it is set to indicate the byte order that +is current at the end of the string. +.P +There is a complete description of the PCRE native API in the +.\" HREF +\fBpcreapi\fP +.\" +page and a description of the POSIX API in the +.\" HREF +\fBpcreposix\fP +.\" +page. diff -Nru pcre3-8.12/doc/pcre_version.3 pcre3-8.31/doc/pcre_version.3 --- pcre3-8.12/doc/pcre_version.3 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/doc/pcre_version.3 2012-03-31 16:41:37.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRE_VERSION 3 +.TH PCRE_VERSION 3 "13 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH SYNOPSIS @@ -8,12 +8,15 @@ .PP .SM .B const char *pcre_version(void); +.PP +.B const char *pcre16_version(void); . .SH DESCRIPTION .rs .sp -This function returns a character string that gives the version number of the -PCRE library and the date of its release. +This function (even in the 16-bit library) returns a zero-terminated, 8-bit +character string that gives the version number of the PCRE library and the date +of its release. .P There is a complete description of the PCRE native API in the .\" HREF diff -Nru pcre3-8.12/doc/pcreapi.3 pcre3-8.31/doc/pcreapi.3 --- pcre3-8.12/doc/pcreapi.3 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/doc/pcreapi.3 2012-06-17 16:53:44.000000000 +0000 @@ -1,11 +1,13 @@ -.TH PCREAPI 3 +.TH PCREAPI 3 "04 May 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions -.SH "PCRE NATIVE API" -.rs .sp .B #include -.PP +. +. +.SH "PCRE NATIVE API BASIC FUNCTIONS" +.rs +.sp .SM .B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP, .ti +5n @@ -25,6 +27,8 @@ .ti +5n .B const char **\fIerrptr\fP); .PP +.B void pcre_free_study(pcre_extra *\fIextra\fP); +.PP .B int pcre_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP," .ti +5n .B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP, @@ -38,7 +42,11 @@ .B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP, .ti +5n .B int *\fIworkspace\fP, int \fIwscount\fP); -.PP +. +. +.SH "PCRE NATIVE API STRING EXTRACTION FUNCTIONS" +.rs +.sp .B int pcre_copy_named_substring(const pcre *\fIcode\fP, .ti +5n .B const char *\fIsubject\fP, int *\fIovector\fP, @@ -82,6 +90,18 @@ .B void pcre_free_substring(const char *\fIstringptr\fP); .PP .B void pcre_free_substring_list(const char **\fIstringptr\fP); +. +. +.SH "PCRE NATIVE API AUXILIARY FUNCTIONS" +.rs +.sp +.B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP); +.PP +.B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP); +.PP +.B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP, +.ti +5n +.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP); .PP .B const unsigned char *pcre_maketables(void); .PP @@ -89,15 +109,20 @@ .ti +5n .B int \fIwhat\fP, void *\fIwhere\fP); .PP -.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int -.B *\fIfirstcharptr\fP); -.PP .B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP); .PP .B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP); .PP .B const char *pcre_version(void); .PP +.B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP, +.ti +5n +.B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP); +. +. +.SH "PCRE NATIVE API INDIRECTED FUNCTIONS" +.rs +.sp .B void *(*pcre_malloc)(size_t); .PP .B void (*pcre_free)(void *); @@ -109,28 +134,57 @@ .B int (*pcre_callout)(pcre_callout_block *); . . +.SH "PCRE 8-BIT AND 16-BIT LIBRARIES" +.rs +.sp +From release 8.30, PCRE can be compiled as a library for handling 16-bit +character strings as well as, or instead of, the original library that handles +8-bit character strings. To avoid too much complication, this document +describes the 8-bit versions of the functions, with only occasional references +to the 16-bit library. +.P +The 16-bit functions operate in the same way as their 8-bit counterparts; they +just use different data types for their arguments and results, and their names +start with \fBpcre16_\fP instead of \fBpcre_\fP. For every option that has UTF8 +in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with +UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit +option names define the same bit values. +.P +References to bytes and UTF-8 in this document should be read as references to +16-bit data quantities and UTF-16 when using the 16-bit library, unless +specified otherwise. More details of the specific differences for the 16-bit +library are given in the +.\" HREF +\fBpcre16\fP +.\" +page. +. +. .SH "PCRE API OVERVIEW" .rs .sp PCRE has its own native API, which is described in this document. There are -also some wrapper functions that correspond to the POSIX regular expression -API. These are described in the +also some wrapper functions (for the 8-bit library only) that correspond to the +POSIX regular expression API, but they do not give access to all the +functionality. They are described in the .\" HREF \fBpcreposix\fP .\" documentation. Both of these APIs define a set of C function calls. A C++ -wrapper is distributed with PCRE. It is documented in the +wrapper (again for the 8-bit library only) is also distributed with PCRE. It is +documented in the .\" HREF \fBpcrecpp\fP .\" page. .P The native API C function prototypes are defined in the header file -\fBpcre.h\fP, and on Unix systems the library itself is called \fBlibpcre\fP. -It can normally be accessed by adding \fB-lpcre\fP to the command for linking -an application that uses PCRE. The header file defines the macros PCRE_MAJOR -and PCRE_MINOR to contain the major and minor release numbers for the library. -Applications can use these to include support for different releases of PCRE. +\fBpcre.h\fP, and on Unix-like systems the (8-bit) library itself is called +\fBlibpcre\fP. It can normally be accessed by adding \fB-lpcre\fP to the +command for linking an application that uses PCRE. The header file defines the +macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers +for the library. Applications can use these to include support for different +releases of PCRE. .P In a Windows environment, if you want to statically link an application program against a non-dll \fBpcre.a\fP file, you must define PCRE_STATIC before @@ -152,6 +206,19 @@ .\" documentation describes how to compile and run it. .P +Just-in-time compiler support is an optional feature of PCRE that can be built +in appropriate hardware environments. It greatly speeds up the matching +performance of many patterns. Simple programs can easily request that it be +used if available, by setting an option that is ignored when it is not +relevant. More complicated programs might need to make use of the functions +\fBpcre_jit_stack_alloc()\fP, \fBpcre_jit_stack_free()\fP, and +\fBpcre_assign_jit_stack()\fP in order to control the JIT code's memory usage. +These functions are discussed in the +.\" HREF +\fBpcrejit\fP +.\" +documentation. +.P A second matching function, \fBpcre_dfa_exec()\fP, which is not Perl-compatible, is also provided. This uses a different algorithm for the matching. The alternative algorithm finds all possible matches (at a given @@ -186,10 +253,8 @@ internal tables that are generated when PCRE is built are used. .P The function \fBpcre_fullinfo()\fP is used to find out information about a -compiled pattern; \fBpcre_info()\fP is an obsolete version that returns only -some of the available information, but is retained for backwards compatibility. -The function \fBpcre_version()\fP returns a pointer to a string containing the -version of PCRE and its date of release. +compiled pattern. The function \fBpcre_version()\fP returns a pointer to a +string containing the version of PCRE and its date of release. .P The function \fBpcre_refcount()\fP maintains a reference count in a data block containing a compiled pattern. This is provided for the benefit of @@ -237,7 +302,7 @@ strings: a single CR (carriage return) character, a single LF (linefeed) character, the two-character sequence CRLF, any of the three preceding, or any Unicode newline sequence. The Unicode newline sequences are the three just -mentioned, plus the single characters VT (vertical tab, U+000B), FF (formfeed, +mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). .P @@ -282,6 +347,13 @@ .P The compiled form of a regular expression is not altered during matching, so the same compiled pattern can safely be used by several threads at once. +.P +If the just-in-time optimization feature is being used, it needs separate +memory stack areas for each thread. See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for more details. . . .SH "SAVING PRECOMPILED PATTERNS FOR LATER USE" @@ -293,9 +365,10 @@ .\" HREF \fBpcreprecompile\fP .\" -documentation. However, compiling a regular expression with one version of PCRE -for use with a different version is not guaranteed to work and may cause -crashes. +documentation, which includes a description of the +\fBpcre_pattern_to_host_byte_order()\fP function. However, compiling a regular +expression with one version of PCRE for use with a different version is not +guaranteed to work and may cause crashes. . . .SH "CHECKING BUILD-TIME OPTIONS" @@ -312,18 +385,40 @@ .P The first argument for \fBpcre_config()\fP is an integer, specifying which information is required; the second argument is a pointer to a variable into -which the information is placed. The following information is available: +which the information is placed. The returned value is zero on success, or the +negative error code PCRE_ERROR_BADOPTION if the value in the first argument is +not recognized. The following information is available: .sp PCRE_CONFIG_UTF8 .sp The output is an integer that is set to one if UTF-8 support is available; -otherwise it is set to zero. +otherwise it is set to zero. If this option is given to the 16-bit version of +this function, \fBpcre16_config()\fP, the result is PCRE_ERROR_BADOPTION. +.sp + PCRE_CONFIG_UTF16 +.sp +The output is an integer that is set to one if UTF-16 support is available; +otherwise it is set to zero. This value should normally be given to the 16-bit +version of this function, \fBpcre16_config()\fP. If it is given to the 8-bit +version of this function, the result is PCRE_ERROR_BADOPTION. .sp PCRE_CONFIG_UNICODE_PROPERTIES .sp The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero. .sp + PCRE_CONFIG_JIT +.sp +The output is an integer that is set to one if support for just-in-time +compiling is available; otherwise it is set to zero. +.sp + PCRE_CONFIG_JITTARGET +.sp +The output is a pointer to a zero-terminated "const char *" string. If JIT +support is available, the string contains the name of the architecture for +which the JIT compiler is configured, for example "x86 32bit (little endian + +unaligned)". If JIT support is not available, the result is NULL. +.sp PCRE_CONFIG_NEWLINE .sp The output is an integer whose value specifies the default character sequence @@ -343,10 +438,12 @@ PCRE_CONFIG_LINK_SIZE .sp The output is an integer that contains the number of bytes used for internal -linkage in compiled regular expressions. The value is 2, 3, or 4. Larger values -allow larger regular expressions to be compiled, at the expense of slower -matching. The default value of 2 is sufficient for all but the most massive -patterns, since it allows the compiled pattern to be up to 64K in size. +linkage in compiled regular expressions. For the 8-bit library, the value can +be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still +a number of bytes. The default value of 2 is sufficient for all but the most +massive patterns, since it allows the compiled pattern to be up to 64K in size. +Larger values allow larger regular expressions to be compiled, at the expense +of slower matching. .sp PCRE_CONFIG_POSIX_MALLOC_THRESHOLD .sp @@ -429,23 +526,23 @@ the pattern, the contents of the \fIoptions\fP argument specifies their settings at the start of compilation and execution. The PCRE_ANCHORED, PCRE_BSR_\fIxxx\fP, PCRE_NEWLINE_\fIxxx\fP, PCRE_NO_UTF8_CHECK, and -PCRE_NO_START_OPT options can be set at the time of matching as well as at +PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at compile time. .P If \fIerrptr\fP is NULL, \fBpcre_compile()\fP returns NULL immediately. Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fP returns NULL, and sets the variable pointed to by \fIerrptr\fP to point to a textual error message. This is a static string that is part of the library. You must -not try to free it. The offset from the start of the pattern to the byte that -was being processed when the error was discovered is placed in the variable -pointed to by \fIerroffset\fP, which must not be NULL. If it is, an immediate -error is given. Some errors are not detected until checks are carried out when -the whole pattern has been scanned; in this case the offset is set to the end -of the pattern. -.P -Note that the offset is in bytes, not characters, even in UTF-8 mode. It may -point into the middle of a UTF-8 character (for example, when -PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string). +not try to free it. Normally, the offset from the start of the pattern to the +byte that was being processed when the error was discovered is placed in the +variable pointed to by \fIerroffset\fP, which must not be NULL (if it is, an +immediate error is given). However, for an invalid UTF-8 string, the offset is +that of the first byte of the failing character. +.P +Some errors are not detected until the whole pattern has been scanned; in these +cases, the offset passed back is the length of the pattern. Note that the +offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point +into the middle of a UTF-8 character. .P If \fBpcre_compile2()\fP is used instead of \fBpcre_compile()\fP, and the \fIerrorcodeptr\fP argument is not NULL, a non-zero error code number is @@ -545,16 +642,16 @@ .sp PCRE_EXTENDED .sp -If this bit is set, whitespace data characters in the pattern are totally -ignored except when escaped or inside a character class. Whitespace does not +If this bit is set, white space data characters in the pattern are totally +ignored except when escaped or inside a character class. White space does not include the VT character (code 11). In addition, characters between an unescaped # outside a character class and the next newline, inclusive, are also ignored. This is equivalent to Perl's /x option, and it can be changed within a pattern by a (?x) option setting. .P -Which characters are interpreted as newlines -is controlled by the options passed to \fBpcre_compile()\fP or by a special -sequence at the start of the pattern, as described in the section entitled +Which characters are interpreted as newlines is controlled by the options +passed to \fBpcre_compile()\fP or by a special sequence at the start of the +pattern, as described in the section entitled .\" HTML .\" "Newline conventions" @@ -564,7 +661,7 @@ happen to represent a newline do not count. .P This option makes it possible to include comments inside complicated patterns. -Note, however, that this applies only to data characters. Whitespace characters +Note, however, that this applies only to data characters. White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that introduces a conditional subpattern. .sp @@ -599,6 +696,20 @@ string (by default this causes the current matching alternative to fail). A pattern such as (\e1)(a) succeeds when this option is set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. +.P +(3) \eU matches an upper case "U" character; by default \eU causes a compile +time error (Perl uses \eU to upper case subsequent characters). +.P +(4) \eu matches a lower case "u" character unless it is followed by four +hexadecimal digits, in which case the hexadecimal number defines the code point +to match. By default, \eu causes a compile time error (Perl uses it to upper +case the following character). +.P +(5) \ex matches a lower case "x" character unless it is followed by two +hexadecimal digits, in which case the hexadecimal number defines the code point +to match. By default, as in Perl, a hexadecimal number is always expected after +\ex, but it may have zero, one, or two digits (so, for example, \exz matches a +binary zero character followed by z). .sp PCRE_MULTILINE .sp @@ -630,9 +741,9 @@ preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. The Unicode newline sequences are the three just mentioned, plus the single characters VT (vertical -tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line -separator, U+2028), and PS (paragraph separator, U+2029). The last two are -recognized only in UTF-8 mode. +tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line +separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit +library, the last two are recognized only in UTF-8 mode. .P The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are used (default @@ -642,7 +753,7 @@ other combinations may yield unused numbers and cause an error. .P The only time that a line break in a pattern is specially recognized when -compiling is when PCRE_EXTENDED is set. CR and LF are whitespace characters, +compiling is when PCRE_EXTENDED is set. CR and LF are white space characters, and so are ignored in this mode. Also, an unescaped # outside a character class indicates a comment that lasts until after the next line break sequence. In other circumstances, line break sequences in patterns are treated as literal @@ -697,39 +808,34 @@ PCRE_UTF8 .sp This option causes PCRE to regard both the pattern and the subject as strings -of UTF-8 characters instead of single-byte character strings. However, it is -available only when PCRE is built to include UTF-8 support. If not, the use -of this option provokes an error. Details of how this option changes the -behaviour of PCRE are given in the -.\" HTML -.\" -section on UTF-8 support -.\" -in the main +of UTF-8 characters instead of single-byte strings. However, it is available +only when PCRE is built to include UTF support. If not, the use of this option +provokes an error. Details of how this option changes the behaviour of PCRE are +given in the .\" HREF -\fBpcre\fP +\fBpcreunicode\fP .\" page. .sp PCRE_NO_UTF8_CHECK .sp -When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is -automatically checked. There is a discussion about the -.\" HTML +When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 +string is automatically checked. There is a discussion about the +.\" HTML .\" validity of UTF-8 strings .\" -in the main +in the .\" HREF -\fBpcre\fP +\fBpcreunicode\fP .\" -page. If an invalid UTF-8 sequence of bytes is found, \fBpcre_compile()\fP -returns an error. If you already know that your pattern is valid, and you want -to skip this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK -option. When it is set, the effect of passing an invalid UTF-8 string as a -pattern is undefined. It may cause your program to crash. Note that this option -can also be passed to \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, to suppress -the UTF-8 validity checking of subject strings. +page. If an invalid UTF-8 sequence is found, \fBpcre_compile()\fP returns an +error. If you already know that your pattern is valid, and you want to skip +this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK option. +When it is set, the effect of passing an invalid UTF-8 string as a pattern is +undefined. It may cause your program to crash. Note that this option can also +be passed to \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, to suppress the +validity checking of subject strings. . . .SH "COMPILATION ERROR CODES" @@ -737,8 +843,9 @@ .sp The following table lists the error codes than may be returned by \fBpcre_compile2()\fP, along with the error messages that may be returned by -both compiling functions. As PCRE has developed, some error codes have fallen -out of use. To avoid confusion, they have not been re-used. +both compiling functions. Note that error messages are always 8-bit ASCII +strings, even in 16-bit mode. As PCRE has developed, some error codes have +fallen out of use. To avoid confusion, they have not been re-used. .sp 0 no error 1 \e at end of pattern @@ -772,26 +879,26 @@ 29 (?R or (?[+-]digits must be followed by ) 30 unknown POSIX class name 31 POSIX collating elements are not supported - 32 this version of PCRE is not compiled with PCRE_UTF8 support + 32 this version of PCRE is compiled without UTF support 33 [this code is not in use] 34 character value in \ex{...} sequence is too large 35 invalid condition (?(0) 36 \eC not allowed in lookbehind assertion - 37 PCRE does not support \eL, \el, \eN, \eU, or \eu + 37 PCRE does not support \eL, \el, \eN{name}, \eU, or \eu 38 number after (?C is > 255 39 closing ) for (?C expected 40 recursive call could loop indefinitely 41 unrecognized character after (?P 42 syntax error in subpattern name (missing terminator) 43 two named subpatterns have the same name - 44 invalid UTF-8 string + 44 invalid UTF-8 string (specifically UTF-8) 45 support for \eP, \ep, and \eX has not been compiled 46 malformed \eP or \ep sequence 47 unknown property name after \eP or \ep 48 subpattern name is too long (maximum 32 characters) 49 too many named subpatterns (maximum 10000) 50 [this code is not in use] - 51 octal value is greater than \e377 (not in UTF-8 mode) + 51 octal value is greater than \e377 in 8-bit non-UTF-8 mode 52 internal error: overran compiling workspace 53 internal error: previously-checked referenced subpattern not found @@ -810,12 +917,23 @@ 65 different names for subpatterns of the same number are not allowed 66 (*MARK) must have an argument - 67 this version of PCRE is not compiled with PCRE_UCP support + 67 this version of PCRE is not compiled with Unicode property + support + 68 \ec must be followed by an ASCII character + 69 \ek is not followed by a braced, angle-bracketed, or quoted name + 70 internal error: unknown opcode in find_fixedlength() + 71 \eN is not supported in a class + 72 too many forward references + 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff) + 74 invalid UTF-16 string (specifically UTF-16) + 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) + 76 character value in \eu.... sequence is too large .sp The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. . . +.\" HTML .SH "STUDYING A PATTERN" .rs .sp @@ -846,8 +964,29 @@ wants to pass any of the other fields to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, it must set up its own \fBpcre_extra\fP block. .P -The second argument of \fBpcre_study()\fP contains option bits. At present, no -options are defined, and this argument should always be zero. +The second argument of \fBpcre_study()\fP contains option bits. There are three +options: +.sp + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE +.sp +If any of these are set, and the just-in-time compiler is available, the +pattern is further compiled into machine code that executes much faster than +the \fBpcre_exec()\fP interpretive matching function. If the just-in-time +compiler is not available, these options are ignored. All other bits in the +\fIoptions\fP argument must be zero. +.P +JIT compilation is a heavyweight optimization. It can take some time for +patterns to be analyzed, and for one-off matches and simple patterns the +benefit of faster execution might be offset by a much slower study time. +Not all patterns can be optimized by the JIT compiler. For those that cannot be +handled, matching automatically falls back to the \fBpcre_exec()\fP +interpreter. For more details, see the +.\" HREF +\fBpcrejit\fP +.\" +documentation. .P The third argument for \fBpcre_study()\fP is a pointer for an error message. If studying succeeds (even if no data is returned), the variable it points to is @@ -856,13 +995,29 @@ should test the error pointer for NULL after calling \fBpcre_study()\fP, to be sure that it has run successfully. .P -This is a typical call to \fBpcre_study\fP(): +When you are finished with a pattern, you can free the memory used for the +study data by calling \fBpcre_free_study()\fP. This function was added to the +API for release 8.20. For earlier versions, the memory could be freed with +\fBpcre_free()\fP, just like the pattern itself. This will still work in cases +where JIT optimization is not used, but it is advisable to change to the new +function when convenient. +.P +This is a typical way in which \fBpcre_study\fP() is used (except that in a +real application there should be tests for errors): .sp - pcre_extra *pe; - pe = pcre_study( + int rc; + pcre *re; + pcre_extra *sd; + re = pcre_compile("pattern", 0, &error, &erroroffset, NULL); + sd = pcre_study( re, /* result of pcre_compile() */ - 0, /* no options exist */ + 0, /* no options */ &error); /* set to NULL or points to a message */ + rc = pcre_exec( /* see below for details of pcre_exec() options */ + re, sd, "subject", 7, 0, 0, ovector, 30); + ... + pcre_free_study(sd); + pcre_free(re); .sp Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not @@ -875,13 +1030,15 @@ Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start -matching. +matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.) .P -The two optimizations just described can be disabled by setting the -PCRE_NO_START_OPTIMIZE option when calling \fBpcre_exec()\fP or -\fBpcre_dfa_exec()\fP. You might want to do this if your pattern contains -callouts or (*MARK), and you want to make use of these facilities in cases -where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE +These two optimizations apply to both \fBpcre_exec()\fP and +\fBpcre_dfa_exec()\fP, and the information is also used by the JIT compiler. +The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option +when calling \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, but if this is done, +JIT execution is also disabled. You might want to do this if your pattern +contains callouts or (*MARK) and you want to make use of these facilities in +cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE .\" HTML .\" below. @@ -894,14 +1051,15 @@ .sp PCRE handles caseless matching, and determines whether characters are letters, digits, or whatever, by reference to a set of tables, indexed by character -value. When running in UTF-8 mode, this applies only to characters with codes -less than 128. By default, higher-valued codes never match escapes such as \ew -or \ed, but they can be tested with \ep if PCRE is built with Unicode character -property support. Alternatively, the PCRE_UCP option can be set at compile -time; this causes \ew and friends to use Unicode property support instead of -built-in tables. The use of locales with Unicode is discouraged. If you are -handling characters with codes greater than 128, you should either use UTF-8 -and Unicode, or use locales, but not try to mix the two. +value. When running in UTF-8 mode, this applies only to characters +with codes less than 128. By default, higher-valued codes never match escapes +such as \ew or \ed, but they can be tested with \ep if PCRE is built with +Unicode character property support. Alternatively, the PCRE_UCP option can be +set at compile time; this causes \ew and friends to use Unicode property +support instead of built-in tables. The use of locales with Unicode is +discouraged. If you are handling characters with codes greater than 128, you +should either use UTF-8 and Unicode, or use locales, but not try to mix the +two. .P PCRE contains an internal set of tables that are used when the final argument of \fBpcre_compile()\fP is NULL. These are sufficient for many applications. @@ -946,6 +1104,7 @@ below in the section on matching a pattern. . . +.\" HTML .SH "INFORMATION ABOUT A PATTERN" .rs .sp @@ -954,8 +1113,8 @@ .B int \fIwhat\fP, void *\fIwhere\fP); .PP The \fBpcre_fullinfo()\fP function returns information about a compiled -pattern. It replaces the obsolete \fBpcre_info()\fP function, which is -nevertheless retained for backwards compability (and is documented below). +pattern. It replaces the \fBpcre_info()\fP function, which was removed from the +library at version 8.30, after more than 10 years of obsolescence. .P The first argument for \fBpcre_fullinfo()\fP is a pointer to the compiled pattern. The second argument is the result of \fBpcre_study()\fP, or NULL if @@ -964,20 +1123,24 @@ to receive the data. The yield of the function is zero for success, or one of the following negative numbers: .sp - PCRE_ERROR_NULL the argument \fIcode\fP was NULL - the argument \fIwhere\fP was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found - PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid + PCRE_ERROR_NULL the argument \fIcode\fP was NULL + the argument \fIwhere\fP was NULL + PCRE_ERROR_BADMAGIC the "magic number" was not found + PCRE_ERROR_BADENDIANNESS the pattern was compiled with different + endianness + PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid .sp The "magic number" is placed at the start of each compiled pattern as an simple -check against passing an arbitrary memory pointer. Here is a typical call of -\fBpcre_fullinfo()\fP, to obtain the length of the compiled pattern: +check against passing an arbitrary memory pointer. The endianness error can +occur if a compiled pattern is saved and reloaded on a different host. Here is +a typical call of \fBpcre_fullinfo()\fP, to obtain the length of the compiled +pattern: .sp int rc; size_t length; rc = pcre_fullinfo( re, /* result of pcre_compile() */ - pe, /* result of pcre_study(), or NULL */ + sd, /* result of pcre_study(), or NULL */ PCRE_INFO_SIZE, /* what is required */ &length); /* where to put the data */ .sp @@ -1005,13 +1168,17 @@ .sp PCRE_INFO_FIRSTBYTE .sp -Return information about the first byte of any matched string, for a -non-anchored pattern. The fourth argument should point to an \fBint\fP -variable. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name is -still recognized for backwards compatibility.) +Return information about the first data unit of any matched string, for a +non-anchored pattern. (The name of this option refers to the 8-bit library, +where data units are bytes.) The fourth argument should point to an \fBint\fP +variable. .P -If there is a fixed first byte, for example, from a pattern such as -(cat|cow|coyote), its value is returned. Otherwise, if either +If there is a fixed first value, for example, the letter "c" from a pattern +such as (cat|cow|coyote), its value is returned. In the 8-bit library, the +value is always less than 256; in the 16-bit library the value can be up to +0xffff. +.P +If there is no fixed first value, and if either .sp (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or @@ -1026,7 +1193,7 @@ PCRE_INFO_FIRSTTABLE .sp If the pattern was studied, and this resulted in the construction of a 256-bit -table indicating a fixed set of bytes for the first byte in any matching +table indicating a fixed set of values for the first data unit in any matching string, a pointer to the table is returned. Otherwise NULL is returned. The fourth argument should point to an \fBunsigned char *\fP variable. .sp @@ -1042,22 +1209,47 @@ 0. The fourth argument should point to an \fBint\fP variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. .sp + PCRE_INFO_JIT +.sp +Return 1 if the pattern was studied with one of the JIT options, and +just-in-time compiling was successful. The fourth argument should point to an +\fBint\fP variable. A return value of 0 means that JIT support is not available +in this version of PCRE, or that the pattern was not studied with a JIT option, +or that the JIT compiler could not handle this particular pattern. See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for details of what can and cannot be handled. +.sp + PCRE_INFO_JITSIZE +.sp +If the pattern was successfully studied with a JIT option, return the size of +the JIT compiled code, otherwise return zero. The fourth argument should point +to a \fBsize_t\fP variable. +.sp PCRE_INFO_LASTLITERAL .sp -Return the value of the rightmost literal byte that must exist in any matched -string, other than at its start, if such a byte has been recorded. The fourth -argument should point to an \fBint\fP variable. If there is no such byte, -1 is -returned. For anchored patterns, a last literal byte is recorded only if it -follows something of variable length. For example, for the pattern +Return the value of the rightmost literal data unit that must exist in any +matched string, other than at its start, if such a value has been recorded. The +fourth argument should point to an \fBint\fP variable. If there is no such +value, -1 is returned. For anchored patterns, a last literal value is recorded +only if it follows something of variable length. For example, for the pattern /^a\ed+z\ed+/ the returned value is "z", but for /^a\edz\ed/ the returned value is -1. .sp + PCRE_INFO_MAXLOOKBEHIND +.sp +Return the number of characters (NB not bytes) in the longest lookbehind +assertion in the pattern. Note that the simple assertions \eb and \eB require a +one-character lookbehind. This information is useful when doing multi-segment +matching using the partial matching facilities. +.sp PCRE_INFO_MINLENGTH .sp If the pattern was studied and a minimum length for matching subject strings was computed, its value is returned. Otherwise the returned value is -1. The -value is a number of characters, not bytes (this may be relevant in UTF-8 -mode). The fourth argument should point to an \fBint\fP variable. A +value is a number of characters, which in UTF-8 mode may be different from the +number of bytes. The fourth argument should point to an \fBint\fP variable. A non-negative value is a lower bound to the length of any matching string. There may not be any strings of that length that do actually match, but every string that does match is at least that long. @@ -1080,9 +1272,11 @@ the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each entry; both of these return an \fBint\fP value. The entry size depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first -entry of the table (a pointer to \fBchar\fP). The first two bytes of each entry -are the number of the capturing parenthesis, most significant byte first. The -rest of the entry is the corresponding name, zero terminated. +entry of the table. This is a pointer to \fBchar\fP in the 8-bit library, where +the first two bytes of each entry are the number of the capturing parenthesis, +most significant byte first. In the 16-bit library, the pointer points to +16-bit data units, the first of which contains the parenthesis number. The rest +of the entry is the corresponding name, zero terminated. .P The names are in alphabetical order. Duplicate names may appear if (?| is used to create multiple groups with the same number, as described in the @@ -1101,8 +1295,8 @@ necessarily the case because later subpatterns may have lower numbers. .P As a simple example of the name/number table, consider the following pattern -(assume PCRE_EXTENDED is set, so white space - including newlines - is -ignored): +after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white +space - including newlines - is ignored): .sp .\" JOIN (? (?(\ed\ed)?\ed\ed) - @@ -1157,43 +1351,32 @@ .sp PCRE_INFO_SIZE .sp -Return the size of the compiled pattern, that is, the value that was passed as -the argument to \fBpcre_malloc()\fP when PCRE was getting memory in which to -place the compiled data. The fourth argument should point to a \fBsize_t\fP -variable. +Return the size of the compiled pattern in bytes (for both libraries). The +fourth argument should point to a \fBsize_t\fP variable. This value does not +include the size of the \fBpcre\fP structure that is returned by +\fBpcre_compile()\fP. The value that is passed as the argument to +\fBpcre_malloc()\fP when \fBpcre_compile()\fP is getting memory in which to +place the compiled data is the value returned by this option plus the size of +the \fBpcre\fP structure. Studying a compiled pattern, with or without JIT, +does not alter the value returned by this option. .sp PCRE_INFO_STUDYSIZE .sp -Return the size of the data block pointed to by the \fIstudy_data\fP field in -a \fBpcre_extra\fP block. That is, it is the value that was passed to -\fBpcre_malloc()\fP when PCRE was getting memory into which to place the data -created by \fBpcre_study()\fP. If \fBpcre_extra\fP is NULL, or there is no +Return the size in bytes of the data block pointed to by the \fIstudy_data\fP +field in a \fBpcre_extra\fP block. If \fBpcre_extra\fP is NULL, or there is no study data, zero is returned. The fourth argument should point to a -\fBsize_t\fP variable. -. -. -.SH "OBSOLETE INFO FUNCTION" -.rs -.sp -.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int -.B *\fIfirstcharptr\fP); -.PP -The \fBpcre_info()\fP function is now obsolete because its interface is too -restrictive to return all the available data about a compiled pattern. New -programs should use \fBpcre_fullinfo()\fP instead. The yield of -\fBpcre_info()\fP is the number of capturing subpatterns, or one of the -following negative numbers: -.sp - PCRE_ERROR_NULL the argument \fIcode\fP was NULL - PCRE_ERROR_BADMAGIC the "magic number" was not found -.sp -If the \fIoptptr\fP argument is not NULL, a copy of the options with which the -pattern was compiled is placed in the integer it points to (see -PCRE_INFO_OPTIONS above). -.P -If the pattern is not anchored and the \fIfirstcharptr\fP argument is not NULL, -it is used to pass back information about the first character of any matched -string (see PCRE_INFO_FIRSTBYTE above). +\fBsize_t\fP variable. The \fIstudy_data\fP field is set by \fBpcre_study()\fP +to record information that will speed up matching (see the section entitled +.\" HTML +.\" +"Studying a pattern" +.\" +above). The format of the \fIstudy_data\fP block is private, but its length +is made available via this option so that it can be saved and restored (see the +.\" HREF +\fBpcreprecompile\fP +.\" +documentation for details). . . .SH "REFERENCE COUNTS" @@ -1231,9 +1414,13 @@ The function \fBpcre_exec()\fP is called to match a subject string against a compiled pattern, which is passed in the \fIcode\fP argument. If the pattern was studied, the result of the study should be passed in the -\fIextra\fP argument. This function is the main matching facility of the -library, and it operates in a Perl-like manner. For specialist use there is -also an alternative matching function, which is described +\fIextra\fP argument. You can call \fBpcre_exec()\fP with the same \fIcode\fP +and \fIextra\fP arguments as many times as you like, in order to match +different subject strings with the same pattern. +.P +This function is the main matching facility of the library, and it operates in +a Perl-like manner. For specialist use there is also an alternative matching +function, which is described .\" HTML .\" below @@ -1264,6 +1451,7 @@ ovector, /* vector of integers for substring information */ 30); /* number of elements (NOT size in bytes) */ . +. .\" HTML .SS "Extra data for \fBpcre_exec()\fR" .rs @@ -1276,38 +1464,50 @@ .sp unsigned long int \fIflags\fP; void *\fIstudy_data\fP; + void *\fIexecutable_jit\fP; unsigned long int \fImatch_limit\fP; unsigned long int \fImatch_limit_recursion\fP; void *\fIcallout_data\fP; const unsigned char *\fItables\fP; unsigned char **\fImark\fP; .sp -The \fIflags\fP field is a bitmap that specifies which of the other fields -are set. The flag bits are: +In the 16-bit version of this structure, the \fImark\fP field has type +"PCRE_UCHAR16 **". +.P +The \fIflags\fP field is used to specify which of the other fields are set. The +flag bits are: .sp - PCRE_EXTRA_STUDY_DATA + PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_EXECUTABLE_JIT + PCRE_EXTRA_MARK PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_MATCH_LIMIT_RECURSION - PCRE_EXTRA_CALLOUT_DATA + PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES - PCRE_EXTRA_MARK .sp -Other flag bits should be set to zero. The \fIstudy_data\fP field is set in the -\fBpcre_extra\fP block that is returned by \fBpcre_study()\fP, together with -the appropriate flag bit. You should not set this yourself, but you may add to -the block by setting the other fields and their corresponding flag bits. +Other flag bits should be set to zero. The \fIstudy_data\fP field and sometimes +the \fIexecutable_jit\fP field are set in the \fBpcre_extra\fP block that is +returned by \fBpcre_study()\fP, together with the appropriate flag bits. You +should not set these yourself, but you may add to the block by setting other +fields and their corresponding flag bits. .P The \fImatch_limit\fP field provides a means of preventing PCRE from using up a vast amount of resources when running patterns that are not going to match, but which have a very large number of possibilities in their search trees. The classic example is a pattern that uses nested unlimited repeats. .P -Internally, PCRE uses a function called \fBmatch()\fP which it calls repeatedly -(sometimes recursively). The limit set by \fImatch_limit\fP is imposed on the -number of times this function is called during a match, which has the effect of -limiting the amount of backtracking that can take place. For patterns that are -not anchored, the count restarts from zero for each position in the subject -string. +Internally, \fBpcre_exec()\fP uses a function called \fBmatch()\fP, which it +calls repeatedly (sometimes recursively). The limit set by \fImatch_limit\fP is +imposed on the number of times this function is called during a match, which +has the effect of limiting the amount of backtracking that can take place. For +patterns that are not anchored, the count restarts from zero for each position +in the subject string. +.P +When \fBpcre_exec()\fP is called with a pattern that was successfully studied +with a JIT option, the way that the matching is executed is entirely different. +However, there is still the possibility of runaway matching that goes on for a +very long time, and so the \fImatch_limit\fP value is also used in this case +(but in a different way) to limit how long the matching can continue. .P The default value for the limit can be set when PCRE is built; the default default is 10 million, which handles all but the most extreme cases. You can @@ -1322,9 +1522,10 @@ total number of calls, because not all calls to \fBmatch()\fP are recursive. This limit is of use only if it is set smaller than \fImatch_limit\fP. .P -Limiting the recursion depth limits the amount of stack that can be used, or, -when PCRE has been compiled to use memory on the heap instead of the stack, the -amount of heap memory that can be used. +Limiting the recursion depth limits the amount of machine stack that can be +used, or, when PCRE has been compiled to use memory on the heap instead of the +stack, the amount of heap memory that can be used. This limit is not relevant, +and is ignored, when matching is done using JIT compiled code. .P The default value for \fImatch_limit_recursion\fP can be set when PCRE is built; the default default is the same value as the default for @@ -1355,13 +1556,13 @@ documentation for a discussion of saving compiled patterns for later use. .P If PCRE_EXTRA_MARK is set in the \fIflags\fP field, the \fImark\fP field must -be set to point to a \fBchar *\fP variable. If the pattern contains any +be set to point to a suitable variable. If the pattern contains any backtracking control verbs such as (*MARK:NAME), and the execution ends up with a name to pass back, a pointer to the name string (zero terminated) is placed in the variable pointed to by the \fImark\fP field. The names are within the compiled pattern; if you wish to retain such a name you must copy it before freeing the memory of a compiled pattern. If there is no name to pass back, the -variable pointed to by the \fImark\fP field set to NULL. For details of the +variable pointed to by the \fImark\fP field is set to NULL. For details of the backtracking control verbs, see the section entitled .\" HTML .\" @@ -1381,8 +1582,15 @@ The unused bits of the \fIoptions\fP argument for \fBpcre_exec()\fP must be zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_\fIxxx\fP, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, -PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and -PCRE_PARTIAL_HARD. +PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and +PCRE_PARTIAL_SOFT. +.P +If the pattern was successfully studied with one of the just-in-time (JIT) +compile options, the only supported options for JIT execution are +PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, +PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an +unsupported option is used, JIT execution is disabled and the normal +interpretive code in \fBpcre_exec()\fP is run. .sp PCRE_ANCHORED .sp @@ -1501,7 +1709,8 @@ "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting position in the subject string. If PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching -time. +time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, +matching is always done using interpretively. .P Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern @@ -1534,22 +1743,29 @@ .sp When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8 string is automatically checked when \fBpcre_exec()\fP is subsequently called. -The value of \fIstartoffset\fP is also checked to ensure that it points to the -start of a UTF-8 character. There is a discussion about the validity of UTF-8 -strings in the -.\" HTML +The entire string is checked before any other processing takes place. The value +of \fIstartoffset\fP is also checked to ensure that it points to the start of a +UTF-8 character. There is a discussion about the +.\" HTML .\" -section on UTF-8 support +validity of UTF-8 strings .\" -in the main +in the .\" HREF -\fBpcre\fP +\fBpcreunicode\fP .\" -page. If an invalid UTF-8 sequence of bytes is found, \fBpcre_exec()\fP returns -the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is -a truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORTUTF8. If -\fIstartoffset\fP contains a value that does not point to the start of a UTF-8 -character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is +page. If an invalid sequence of bytes is found, \fBpcre_exec()\fP returns the +error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a +truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both +cases, information about the precise nature of the error may also be returned +(see the descriptions of these errors in the section entitled \fIError return +values from\fP \fBpcre_exec()\fP +.\" HTML +.\" +below). +.\" +If \fIstartoffset\fP contains a value that does not point to the start of a +UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. .P If you already know that your subject is valid, and you want to skip these @@ -1557,9 +1773,9 @@ calling \fBpcre_exec()\fP. You might want to do this for the second and subsequent calls to \fBpcre_exec()\fP if you are making repeated calls to find all the matches in a single subject string. However, you should be sure that -the value of \fIstartoffset\fP points to the start of a UTF-8 character (or the -end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an -invalid UTF-8 string as a subject or an invalid value of \fIstartoffset\fP is +the value of \fIstartoffset\fP points to the start of a character (or the end +of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an +invalid string as a subject or an invalid value of \fIstartoffset\fP is undefined. Your program may crash. .sp PCRE_PARTIAL_HARD @@ -1594,7 +1810,7 @@ .rs .sp The subject string is passed to \fBpcre_exec()\fP as a pointer in -\fIsubject\fP, a length (in bytes) in \fIlength\fP, and a starting byte offset +\fIsubject\fP, a length in bytes in \fIlength\fP, and a starting byte offset in \fIstartoffset\fP. If this is negative or greater than the length of the subject, \fBpcre_exec()\fP returns PCRE_ERROR_BADOFFSET. When the starting offset is zero, the search for a match starts at the beginning of the subject, @@ -1682,12 +1898,27 @@ .P If the vector is too small to hold all the captured substring offsets, it is used as far as possible (up to two-thirds of its length), and the function -returns a value of zero. If the substring offsets are not of interest, -\fBpcre_exec()\fP may be called with \fIovector\fP passed as NULL and -\fIovecsize\fP as zero. However, if the pattern contains back references and -the \fIovector\fP is not big enough to remember the related substrings, PCRE -has to get additional memory for use during matching. Thus it is usually -advisable to supply an \fIovector\fP. +returns a value of zero. If neither the actual string matched nor any captured +substrings are of interest, \fBpcre_exec()\fP may be called with \fIovector\fP +passed as NULL and \fIovecsize\fP as zero. However, if the pattern contains +back references and the \fIovector\fP is not big enough to remember the related +substrings, PCRE has to get additional memory for use during matching. Thus it +is usually advisable to supply an \fIovector\fP of reasonable size. +.P +There are some cases where zero is returned (indicating vector overflow) when +in fact the vector is exactly the right size for the final match. For example, +consider the pattern +.sp + (a)(?:(b)c|bd) +.sp +If a vector of 6 elements (allowing for only 1 captured substring) is given +with subject string "abd", \fBpcre_exec()\fP will try to set the second +captured string, thereby recording a vector overflow, before failing to match +"c" and backing up to try the second alternative. The zero return, however, +does correctly indicate that the maximum number of slots (namely 2) have been +filled. In similar cases where there is temporary overflow, but the final +number of used slots is actually less than the maximum, a non-zero value is +returned. .P The \fBpcre_fullinfo()\fP function can be used to find out how many capturing subpatterns there are in a compiled pattern. The smallest size for @@ -1708,15 +1939,16 @@ number is 1, and the offsets for for the second and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. .P -\fBNote\fP: Elements of \fIovector\fP that do not correspond to capturing -parentheses in the pattern are never changed. That is, if a pattern contains -\fIn\fP capturing parentheses, no more than \fIovector[0]\fP to -\fIovector[2n+1]\fP are set by \fBpcre_exec()\fP. The other elements retain -whatever values they previously had. +\fBNote\fP: Elements in the first two-thirds of \fIovector\fP that do not +correspond to capturing parentheses in the pattern are never changed. That is, +if a pattern contains \fIn\fP capturing parentheses, no more than +\fIovector[0]\fP to \fIovector[2n+1]\fP are set by \fBpcre_exec()\fP. The other +elements (in the first two-thirds) retain whatever values they previously had. .P Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. . +. .\" HTML .SS "Error return values from \fBpcre_exec()\fP" .rs @@ -1786,14 +2018,24 @@ .sp PCRE_ERROR_BADUTF8 (-10) .sp -A string that contains an invalid UTF-8 byte sequence was passed as a subject. -However, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 -character at the end of the subject, PCRE_ERROR_SHORTUTF8 is used instead. +A string that contains an invalid UTF-8 byte sequence was passed as a subject, +and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector +(\fIovecsize\fP) is at least 2, the byte offset to the start of the the invalid +UTF-8 character is placed in the first element, and a reason code is placed in +the second element. The reason codes are listed in the +.\" HTML +.\" +following section. +.\" +For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a +truncated UTF-8 character at the end of the subject (reason codes 1 to 5), +PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. .sp PCRE_ERROR_BADUTF8_OFFSET (-11) .sp -The UTF-8 byte sequence that was passed as a subject was valid, but the value -of \fIstartoffset\fP did not point to the beginning of a UTF-8 character or the +The UTF-8 byte sequence that was passed as a subject was checked and found to +be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of +\fIstartoffset\fP did not point to the beginning of a UTF-8 character or the end of the subject. .sp PCRE_ERROR_PARTIAL (-12) @@ -1837,11 +2079,127 @@ .sp PCRE_ERROR_SHORTUTF8 (-25) .sp -The subject string ended with an incomplete (truncated) UTF-8 character, and -the PCRE_PARTIAL_HARD option was set. Without this option, PCRE_ERROR_BADUTF8 -is returned in this situation. +This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string +ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set. +Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in +fact sufficient to detect this case, but this special error code for +PCRE_PARTIAL_HARD precedes the implementation of returned information; it is +retained for backwards compatibility. +.sp + PCRE_ERROR_RECURSELOOP (-26) +.sp +This error is returned when \fBpcre_exec()\fP detects a recursion loop within +the pattern. Specifically, it means that either the whole pattern or a +subpattern has been called recursively for the second time at the same position +in the subject string. Some simple patterns that might do this are detected and +faulted at compile time, but more complicated cases, in particular mutual +recursions between two different subpatterns, cannot be detected until run +time. +.sp + PCRE_ERROR_JIT_STACKLIMIT (-27) +.sp +This error is returned when a pattern that was successfully studied using a +JIT compile option is being matched, but the memory available for the +just-in-time processing stack is not large enough. See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for more details. +.sp + PCRE_ERROR_BADMODE (-28) +.sp +This error is given if a pattern that was compiled by the 8-bit library is +passed to a 16-bit library function, or vice versa. +.sp + PCRE_ERROR_BADENDIANNESS (-29) +.sp +This error is given if a pattern that was compiled and saved is reloaded on a +host with different endianness. The utility function +\fBpcre_pattern_to_host_byte_order()\fP can be used to convert such a pattern +so that it runs on the new host. .P -Error numbers -16 to -20 and -22 are not used by \fBpcre_exec()\fP. +Error numbers -16 to -20, -22, and -30 are not used by \fBpcre_exec()\fP. +. +. +.\" HTML +.SS "Reason codes for invalid UTF-8 strings" +.rs +.sp +This section applies only to the 8-bit library. The corresponding information +for the 16-bit library is given in the +.\" HREF +\fBpcre16\fP +.\" +page. +.P +When \fBpcre_exec()\fP returns either PCRE_ERROR_BADUTF8 or +PCRE_ERROR_SHORTUTF8, and the size of the output vector (\fIovecsize\fP) is at +least 2, the offset of the start of the invalid UTF-8 character is placed in +the first output vector element (\fIovector[0]\fP) and a reason code is placed +in the second element (\fIovector[1]\fP). The reason codes are given names in +the \fBpcre.h\fP header file: +.sp + PCRE_UTF8_ERR1 + PCRE_UTF8_ERR2 + PCRE_UTF8_ERR3 + PCRE_UTF8_ERR4 + PCRE_UTF8_ERR5 +.sp +The string ends with a truncated UTF-8 character; the code specifies how many +bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be +no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279) +allows for up to 6 bytes, and this is checked first; hence the possibility of +4 or 5 missing bytes. +.sp + PCRE_UTF8_ERR6 + PCRE_UTF8_ERR7 + PCRE_UTF8_ERR8 + PCRE_UTF8_ERR9 + PCRE_UTF8_ERR10 +.sp +The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the +character do not have the binary value 0b10 (that is, either the most +significant bit is 0, or the next bit is 1). +.sp + PCRE_UTF8_ERR11 + PCRE_UTF8_ERR12 +.sp +A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; +these code points are excluded by RFC 3629. +.sp + PCRE_UTF8_ERR13 +.sp +A 4-byte character has a value greater than 0x10fff; these code points are +excluded by RFC 3629. +.sp + PCRE_UTF8_ERR14 +.sp +A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of +code points are reserved by RFC 3629 for use with UTF-16, and so are excluded +from UTF-8. +.sp + PCRE_UTF8_ERR15 + PCRE_UTF8_ERR16 + PCRE_UTF8_ERR17 + PCRE_UTF8_ERR18 + PCRE_UTF8_ERR19 +.sp +A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a +value that can be represented by fewer bytes, which is invalid. For example, +the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just +one byte. +.sp + PCRE_UTF8_ERR20 +.sp +The two most significant bits of the first byte of a character have the binary +value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a +byte can only validly occur as the second or subsequent byte of a multi-byte +character. +.sp + PCRE_UTF8_ERR21 +.sp +The first byte of a character has the value 0xfe or 0xff. These values can +never occur in a valid UTF-8 string. . . .SH "EXTRACTING CAPTURED SUBSTRINGS BY NUMBER" @@ -2006,6 +2364,7 @@ numbers. For this reason, the use of different names for subpatterns of the same number causes an error at compile time. . +. .SH "DUPLICATE SUBPATTERN NAMES" .rs .sp @@ -2039,7 +2398,11 @@ has run, they point to the first and last entries in the name-to-number table for the given name. The function itself returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if there are none. The format of the table is -described above in the section entitled \fIInformation about a pattern\fP. +described above in the section entitled \fIInformation about a pattern\fP +.\" HTML +.\" +above. +.\" Given all the relevant entries for the name, you can extract each of their numbers, and hence the captured data, if any. . @@ -2066,6 +2429,32 @@ will yield PCRE_ERROR_NOMATCH. . . +.SH "OBTAINING AN ESTIMATE OF STACK USAGE" +.rs +.sp +Matching certain patterns using \fBpcre_exec()\fP can use a lot of process +stack, which in certain environments can be rather limited in size. Some users +find it helpful to have an estimate of the amount of stack that is used by +\fBpcre_exec()\fP, to help them set recursion limits, as described in the +.\" HREF +\fBpcrestack\fP +.\" +documentation. The estimate that is output by \fBpcretest\fP when called with +the \fB-m\fP and \fB-C\fP options is obtained by calling \fBpcre_exec\fP with +the values NULL, NULL, NULL, -999, and -999 for its first five arguments. +.P +Normally, if its first argument is NULL, \fBpcre_exec()\fP immediately returns +the negative error code PCRE_ERROR_NULL, but with this special combination of +arguments, it returns instead a negative number whose absolute value is the +approximate stack frame size in bytes. (A negative number is used so that it is +clear that no match has happened.) The value is approximate because in some +cases, recursive calls to \fBpcre_exec()\fP occur when there are one or two +additional variables on the stack. +.P +If PCRE has been compiled to use the heap instead of the stack for recursion, +the value returned is the size of each block that is obtained from the heap. +. +. .\" HTML .SH "MATCHING A PATTERN: THE ALTERNATIVE FUNCTION" .rs @@ -2169,6 +2558,7 @@ .\" documentation. . +. .SS "Successful returns from \fBpcre_dfa_exec()\fP" .rs .sp @@ -2200,7 +2590,9 @@ The strings are returned in reverse order of length; that is, the longest matching string is given first. If there were too many matches to fit into \fIovector\fP, the yield of the function is zero, and the vector is filled with -the longest matches. +the longest matches. Unlike \fBpcre_exec()\fP, \fBpcre_dfa_exec()\fP can use +the entire \fIovector\fP for returning matched strings. +. . .SS "Error returns from \fBpcre_dfa_exec()\fP" .rs @@ -2229,8 +2621,9 @@ PCRE_ERROR_DFA_UMLIMIT (-18) .sp This return is given if \fBpcre_dfa_exec()\fP is called with an \fIextra\fP -block that contains a setting of the \fImatch_limit\fP field. This is not -supported (it is meaningless). +block that contains a setting of the \fImatch_limit\fP or +\fImatch_limit_recursion\fP fields. This is not supported (these fields are +meaningless for DFA matching). .sp PCRE_ERROR_DFA_WSSIZE (-19) .sp @@ -2243,12 +2636,19 @@ recursively, using private vectors for \fIovector\fP and \fIworkspace\fP. This error is given if the output vector is not large enough. This should be extremely rare, as a vector of size 1000 is used. +.sp + PCRE_ERROR_DFA_BADRESTART (-30) +.sp +When \fBpcre_dfa_exec()\fP is called with the \fBPCRE_DFA_RESTART\fP option, +some plausibility checks are made on the contents of the workspace, which +should contain data about the previous partial match. If any of these checks +fail, this error is given. . . .SH "SEE ALSO" .rs .sp -\fBpcrebuild\fP(3), \fBpcrecallout\fP(3), \fBpcrecpp(3)\fP(3), +\fBpcre16\fP(3), \fBpcrebuild\fP(3), \fBpcrecallout\fP(3), \fBpcrecpp(3)\fP(3), \fBpcrematching\fP(3), \fBpcrepartial\fP(3), \fBpcreposix\fP(3), \fBpcreprecompile\fP(3), \fBpcresample\fP(3), \fBpcrestack\fP(3). . @@ -2267,6 +2667,6 @@ .rs .sp .nf -Last updated: 21 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 17 June 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrebuild.3 pcre3-8.31/doc/pcrebuild.3 --- pcre3-8.12/doc/pcrebuild.3 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/doc/pcrebuild.3 2012-05-26 14:21:10.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREBUILD 3 +.TH PCREBUILD 3 "07 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions . @@ -32,49 +32,92 @@ exists as well, but as it specifies the default, it is not described. . . +.SH "BUILDING 8-BIT and 16-BIT LIBRARIES" +.rs +.sp +By default, a library called \fBlibpcre\fP is built, containing functions that +take string arguments contained in vectors of bytes, either as single-byte +characters, or interpreted as UTF-8 strings. You can also build a separate +library, called \fBlibpcre16\fP, in which strings are contained in vectors of +16-bit data units and interpreted either as single-unit characters or UTF-16 +strings, by adding +.sp + --enable-pcre16 +.sp +to the \fBconfigure\fP command. If you do not want the 8-bit library, add +.sp + --disable-pcre8 +.sp +as well. At least one of the two libraries must be built. Note that the C++ and +POSIX wrappers are for the 8-bit library only, and that \fBpcregrep\fP is an +8-bit program. None of these are built if you select only the 16-bit library. +. +. +.SH "BUILDING SHARED AND STATIC LIBRARIES" +.rs +.sp +The PCRE building process uses \fBlibtool\fP to build both shared and static +Unix libraries by default. You can suppress one of these by adding one of +.sp + --disable-shared + --disable-static +.sp +to the \fBconfigure\fP command, as required. +. +. .SH "C++ SUPPORT" .rs .sp -By default, the \fBconfigure\fP script will search for a C++ compiler and C++ -header files. If it finds them, it automatically builds the C++ wrapper library -for PCRE. You can disable this by adding +By default, if the 8-bit library is being built, the \fBconfigure\fP script +will search for a C++ compiler and C++ header files. If it finds them, it +automatically builds the C++ wrapper library (which supports only 8-bit +strings). You can disable this by adding .sp --disable-cpp .sp to the \fBconfigure\fP command. . . -.SH "UTF-8 SUPPORT" +.SH "UTF-8 and UTF-16 SUPPORT" .rs .sp -To build PCRE with support for UTF-8 Unicode character strings, add +To build PCRE with support for UTF Unicode character strings, add .sp - --enable-utf8 + --enable-utf .sp -to the \fBconfigure\fP command. Of itself, this does not make PCRE treat -strings as UTF-8. As well as compiling PCRE with this option, you also have -have to set the PCRE_UTF8 option when you call the \fBpcre_compile()\fP -or \fBpcre_compile2()\fP functions. +to the \fBconfigure\fP command. This setting applies to both libraries, adding +support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit +library. There are no separate options for enabling UTF-8 and UTF-16 +independently because that would allow ridiculous settings such as requesting +UTF-16 support while building only the 8-bit library. It is not possible to +build one library with UTF support and the other without in the same +configuration. (For backwards compatibility, --enable-utf8 is a synonym of +--enable-utf.) +.P +Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As +well as compiling PCRE with this option, you also have have to set the +PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling +functions. .P -If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE expects -its input to be either ASCII or UTF-8 (depending on the runtime option). It is +If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects +its input to be either ASCII or UTF-8 (depending on the run-time option). It is not possible to support both EBCDIC and UTF-8 codes in the same version of the -library. Consequently, --enable-utf8 and --enable-ebcdic are mutually +library. Consequently, --enable-utf and --enable-ebcdic are mutually exclusive. . . .SH "UNICODE CHARACTER PROPERTY SUPPORT" .rs .sp -UTF-8 support allows PCRE to process character values greater than 255 in the -strings that it handles. On its own, however, it does not provide any +UTF support allows the libraries to process character codepoints up to 0x10ffff +in the strings that they handle. On its own, however, it does not provide any facilities for accessing the properties of such characters. If you want to be able to use the pattern escapes \eP, \ep, and \eX, which refer to Unicode character properties, you must add .sp --enable-unicode-properties .sp -to the \fBconfigure\fP command. This implies UTF-8 support, even if you have +to the \fBconfigure\fP command. This implies UTF support, even if you have not explicitly requested it. .P Including Unicode property support adds around 30K of tables to the PCRE @@ -86,6 +129,27 @@ documentation. . . +.SH "JUST-IN-TIME COMPILER SUPPORT" +.rs +.sp +Just-in-time compiler support is included in the build by specifying +.sp + --enable-jit +.sp +This support is available only for certain hardware architectures. If this +option is set for an unsupported architecture, a compile time error occurs. +See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for a discussion of JIT usage. When JIT support is enabled, +pcregrep automatically makes use of it, unless you add +.sp + --disable-pcregrep-jit +.sp +to the "configure" command. +. +. .SH "CODE VALUE OF NEWLINE" .rs .sp @@ -132,22 +196,10 @@ called. . . -.SH "BUILDING SHARED AND STATIC LIBRARIES" -.rs -.sp -The PCRE building process uses \fBlibtool\fP to build both shared and static -Unix libraries by default. You can suppress one of these by adding one of -.sp - --disable-shared - --disable-static -.sp -to the \fBconfigure\fP command, as required. -. -. .SH "POSIX MALLOC USAGE" .rs .sp -When PCRE is called through the POSIX interface (see the +When the 8-bit library is called through the POSIX interface (see the .\" HREF \fBpcreposix\fP .\" @@ -172,14 +224,15 @@ metacharacter). By default, two-byte values are used for these offsets, leading to a maximum size for a compiled pattern of around 64K. This is sufficient to handle all but the most gigantic patterns. Nevertheless, some people do want to -process truyl enormous patterns, so it is possible to compile PCRE to use +process truly enormous patterns, so it is possible to compile PCRE to use three-byte or four-byte offsets by adding a setting such as .sp --with-link-size=3 .sp -to the \fBconfigure\fP command. The value given must be 2, 3, or 4. Using -longer offsets slows down the operation of PCRE because it has to load -additional bytes when handling them. +to the \fBconfigure\fP command. The value given must be 2, 3, or 4. For the +16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows +down the operation of PCRE because it has to load additional data when handling +them. . . .SH "AVOIDING EXCESSIVE STACK USAGE" @@ -260,7 +313,7 @@ .sp to the \fBconfigure\fP command, the distributed tables are no longer used. Instead, a program called \fBdftables\fP is compiled and run. This outputs the -source for new set of tables, created in the default locale of your C runtime +source for new set of tables, created in the default locale of your C run-time system. (This method of replacing the tables does not work if you are cross compiling, because \fBdftables\fP is run on the local host. If you need to create alternative tables when cross compiling, you will have to do so "by @@ -280,7 +333,7 @@ to the \fBconfigure\fP command. This setting implies --enable-rebuild-chartables. You should only use it if you know that you are in an EBCDIC environment (for example, an IBM mainframe operating system). The ---enable-ebcdic option is incompatible with --enable-utf8. +--enable-ebcdic option is incompatible with --enable-utf. . . .SH "PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT" @@ -298,6 +351,23 @@ they are not. . . +.SH "PCREGREP BUFFER SIZE" +.rs +.sp +\fBpcregrep\fP uses an internal buffer to hold a "window" on the file it is +scanning, in order to be able to output "before" and "after" lines when it +finds a match. The size of the buffer is controlled by a parameter whose +default value is 20K. The buffer itself is three times this size, but because +of the way it is used for holding "before" lines, the longest line that is +guaranteed to be processable is the parameter size. You can change the default +parameter value by adding, for example, +.sp + --with-pcregrep-bufsize=50K +.sp +to the \fBconfigure\fP command. The caller of \fPpcregrep\fP can, however, +override this value by specifying a run-time option. +. +. .SH "PCRETEST OPTION FOR LIBREADLINE SUPPORT" .rs .sp @@ -333,7 +403,7 @@ .SH "SEE ALSO" .rs .sp -\fBpcreapi\fP(3), \fBpcre_config\fP(3). +\fBpcreapi\fP(3), \fBpcre16\fP, \fBpcre_config\fP(3). . . .SH AUTHOR @@ -350,6 +420,6 @@ .rs .sp .nf -Last updated: 29 September 2009 -Copyright (c) 1997-2009 University of Cambridge. +Last updated: 07 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrecallout.3 pcre3-8.31/doc/pcrecallout.3 --- pcre3-8.12/doc/pcrecallout.3 2010-11-21 18:50:52.000000000 +0000 +++ pcre3-8.31/doc/pcrecallout.3 2012-03-31 18:00:11.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRECALLOUT 3 +.TH PCRECALLOUT 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE CALLOUTS" @@ -6,11 +6,14 @@ .sp .B int (*pcre_callout)(pcre_callout_block *); .PP +.B int (*pcre16_callout)(pcre16_callout_block *); +.PP PCRE provides a feature called "callout", which is a means of temporarily passing control to the caller of PCRE in the middle of pattern matching. The caller of PCRE provides an external function by putting its entry point in the -global variable \fIpcre_callout\fP. By default, this variable contains NULL, -which disables all calling out. +global variable \fIpcre_callout\fP (\fIpcre16_callout\fP for the 16-bit +library). By default, this variable contains NULL, which disables all calling +out. .P Within a regular expression, (?C) indicates the points at which the external function is to be called. Different callout points can be identified by putting @@ -19,10 +22,9 @@ .sp (?C1)abc(?C2)def .sp -If the PCRE_AUTO_CALLOUT option bit is set when \fBpcre_compile()\fP or -\fBpcre_compile2()\fP is called, PCRE automatically inserts callouts, all with -number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT -is used with the pattern +If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE +automatically inserts callouts, all with number 255, before each item in the +pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern .sp A(\ed{2}|--) .sp @@ -39,6 +41,10 @@ command has an option that sets automatic callouts; when it is used, the output indicates how the pattern is matched. This is useful information when you are trying to optimize the performance of a particular pattern. +.P +The use of callouts in a pattern makes it ineligible for optimization by the +just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE +option always fails. . . .SH "MISSING CALLOUTS" @@ -61,35 +67,38 @@ been scanned far enough. .P You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE -option to \fBpcre_compile()\fP, \fBpcre_exec()\fP, or \fBpcre_dfa_exec()\fP, -or by starting the pattern with (*NO_START_OPT). This slows down the matching -process, but does ensure that callouts such as the example above are obeyed. +option to the matching function, or by starting the pattern with +(*NO_START_OPT). This slows down the matching process, but does ensure that +callouts such as the example above are obeyed. . . .SH "THE CALLOUT INTERFACE" .rs .sp During matching, when PCRE reaches a callout point, the external function -defined by \fIpcre_callout\fP is called (if it is set). This applies to both -the \fBpcre_exec()\fP and the \fBpcre_dfa_exec()\fP matching functions. The -only argument to the callout function is a pointer to a \fBpcre_callout\fP -block. This structure contains the following fields: -.sp - int \fIversion\fP; - int \fIcallout_number\fP; - int *\fIoffset_vector\fP; - const char *\fIsubject\fP; - int \fIsubject_length\fP; - int \fIstart_match\fP; - int \fIcurrent_position\fP; - int \fIcapture_top\fP; - int \fIcapture_last\fP; - void *\fIcallout_data\fP; - int \fIpattern_position\fP; - int \fInext_item_length\fP; +defined by \fIpcre_callout\fP or \fIpcre16_callout\fP is called (if it is set). +This applies to both normal and DFA matching. The only argument to the callout +function is a pointer to a \fBpcre_callout\fP or \fBpcre16_callout\fP block. +These structures contains the following fields: +.sp + int \fIversion\fP; + int \fIcallout_number\fP; + int *\fIoffset_vector\fP; + const char *\fIsubject\fP; (8-bit version) + PCRE_SPTR16 \fIsubject\fP; (16-bit version) + int \fIsubject_length\fP; + int \fIstart_match\fP; + int \fIcurrent_position\fP; + int \fIcapture_top\fP; + int \fIcapture_last\fP; + void *\fIcallout_data\fP; + int \fIpattern_position\fP; + int \fInext_item_length\fP; + const unsigned char *\fImark\fP; (8-bit version) + const PCRE_UCHAR16 *\fImark\fP; (16-bit version) .sp The \fIversion\fP field is an integer containing the version number of the -block format. The initial version was 0; the current version is 1. The version +block format. The initial version was 0; the current version is 2. The version number will change again in future if additional fields are added, but the intention is never to remove any of the existing fields. .P @@ -98,14 +107,14 @@ automatically generated callouts). .P The \fIoffset_vector\fP field is a pointer to the vector of offsets that was -passed by the caller to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. When -\fBpcre_exec()\fP is used, the contents can be inspected in order to extract +passed by the caller to the matching function. When \fBpcre_exec()\fP or +\fBpcre16_exec()\fP is used, the contents can be inspected, in order to extract substrings that have been matched so far, in the same way as for extracting -substrings after a match has completed. For \fBpcre_dfa_exec()\fP this field is -not useful. +substrings after a match has completed. For the DFA matching functions, this +field is not useful. .P The \fIsubject\fP and \fIsubject_length\fP fields contain copies of the values -that were passed to \fBpcre_exec()\fP. +that were passed to the matching function. .P The \fIstart_match\fP field normally contains the offset within the subject at which the current match attempt started. However, if the escape sequence \eK @@ -117,41 +126,47 @@ The \fIcurrent_position\fP field contains the offset within the subject of the current match pointer. .P -When the \fBpcre_exec()\fP function is used, the \fIcapture_top\fP field -contains one more than the number of the highest numbered captured substring so -far. If no substrings have been captured, the value of \fIcapture_top\fP is -one. This is always the case when \fBpcre_dfa_exec()\fP is used, because it -does not support captured substrings. +When the \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used, the +\fIcapture_top\fP field contains one more than the number of the highest +numbered captured substring so far. If no substrings have been captured, the +value of \fIcapture_top\fP is one. This is always the case when the DFA +functions are used, because they do not support captured substrings. .P The \fIcapture_last\fP field contains the number of the most recently captured substring. If no substrings have been captured, its value is -1. This is always -the case when \fBpcre_dfa_exec()\fP is used. +the case for the DFA matching functions. .P -The \fIcallout_data\fP field contains a value that is passed to -\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP specifically so that it can be -passed back in callouts. It is passed in the \fIpcre_callout\fP field of the -\fBpcre_extra\fP data structure. If no such data was passed, the value of -\fIcallout_data\fP in a \fBpcre_callout\fP block is NULL. There is a -description of the \fBpcre_extra\fP structure in the +The \fIcallout_data\fP field contains a value that is passed to a matching +function specifically so that it can be passed back in callouts. It is passed +in the \fIcallout_data\fP field of a \fBpcre_extra\fP or \fBpcre16_extra\fP +data structure. If no such data was passed, the value of \fIcallout_data\fP in +a callout block is NULL. There is a description of the \fBpcre_extra\fP +structure in the .\" HREF \fBpcreapi\fP .\" documentation. .P -The \fIpattern_position\fP field is present from version 1 of the -\fIpcre_callout\fP structure. It contains the offset to the next item to be -matched in the pattern string. -.P -The \fInext_item_length\fP field is present from version 1 of the -\fIpcre_callout\fP structure. It contains the length of the next item to be -matched in the pattern string. When the callout immediately precedes an -alternation bar, a closing parenthesis, or the end of the pattern, the length -is zero. When the callout precedes an opening parenthesis, the length is that -of the entire subpattern. +The \fIpattern_position\fP field is present from version 1 of the callout +structure. It contains the offset to the next item to be matched in the pattern +string. +.P +The \fInext_item_length\fP field is present from version 1 of the callout +structure. It contains the length of the next item to be matched in the pattern +string. When the callout immediately precedes an alternation bar, a closing +parenthesis, or the end of the pattern, the length is zero. When the callout +precedes an opening parenthesis, the length is that of the entire subpattern. .P The \fIpattern_position\fP and \fInext_item_length\fP fields are intended to help in distinguishing between different automatic callouts, which all have the same callout number. However, they are set for all callouts. +.P +The \fImark\fP field is present from version 2 of the callout structure. In +callouts from \fBpcre_exec()\fP or \fBpcre16_exec()\fP it contains a pointer to +the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or +(*THEN) item in the match, or NULL if no such items have been passed. Instances +of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In +callouts from the DFA matching functions this field always contains NULL. . . .SH "RETURN VALUES" @@ -161,8 +176,7 @@ matching proceeds as normal. If the value is greater than zero, matching fails at the current point, but the testing of other matching possibilities goes ahead, just as if a lookahead assertion had failed. If the value is less than -zero, the match is abandoned, and \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP -returns the negative value. +zero, the match is abandoned, the matching function returns the negative value. .P Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a standard "no match" failure. @@ -184,6 +198,6 @@ .rs .sp .nf -Last updated: 21 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 08 Janurary 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrecompat.3 pcre3-8.31/doc/pcrecompat.3 --- pcre3-8.12/doc/pcrecompat.3 2010-11-24 17:38:33.000000000 +0000 +++ pcre3-8.31/doc/pcrecompat.3 2012-06-01 17:50:56.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRECOMPAT 3 +.TH PCRECOMPAT 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "DIFFERENCES BETWEEN PCRE AND PERL" @@ -8,22 +8,19 @@ regular expressions. The differences described here are with respect to Perl versions 5.10 and above. .P -1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details of what -it does have are given in the -.\" HTML -.\" -section on UTF-8 support -.\" -in the main +1. PCRE has only a subset of Perl's Unicode support. Details of what it does +have are given in the .\" HREF -\fBpcre\fP +\fBpcreunicode\fP .\" page. .P -2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits -them, but they do not mean what you might think. For example, (?!a){3} does -not assert that the next three characters are not "a". It just asserts that the -next character is not "a" three times. +2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do +not mean what you might think. For example, (?!a){3} does not assert that the +next three characters are not "a". It just asserts that the next character is +not "a" three times (in principle: PCRE optimizes this to run the assertion +just once). Perl allows repeat quantifiers on other assertions such as \eb, but +these do not seem to have any use. .P 3. Capturing subpatterns that occur inside negative lookahead assertions are counted, but their entries in the offsets vector are never set. Perl sets its @@ -37,9 +34,12 @@ represent a binary zero. .P 5. The following Perl escape sequences are not supported: \el, \eu, \eL, -\eU, and \eN. In fact these are implemented by Perl's general string-handling -and are not part of its pattern matching engine. If any of these are -encountered by PCRE, an error is generated. +\eU, and \eN when followed by a character name or Unicode value. (\eN on its +own, matching a non-newline character, is supported.) In fact these are +implemented by Perl's general string-handling and are not part of its pattern +matching engine. If any of these are encountered by PCRE, an error is +generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set, +\eU and \eu are interpreted as JavaScript interprets them. .P 6. The Perl escape sequences \ep, \eP, and \eX are supported only if PCRE is built with Unicode character property support. The properties that can be @@ -50,7 +50,11 @@ the internal representation of Unicode characters, there is no need to implement the somewhat messy concept of surrogates." .P -7. PCRE does support the \eQ...\eE escape for quoting substrings. Characters in +7. PCRE implements a simpler version of \eX than Perl, which changed to make +\eX match what Unicode calls an "extended grapheme cluster". This is more +complicated than an extended Unicode sequence, which is what PCRE matches. +.P +8. PCRE does support the \eQ...\eE escape for quoting substrings. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they cause variable interpolation (but of course PCRE does not have variables). Note the @@ -66,7 +70,7 @@ .sp The \eQ...\eE sequence is recognized both inside and outside character classes. .P -8. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) +9. Fairly obviously, PCRE does not support the (?{code}) and (??{code}) constructions. However, there is support for recursive patterns. This is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout" feature allows an external function to be called during pattern matching. See @@ -76,9 +80,11 @@ .\" documentation for details. .P -9. Subpatterns that are called recursively or as "subroutines" are always -treated as atomic groups in PCRE. This is like Python, but unlike Perl. There -is a discussion of an example that explains this in more detail in the +10. Subpatterns that are called as subroutines (whether or not recursively) are +always treated as atomic groups in PCRE. This is like Python, but unlike Perl. +Captured values that are set outside a subroutine call can be reference from +inside in PCRE, but not in Perl. There is a discussion that explains these +differences in more detail in the .\" HTML .\" section on recursion differences from Perl @@ -89,11 +95,22 @@ .\" page. .P -10. There are some differences that are concerned with the settings of captured +11. If any of the backtracking control verbs are used in an assertion or in a +subpattern that is called as a subroutine (whether or not recursively), their +effect is confined to that subpattern; it does not extend to the surrounding +pattern. This is not always the case in Perl. In particular, if (*THEN) is +present in a group that is called as a subroutine, its action is limited to +that group, even if the group does not contain any | characters. There is one +exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is +encountered in a successful positive assertion \fIis\fP passed back when a +match succeeds (compare capturing parentheses in assertions). Note that such +subpatterns are processed as anchored at the point where they are tested. +.P +12. There are some differences that are concerned with the settings of captured strings when part of a pattern is repeated. For example, matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b". .P -11. PCRE's handling of duplicate subpattern numbers and duplicate subpattern +13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern names is not as general as Perl's. This is a consequence of the fact the PCRE works internally just with numbers, using an external table to translate between numbers and names. In particular, a pattern such as (?|(?A)|(?\fP. When there is more than one pattern -(specified by the use of \fB-e\fP and/or \fB-f\fP), each pattern is applied to -each line in the order in which they are defined, except that all the \fB-e\fP -patterns are tried before the \fB-f\fP patterns. +The amount of memory used for buffering files that are being scanned is +controlled by a parameter that can be set by the \fB--buffer-size\fP option. +The default value for this parameter is specified when \fBpcregrep\fP is built, +with the default default being 20K. A block of memory three times this size is +used (to allow for buffering "before" and "after" lines). An error occurs if a +line overflows the buffer. +.P +Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is +defined in \fB\fP. When there is more than one pattern (specified by +the use of \fB-e\fP and/or \fB-f\fP), each pattern is applied to each line in +the order in which they are defined, except that all the \fB-e\fP patterns are +tried before the \fB-f\fP patterns. .P By default, as soon as one pattern matches (or fails to match when \fB-v\fP is used), no further patterns are considered. However, if \fB--colour\fP (or @@ -76,9 +82,7 @@ If the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variable is set, \fBpcregrep\fP uses the value to set a locale when calling the PCRE library. The \fB--locale\fP option can be used to override this. -.P -\fBzpcregrep\fR is a wrapper script that allows pcregrep to work on -gzip compressed files. +. . .SH "SUPPORT FOR COMPRESSED FILES" .rs @@ -90,16 +94,27 @@ appropriate support is not present, files are treated as plain text. The standard input is always so treated. . +. +.SH "BINARY FILES" +.rs +.sp +By default, a file that contains a binary zero byte within the first 1024 bytes +is identified as a binary file, and is processed specially. (GNU grep also +identifies binary files in this manner.) See the \fB--binary-files\fP option +for a means of changing the way binary files are handled. +. +. .SH OPTIONS .rs .sp The order in which some of the options appear can affect the output. For example, both the \fB-h\fP and \fB-l\fP options affect the printing of file names. Whichever comes later in the command line will be the one that takes -effect. +effect. Numerical values for options may be followed by K or M, to signify +multiplication by 1024 or 1024*1024 respectively. .TP 10 \fB--\fP -This terminate the list of options. It is useful if the next item on the +This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and filenames that start with hyphens. .TP @@ -111,6 +126,10 @@ of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP guarantees to have up to 8K of following text available for context output. .TP +\fB-a\fP, \fB--text\fP +Treat binary files as text. This is equivalent to +\fB--binary-files\fP=\fItext\fP. +.TP \fB-B\fP \fInumber\fP, \fB--before-context=\fP\fInumber\fP Output \fInumber\fP lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen separator is used instead of a @@ -119,6 +138,21 @@ of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP guarantees to have up to 8K of preceding text available for context output. .TP +\fB--binary-files=\fP\fIword\fP +Specify how binary files are to be processed. If the word is "binary" (the +default), pattern matching is performed on binary files, but the only output is +"Binary file matches" when a match succeeds. If the word is "text", +which is equivalent to the \fB-a\fP or \fB--text\fP option, binary files are +processed in the same way as any other file. In this case, when a match +succeeds, the output may be binary garbage, which can have nasty effects if +sent to a terminal. If the word is "without-match", which is equivalent to the +\fB-I\fP option, binary files are not processed at all; they are assumed not to +be of interest. +.TP +\fB--buffer-size=\fP\fInumber\fP +Set the parameter that controls how much memory is used for buffering files +that are being scanned. +.TP \fB-C\fP \fInumber\fP, \fB--context=\fP\fInumber\fP Output \fInumber\fP lines of context both before and after each matching line. This is equivalent to setting both \fB-A\fP and \fB-B\fP to the same value. @@ -214,11 +248,21 @@ filename can be given as "-" to refer to the standard input. When \fB-f\fP is used, patterns specified on the command line using \fB-e\fP may also be present; they are tested before the file's patterns. However, no other pattern -is taken from the command line; all arguments are treated as file names. There -is an overall maximum of 100 patterns. Trailing white space is removed from -each line, and blank lines are ignored. An empty file contains no patterns and -therefore matches nothing. See also the comments about multiple patterns versus -a single pattern with alternatives in the description of \fB-e\fP above. +is taken from the command line; all arguments are treated as the names of paths +to be searched. There is an overall maximum of 100 patterns. Trailing white +space is removed from each line, and blank lines are ignored. An empty file +contains no patterns and therefore matches nothing. See also the comments about +multiple patterns versus a single pattern with alternatives in the description +of \fB-e\fP above. +.TP +\fB--file-list\fP=\fIfilename\fP +Read a list of files to be searched from the given file, one per line. Trailing +white space is removed from each line, and blank lines are ignored. These files +are searched before any others that may be listed on the command line. The +filename can be given as "-" to refer to the standard input. If \fB--file\fP +and \fB--file-list\fP are both specified as "-", patterns are read first. This +is useful only when the standard input is a terminal, from which further lines +(the list of files) can be read after an end-of-file indication. .TP \fB--file-offsets\fP Instead of showing lines or parts of lines that match, show each match as an @@ -245,6 +289,10 @@ Output a help message, giving brief details of the command options and file type support, and then exit. .TP +\fB-I\fP +Treat binary files as never matching. This is equivalent to +\fB--binary-files\fP=\fIwithout-match\fP. +.TP \fB-i\fP, \fB--ignore-case\fP Ignore upper/lower case distinctions during comparisons. .TP @@ -360,7 +408,7 @@ which recognizes any of the preceding three types, and an "any" convention, in which any Unicode line ending sequence is assumed to end a line. The Unicode sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF -(formfeed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and +(form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). .sp When the PCRE library is built, a default line-ending sequence is specified. @@ -378,6 +426,13 @@ output, it precedes the line number. This option is forced if \fB--line-offsets\fP is used. .TP +\fB--no-jit\fP +If the PCRE library is built with support for just-in-time compiling (which +speeds up matching), \fBpcregrep\fP automatically makes use of this, unless it +was explicitly disabled at build time. This option can be used to disable the +use of JIT at run time. It is provided for testing and working round problems. +It should never be needed in normal use. +.TP \fB-o\fP, \fB--only-matching\fP Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and @@ -466,13 +521,14 @@ .rs .sp Many of the short and long forms of \fBpcregrep\fP's options are the same -as in the GNU \fBgrep\fP program (version 2.5.4). Any long option of the form +as in the GNU \fBgrep\fP program. Any long option of the form \fB--xxx-regexp\fP (GNU terminology) is also available as \fB--xxx-regex\fP -(PCRE terminology). However, the \fB--file-offsets\fP, \fB--include-dir\fP, -\fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP, \fB-M\fP, -\fB--multiline\fP, \fB-N\fP, \fB--newline\fP, \fB--recursion-limit\fP, -\fB-u\fP, and \fB--utf-8\fP options are specific to \fBpcregrep\fP, as is the -use of the \fB--only-matching\fP option with a capturing parentheses number. +(PCRE terminology). However, the \fB--file-list\fP, \fB--file-offsets\fP, +\fB--include-dir\fP, \fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP, +\fB-M\fP, \fB--multiline\fP, \fB-N\fP, \fB--newline\fP, +\fB--recursion-limit\fP, \fB-u\fP, and \fB--utf-8\fP options are specific to +\fBpcregrep\fP, as is the use of the \fB--only-matching\fP option with a +capturing parentheses number. .P Although most of the common options work the same way, a few are different in \fBpcregrep\fP. For example, the \fB--include\fP option's argument is a glob @@ -534,10 +590,10 @@ .rs .sp Exit status is 0 if any matches were found, 1 if no matches were found, and 2 -for syntax errors and non-existent or inaccessible files (even if matches were -found in other files) or too many matching errors. Using the \fB-s\fP option to -suppress error messages about inaccessble files does not affect the return -code. +for syntax errors, overlong lines, non-existent or inaccessible files (even if +matches were found in other files) or too many matching errors. Using the +\fB-s\fP option to suppress error messages about inaccessible files does not +affect the return code. . . .SH "SEE ALSO" @@ -560,6 +616,6 @@ .rs .sp .nf -Last updated: 14 January 2011 -Copyright (c) 1997-2011 University of Cambridge. +Last updated: 04 March 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcregrep.txt pcre3-8.31/doc/pcregrep.txt --- pcre3-8.12/doc/pcregrep.txt 2011-01-15 17:27:45.000000000 +0000 +++ pcre3-8.31/doc/pcregrep.txt 2012-07-06 09:55:27.000000000 +0000 @@ -49,19 +49,26 @@ What defines a line boundary is controlled by the -N (--newline) option. - Patterns are limited to 8K or BUFSIZ characters, whichever is the - greater. BUFSIZ is defined in . When there is more than one - pattern (specified by the use of -e and/or -f), each pattern is applied - to each line in the order in which they are defined, except that all - the -e patterns are tried before the -f patterns. + The amount of memory used for buffering files that are being scanned is + controlled by a parameter that can be set by the --buffer-size option. + The default value for this parameter is specified when pcregrep is + built, with the default default being 20K. A block of memory three + times this size is used (to allow for buffering "before" and "after" + lines). An error occurs if a line overflows the buffer. + + Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. + BUFSIZ is defined in . When there is more than one pattern + (specified by the use of -e and/or -f), each pattern is applied to each + line in the order in which they are defined, except that all the -e + patterns are tried before the -f patterns. - By default, as soon as one pattern matches (or fails to match when -v - is used), no further patterns are considered. However, if --colour (or + By default, as soon as one pattern matches (or fails to match when -v + is used), no further patterns are considered. However, if --colour (or --color) is used to colour the matching substrings, or if --only-match- - ing, --file-offsets, or --line-offsets is used to output only the part - of the line that matched (either shown literally, or as an offset), - scanning resumes immediately following the match, so that further - matches on the same line can be found. If there are multiple patterns, + ing, --file-offsets, or --line-offsets is used to output only the part + of the line that matched (either shown literally, or as an offset), + scanning resumes immediately following the match, so that further + matches on the same line can be found. If there are multiple patterns, they are all tried on the remainder of the line, but patterns that fol- low the one that matched are not tried on the earlier part of the line. @@ -69,36 +76,46 @@ in which multiple patterns are specified can affect the output when one of the above options is used. - Patterns that can match an empty string are accepted, but empty string + Patterns that can match an empty string are accepted, but empty string matches are never recognized. An example is the pattern - "(super)?(man)?", in which all components are optional. This pattern - finds all occurrences of both "super" and "man"; the output differs - from matching with "super|man" when only the matching substrings are + "(super)?(man)?", in which all components are optional. This pattern + finds all occurrences of both "super" and "man"; the output differs + from matching with "super|man" when only the matching substrings are being shown. - If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses - the value to set a locale when calling the PCRE library. The --locale + If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses + the value to set a locale when calling the PCRE library. The --locale option can be used to override this. SUPPORT FOR COMPRESSED FILES - It is possible to compile pcregrep so that it uses libz or libbz2 to - read files whose names end in .gz or .bz2, respectively. You can find + It is possible to compile pcregrep so that it uses libz or libbz2 to + read files whose names end in .gz or .bz2, respectively. You can find out whether your binary has support for one or both of these file types by running it with the --help option. If the appropriate support is not - present, files are treated as plain text. The standard input is always + present, files are treated as plain text. The standard input is always so treated. +BINARY FILES + + By default, a file that contains a binary zero byte within the first + 1024 bytes is identified as a binary file, and is processed specially. + (GNU grep also identifies binary files in this manner.) See the + --binary-files option for a means of changing the way binary files are + handled. + + OPTIONS - The order in which some of the options appear can affect the output. - For example, both the -h and -l options affect the printing of file - names. Whichever comes later in the command line will be the one that - takes effect. + The order in which some of the options appear can affect the output. + For example, both the -h and -l options affect the printing of file + names. Whichever comes later in the command line will be the one that + takes effect. Numerical values for options may be followed by K or M, + to signify multiplication by 1024 or 1024*1024 respectively. - -- This terminate the list of options. It is useful if the next + -- This terminates the list of options. It is useful if the next item on the command line starts with a hyphen but is not an option. This allows for the processing of patterns and file- names that start with hyphens. @@ -113,16 +130,37 @@ pcregrep guarantees to have up to 8K of following text avail- able for context output. + -a, --text + Treat binary files as text. This is equivalent to --binary- + files=text. + -B number, --before-context=number - Output number lines of context before each matching line. If + Output number lines of context before each matching line. If filenames and/or line numbers are being output, a hyphen sep- - arator is used instead of a colon for the context lines. A - line containing "--" is output between each group of lines, - unless they are in fact contiguous in the input file. The - value of number is expected to be relatively small. However, + arator is used instead of a colon for the context lines. A + line containing "--" is output between each group of lines, + unless they are in fact contiguous in the input file. The + value of number is expected to be relatively small. However, pcregrep guarantees to have up to 8K of preceding text avail- able for context output. + --binary-files=word + Specify how binary files are to be processed. If the word is + "binary" (the default), pattern matching is performed on + binary files, but the only output is "Binary file + matches" when a match succeeds. If the word is "text", which + is equivalent to the -a or --text option, binary files are + processed in the same way as any other file. In this case, + when a match succeeds, the output may be binary garbage, + which can have nasty effects if sent to a terminal. If the + word is "without-match", which is equivalent to the -I + option, binary files are not processed at all; they are + assumed not to be of interest. + + --buffer-size=number + Set the parameter that controls how much memory is used for + buffering files that are being scanned. + -C number, --context=number Output number lines of context both before and after each matching line. This is equivalent to setting both -A and -B @@ -236,12 +274,23 @@ specified on the command line using -e may also be present; they are tested before the file's patterns. However, no other pattern is taken from the command line; all arguments are - treated as file names. There is an overall maximum of 100 - patterns. Trailing white space is removed from each line, and - blank lines are ignored. An empty file contains no patterns - and therefore matches nothing. See also the comments about - multiple patterns versus a single pattern with alternatives - in the description of -e above. + treated as the names of paths to be searched. There is an + overall maximum of 100 patterns. Trailing white space is + removed from each line, and blank lines are ignored. An empty + file contains no patterns and therefore matches nothing. See + also the comments about multiple patterns versus a single + pattern with alternatives in the description of -e above. + + --file-list=filename + Read a list of files to be searched from the given file, one + per line. Trailing white space is removed from each line, and + blank lines are ignored. These files are searched before any + others that may be listed on the command line. The filename + can be given as "-" to refer to the standard input. If --file + and --file-list are both specified as "-", patterns are read + first. This is useful only when the standard input is a ter- + minal, from which further lines (the list of files) can be + read after an end-of-file indication. --file-offsets Instead of showing lines or parts of lines that match, show @@ -270,6 +319,9 @@ --help Output a help message, giving brief details of the command options and file type support, and then exit. + -I Treat binary files as never matching. This is equivalent to + --binary-files=without-match. + -i, --ignore-case Ignore upper/lower case distinctions during comparisons. @@ -277,38 +329,38 @@ When pcregrep is searching the files in a directory as a con- sequence of the -r (recursive search) option, only those reg- ular files whose names match the pattern are included. Subdi- - rectories are always included and searched recursively, sub- + rectories are always included and searched recursively, sub- ject to the --include-dir and --exclude-dir options. The pat- tern is a PCRE regular expression, and is matched against the - final component of the file name (not the entire path). If a + final component of the file name (not the entire path). If a file name matches both --include and --exclude, it is excluded. There is no short form for this option. --include-dir=pattern - When pcregrep is searching the contents of a directory as a - consequence of the -r (recursive search) option, only those - subdirectories whose names match the pattern are included. - (Note that the --include option does not affect subdirecto- - ries.) The pattern is a PCRE regular expression, and is - matched against the final component of the name (not the - entire path). If a subdirectory name matches both --include- + When pcregrep is searching the contents of a directory as a + consequence of the -r (recursive search) option, only those + subdirectories whose names match the pattern are included. + (Note that the --include option does not affect subdirecto- + ries.) The pattern is a PCRE regular expression, and is + matched against the final component of the name (not the + entire path). If a subdirectory name matches both --include- dir and --exclude-dir, it is excluded. There is no short form for this option. -L, --files-without-match - Instead of outputting lines from the files, just output the - names of the files that do not contain any lines that would - have been output. Each file name is output once, on a sepa- + Instead of outputting lines from the files, just output the + names of the files that do not contain any lines that would + have been output. Each file name is output once, on a sepa- rate line. -l, --files-with-matches - Instead of outputting lines from the files, just output the + Instead of outputting lines from the files, just output the names of the files containing lines that would have been out- - put. Each file name is output once, on a separate line. - Searching normally stops as soon as a matching line is found - in a file. However, if the -c (count) option is also used, - matching continues in order to obtain the correct count, and - those files that have at least one match are listed along + put. Each file name is output once, on a separate line. + Searching normally stops as soon as a matching line is found + in a file. However, if the -c (count) option is also used, + matching continues in order to obtain the correct count, and + those files that have at least one match are listed along with their counts. Using this option with -c is a way of sup- pressing the listing of files with no matches. @@ -318,116 +370,123 @@ input)" is used. There is no short form for this option. --line-buffered - When this option is given, input is read and processed line - by line, and the output is flushed after each write. By - default, input is read in large chunks, unless pcregrep can - determine that it is reading from a terminal (which is cur- - rently possible only in Unix environments). Output to termi- - nal is normally automatically flushed by the operating sys- - tem. This option can be useful when the input or output is - attached to a pipe and you do not want pcregrep to buffer up - large amounts of data. However, its use will affect perfor- + When this option is given, input is read and processed line + by line, and the output is flushed after each write. By + default, input is read in large chunks, unless pcregrep can + determine that it is reading from a terminal (which is cur- + rently possible only in Unix environments). Output to termi- + nal is normally automatically flushed by the operating sys- + tem. This option can be useful when the input or output is + attached to a pipe and you do not want pcregrep to buffer up + large amounts of data. However, its use will affect perfor- mance, and the -M (multiline) option ceases to work. --line-offsets - Instead of showing lines or parts of lines that match, show + Instead of showing lines or parts of lines that match, show each match as a line number, the offset from the start of the - line, and a length. The line number is terminated by a colon - (as usual; see the -n option), and the offset and length are - separated by a comma. In this mode, no context is shown. - That is, the -A, -B, and -C options are ignored. If there is - more than one match in a line, each of them is shown sepa- + line, and a length. The line number is terminated by a colon + (as usual; see the -n option), and the offset and length are + separated by a comma. In this mode, no context is shown. + That is, the -A, -B, and -C options are ignored. If there is + more than one match in a line, each of them is shown sepa- rately. This option is mutually exclusive with --file-offsets and --only-matching. --locale=locale-name - This option specifies a locale to be used for pattern match- - ing. It overrides the value in the LC_ALL or LC_CTYPE envi- - ronment variables. If no locale is specified, the PCRE - library's default (usually the "C" locale) is used. There is + This option specifies a locale to be used for pattern match- + ing. It overrides the value in the LC_ALL or LC_CTYPE envi- + ronment variables. If no locale is specified, the PCRE + library's default (usually the "C" locale) is used. There is no short form for this option. --match-limit=number - Processing some regular expression patterns can require a - very large amount of memory, leading in some cases to a pro- - gram crash if not enough is available. Other patterns may - take a very long time to search for all possible matching - strings. The pcre_exec() function that is called by pcregrep - to do the matching has two parameters that can limit the + Processing some regular expression patterns can require a + very large amount of memory, leading in some cases to a pro- + gram crash if not enough is available. Other patterns may + take a very long time to search for all possible matching + strings. The pcre_exec() function that is called by pcregrep + to do the matching has two parameters that can limit the resources that it uses. - The --match-limit option provides a means of limiting + The --match-limit option provides a means of limiting resource usage when processing patterns that are not going to match, but which have a very large number of possibilities in - their search trees. The classic example is a pattern that - uses nested unlimited repeats. Internally, PCRE uses a func- - tion called match() which it calls repeatedly (sometimes - recursively). The limit set by --match-limit is imposed on - the number of times this function is called during a match, - which has the effect of limiting the amount of backtracking + their search trees. The classic example is a pattern that + uses nested unlimited repeats. Internally, PCRE uses a func- + tion called match() which it calls repeatedly (sometimes + recursively). The limit set by --match-limit is imposed on + the number of times this function is called during a match, + which has the effect of limiting the amount of backtracking that can take place. The --recursion-limit option is similar to --match-limit, but instead of limiting the total number of times that match() is called, it limits the depth of recursive calls, which in turn - limits the amount of memory that can be used. The recursion - depth is a smaller number than the total number of calls, + limits the amount of memory that can be used. The recursion + depth is a smaller number than the total number of calls, because not all calls to match() are recursive. This limit is of use only if it is set smaller than --match-limit. - There are no short forms for these options. The default set- - tings are specified when the PCRE library is compiled, with + There are no short forms for these options. The default set- + tings are specified when the PCRE library is compiled, with the default default being 10 million. -M, --multiline - Allow patterns to match more than one line. When this option + Allow patterns to match more than one line. When this option is given, patterns may usefully contain literal newline char- - acters and internal occurrences of ^ and $ characters. The - output for a successful match may consist of more than one - line, the last of which is the one in which the match ended. + acters and internal occurrences of ^ and $ characters. The + output for a successful match may consist of more than one + line, the last of which is the one in which the match ended. If the matched string ends with a newline sequence the output ends at the end of that line. - When this option is set, the PCRE library is called in "mul- - tiline" mode. There is a limit to the number of lines that - can be matched, imposed by the way that pcregrep buffers the - input file as it scans it. However, pcregrep ensures that at + When this option is set, the PCRE library is called in "mul- + tiline" mode. There is a limit to the number of lines that + can be matched, imposed by the way that pcregrep buffers the + input file as it scans it. However, pcregrep ensures that at least 8K characters or the rest of the document (whichever is - the shorter) are available for forward matching, and simi- + the shorter) are available for forward matching, and simi- larly the previous 8K characters (or all the previous charac- - ters, if fewer than 8K) are guaranteed to be available for - lookbehind assertions. This option does not work when input + ters, if fewer than 8K) are guaranteed to be available for + lookbehind assertions. This option does not work when input is read line by line (see --line-buffered.) -N newline-type, --newline=newline-type - The PCRE library supports five different conventions for - indicating the ends of lines. They are the single-character - sequences CR (carriage return) and LF (linefeed), the two- - character sequence CRLF, an "anycrlf" convention, which rec- - ognizes any of the preceding three types, and an "any" con- + The PCRE library supports five different conventions for + indicating the ends of lines. They are the single-character + sequences CR (carriage return) and LF (linefeed), the two- + character sequence CRLF, an "anycrlf" convention, which rec- + ognizes any of the preceding three types, and an "any" con- vention, in which any Unicode line ending sequence is assumed - to end a line. The Unicode sequences are the three just men- - tioned, plus VT (vertical tab, U+000B), FF (formfeed, - U+000C), NEL (next line, U+0085), LS (line separator, + to end a line. The Unicode sequences are the three just men- + tioned, plus VT (vertical tab, U+000B), FF (form feed, + U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). When the PCRE library is built, a default line-ending - sequence is specified. This is normally the standard + sequence is specified. This is normally the standard sequence for the operating system. Unless otherwise specified - by this option, pcregrep uses the library's default. The + by this option, pcregrep uses the library's default. The possible values for this option are CR, LF, CRLF, ANYCRLF, or - ANY. This makes it possible to use pcregrep on files that - have come from other environments without having to modify - their line endings. If the data that is being scanned does - not agree with the convention set by this option, pcregrep + ANY. This makes it possible to use pcregrep on files that + have come from other environments without having to modify + their line endings. If the data that is being scanned does + not agree with the convention set by this option, pcregrep may behave in strange ways. -n, --line-number Precede each output line by its line number in the file, fol- - lowed by a colon for matching lines or a hyphen for context - lines. If the filename is also being output, it precedes the + lowed by a colon for matching lines or a hyphen for context + lines. If the filename is also being output, it precedes the line number. This option is forced if --line-offsets is used. + --no-jit If the PCRE library is built with support for just-in-time + compiling (which speeds up matching), pcregrep automatically + makes use of this, unless it was explicitly disabled at build + time. This option can be used to disable the use of JIT at + run time. It is provided for testing and working round prob- + lems. It should never be needed in normal use. + -o, --only-matching Show only the part of the line that matched a pattern instead of the whole line. In this mode, no context is shown. That @@ -521,12 +580,12 @@ OPTIONS COMPATIBILITY Many of the short and long forms of pcregrep's options are the same as - in the GNU grep program (version 2.5.4). Any long option of the form - --xxx-regexp (GNU terminology) is also available as --xxx-regex (PCRE - terminology). However, the --file-offsets, --include-dir, --line-off- - sets, --locale, --match-limit, -M, --multiline, -N, --newline, --recur- - sion-limit, -u, and --utf-8 options are specific to pcregrep, as is the - use of the --only-matching option with a capturing parentheses number. + in the GNU grep program. Any long option of the form --xxx-regexp (GNU + terminology) is also available as --xxx-regex (PCRE terminology). How- + ever, the --file-list, --file-offsets, --include-dir, --line-offsets, + --locale, --match-limit, -M, --multiline, -N, --newline, --recursion- + limit, -u, and --utf-8 options are specific to pcregrep, as is the use + of the --only-matching option with a capturing parentheses number. Although most of the common options work the same way, a few are dif- ferent in pcregrep. For example, the --include option's argument is a @@ -587,10 +646,10 @@ DIAGNOSTICS Exit status is 0 if any matches were found, 1 if no matches were found, - and 2 for syntax errors and non-existent or inacessible files (even if - matches were found in other files) or too many matching errors. Using - the -s option to suppress error messages about inaccessble files does - not affect the return code. + and 2 for syntax errors, overlong lines, non-existent or inaccessible + files (even if matches were found in other files) or too many matching + errors. Using the -s option to suppress error messages about inaccessi- + ble files does not affect the return code. SEE ALSO @@ -607,5 +666,5 @@ REVISION - Last updated: 14 January 2011 - Copyright (c) 1997-2011 University of Cambridge. + Last updated: 04 March 2012 + Copyright (c) 1997-2012 University of Cambridge. diff -Nru pcre3-8.12/doc/pcrejit.3 pcre3-8.31/doc/pcrejit.3 --- pcre3-8.12/doc/pcrejit.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcrejit.3 2012-06-02 10:55:17.000000000 +0000 @@ -0,0 +1,403 @@ +.TH PCREJIT 3 "04 May 2012" "PCRE 8.31" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "PCRE JUST-IN-TIME COMPILER SUPPORT" +.rs +.sp +Just-in-time compiling is a heavyweight optimization that can greatly speed up +pattern matching. However, it comes at the cost of extra processing before the +match is performed. Therefore, it is of most benefit when the same pattern is +going to be matched many times. This does not necessarily mean many calls of a +matching function; if the pattern is not anchored, matching attempts may take +place many times at various positions in the subject, even for a single call. +Therefore, if the subject string is very long, it may still pay to use JIT for +one-off matches. +.P +JIT support applies only to the traditional Perl-compatible matching function. +It does not apply when the DFA matching function is being used. The code for +this support was written by Zoltan Herczeg. +. +. +.SH "8-BIT and 16-BIT SUPPORT" +.rs +.sp +JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep +this documentation simple, only the 8-bit interface is described in what +follows. If you are using the 16-bit library, substitute the 16-bit functions +and 16-bit structures (for example, \fIpcre16_jit_stack\fP instead of +\fIpcre_jit_stack\fP). +. +. +.SH "AVAILABILITY OF JIT SUPPORT" +.rs +.sp +JIT support is an optional feature of PCRE. The "configure" option --enable-jit +(or equivalent CMake option) must be set when PCRE is built if you want to use +JIT. The support is limited to the following hardware platforms: +.sp + ARM v5, v7, and Thumb2 + Intel x86 32-bit and 64-bit + MIPS 32-bit + Power PC 32-bit and 64-bit +.sp +If --enable-jit is set on an unsupported platform, compilation fails. +.P +A program that is linked with PCRE 8.20 or later can tell if JIT support is +available by calling \fBpcre_config()\fP with the PCRE_CONFIG_JIT option. The +result is 1 when JIT is available, and 0 otherwise. However, a simple program +does not need to check this in order to use JIT. The API is implemented in a +way that falls back to the interpretive code if JIT is not available. +.P +If your program may sometimes be linked with versions of PCRE that are older +than 8.20, but you want to use JIT when it is available, you can test +the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such +as PCRE_CONFIG_JIT, for compile-time control of your code. +. +. +.SH "SIMPLE USE OF JIT" +.rs +.sp +You have to do two things to make use of the JIT support in the simplest way: +.sp + (1) Call \fBpcre_study()\fP with the PCRE_STUDY_JIT_COMPILE option for + each compiled pattern, and pass the resulting \fBpcre_extra\fP block to + \fBpcre_exec()\fP. +.sp + (2) Use \fBpcre_free_study()\fP to free the \fBpcre_extra\fP block when it is + no longer needed, instead of just freeing it yourself. This + ensures that any JIT data is also freed. +.sp +For a program that may be linked with pre-8.20 versions of PCRE, you can insert +.sp + #ifndef PCRE_STUDY_JIT_COMPILE + #define PCRE_STUDY_JIT_COMPILE 0 + #endif +.sp +so that no option is passed to \fBpcre_study()\fP, and then use something like +this to free the study data: +.sp + #ifdef PCRE_CONFIG_JIT + pcre_free_study(study_ptr); + #else + pcre_free(study_ptr); + #endif +.sp +PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete +matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or +PCRE_PARTIAL_SOFT options of \fBpcre_exec()\fP, you should set one or both of +the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE +when you call \fBpcre_study()\fP: +.sp + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE +.sp +The JIT compiler generates different optimized code for each of the three +modes (normal, soft partial, hard partial). When \fBpcre_exec()\fP is called, +the appropriate code is run if it is available. Otherwise, the pattern is +matched using interpretive code. +.P +In some circumstances you may need to call additional functions. These are +described in the section entitled +.\" HTML +.\" +"Controlling the JIT stack" +.\" +below. +.P +If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and +no JIT data is created. Otherwise, the compiled pattern is passed to the JIT +compiler, which turns it into machine code that executes much faster than the +normal interpretive code. When \fBpcre_exec()\fP is passed a \fBpcre_extra\fP +block containing a pointer to JIT code of the appropriate mode (normal or +hard/soft partial), it obeys that code instead of running the interpreter. The +result is identical, but the compiled JIT code runs much faster. +.P +There are some \fBpcre_exec()\fP options that are not supported for JIT +execution. There are also some pattern items that JIT cannot handle. Details +are given below. In both cases, execution automatically falls back to the +interpretive code. If you want to know whether JIT was actually used for a +particular match, you should arrange for a JIT callback function to be set up +as described in the section entitled +.\" HTML +.\" +"Controlling the JIT stack" +.\" +below, even if you do not need to supply a non-default JIT stack. Such a +callback function is called whenever JIT code is about to be obeyed. If the +execution options are not right for JIT execution, the callback function is not +obeyed. +.P +If the JIT compiler finds an unsupported item, no JIT data is generated. You +can find out if JIT execution is available after studying a pattern by calling +\fBpcre_fullinfo()\fP with the PCRE_INFO_JIT option. A result of 1 means that +JIT compilation was successful. A result of 0 means that JIT support is not +available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or +the JIT compiler was not able to handle the pattern. +.P +Once a pattern has been studied, with or without JIT, it can be used as many +times as you like for matching different subject strings. +. +. +.SH "UNSUPPORTED OPTIONS AND PATTERN ITEMS" +.rs +.sp +The only \fBpcre_exec()\fP options that are supported for JIT execution are +PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, +PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. +.P +The unsupported pattern items are: +.sp + \eC match a single byte; not supported in UTF-8 mode + (?Cn) callouts + (*PRUNE) ) + (*SKIP) ) backtracking control verbs + (*THEN) ) +.sp +Support for some of these may be added in future. +. +. +.SH "RETURN VALUES FROM JIT EXECUTION" +.rs +.sp +When a pattern is matched using JIT execution, the return values are the same +as those given by the interpretive \fBpcre_exec()\fP code, with the addition of +one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used +for the JIT stack was insufficient. See +.\" HTML +.\" +"Controlling the JIT stack" +.\" +below for a discussion of JIT stack usage. For compatibility with the +interpretive \fBpcre_exec()\fP code, no more than two-thirds of the +\fIovector\fP argument is used for passing back captured substrings. +.P +The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a +very large pattern tree goes on for too long, as it is in the same circumstance +when JIT is not used, but the details of exactly what is counted are not the +same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT +execution. +. +. +.SH "SAVING AND RESTORING COMPILED PATTERNS" +.rs +.sp +The code that is generated by the JIT compiler is architecture-specific, and is +also position dependent. For those reasons it cannot be saved (in a file or +database) and restored later like the bytecode and other data of a compiled +pattern. Saving and restoring compiled patterns is not something many people +do. More detail about this facility is given in the +.\" HREF +\fBpcreprecompile\fP +.\" +documentation. It should be possible to run \fBpcre_study()\fP on a saved and +restored pattern, and thereby recreate the JIT data, but because JIT +compilation uses significant resources, it is probably not worth doing this; +you might as well recompile the original pattern. +. +. +.\" HTML +.SH "CONTROLLING THE JIT STACK" +.rs +.sp +When the compiled JIT code runs, it needs a block of memory to use as a stack. +By default, it uses 32K on the machine stack. However, some large or +complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT +is given when there is not enough stack. Three functions are provided for +managing blocks of memory for use as JIT stacks. There is further discussion +about the use of JIT stacks in the section entitled +.\" HTML +.\" +"JIT stack FAQ" +.\" +below. +.P +The \fBpcre_jit_stack_alloc()\fP function creates a JIT stack. Its arguments +are a starting size and a maximum size, and it returns a pointer to an opaque +structure of type \fBpcre_jit_stack\fP, or NULL if there is an error. The +\fBpcre_jit_stack_free()\fP function can be used to free a stack that is no +longer needed. (For the technically minded: the address space is allocated by +mmap or VirtualAlloc.) +.P +JIT uses far less memory for recursion than the interpretive code, +and a maximum stack size of 512K to 1M should be more than enough for any +pattern. +.P +The \fBpcre_assign_jit_stack()\fP function specifies which stack JIT code +should use. Its arguments are as follows: +.sp + pcre_extra *extra + pcre_jit_callback callback + void *data +.sp +The \fIextra\fP argument must be the result of studying a pattern with +PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other +two options: +.sp + (1) If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block + on the machine stack is used. +.sp + (2) If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must be + a valid JIT stack, the result of calling \fBpcre_jit_stack_alloc()\fP. +.sp + (3) If \fIcallback\fP is not NULL, it must point to a function that is + called with \fIdata\fP as an argument at the start of matching, in + order to set up a JIT stack. If the return from the callback + function is NULL, the internal 32K stack is used; otherwise the + return value must be a valid JIT stack, the result of calling + \fBpcre_jit_stack_alloc()\fP. +.sp +A callback function is obeyed whenever JIT code is about to be run; it is not +obeyed when \fBpcre_exec()\fP is called with options that are incompatible for +JIT execution. A callback function can therefore be used to determine whether a +match operation was executed by JIT or by the interpreter. +.P +You may safely use the same JIT stack for more than one pattern (either by +assigning directly or by callback), as long as the patterns are all matched +sequentially in the same thread. In a multithread application, if you do not +specify a JIT stack, or if you assign or pass back NULL from a callback, that +is thread-safe, because each thread has its own machine stack. However, if you +assign or pass back a non-NULL JIT stack, this must be a different stack for +each thread so that the application is thread-safe. +.P +Strictly speaking, even more is allowed. You can assign the same non-NULL stack +to any number of patterns as long as they are not used for matching by multiple +threads at the same time. For example, you can assign the same stack to all +compiled patterns, and use a global mutex in the callback to wait until the +stack is available for use. However, this is an inefficient solution, and not +recommended. +.P +This is a suggestion for how a multithreaded program that needs to set up +non-default JIT stacks might operate: +.sp + During thread initalization + thread_local_var = pcre_jit_stack_alloc(...) +.sp + During thread exit + pcre_jit_stack_free(thread_local_var) +.sp + Use a one-line callback function + return thread_local_var +.sp +All the functions described in this section do nothing if JIT is not available, +and \fBpcre_assign_jit_stack()\fP does nothing unless the \fBextra\fP argument +is non-NULL and points to a \fBpcre_extra\fP block that is the result of a +successful study with PCRE_STUDY_JIT_COMPILE etc. +. +. +.\" HTML +.SH "JIT STACK FAQ" +.rs +.sp +(1) Why do we need JIT stacks? +.sp +PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where +the local data of the current node is pushed before checking its child nodes. +Allocating real machine stack on some platforms is difficult. For example, the +stack chain needs to be updated every time if we extend the stack on PowerPC. +Although it is possible, its updating time overhead decreases performance. So +we do the recursion in memory. +.P +(2) Why don't we simply allocate blocks of memory with \fBmalloc()\fP? +.sp +Modern operating systems have a nice feature: they can reserve an address space +instead of allocating memory. We can safely allocate memory pages inside this +address space, so the stack could grow without moving memory data (this is +important because of pointers). Thus we can allocate 1M address space, and use +only a single memory page (usually 4K) if that is enough. However, we can still +grow up to 1M anytime if needed. +.P +(3) Who "owns" a JIT stack? +.sp +The owner of the stack is the user program, not the JIT studied pattern or +anything else. The user program must ensure that if a stack is used by +\fBpcre_exec()\fP, (that is, it is assigned to the pattern currently running), +that stack must not be used by any other threads (to avoid overwriting the same +memory area). The best practice for multithreaded programs is to allocate a +stack for each thread, and return this stack through the JIT callback function. +.P +(4) When should a JIT stack be freed? +.sp +You can free a JIT stack at any time, as long as it will not be used by +\fBpcre_exec()\fP again. When you assign the stack to a pattern, only a pointer +is set. There is no reference counting or any other magic. You can free the +patterns and stacks in any order, anytime. Just \fIdo not\fP call +\fBpcre_exec()\fP with a pattern pointing to an already freed stack, as that +will cause SEGFAULT. (Also, do not free a stack currently used by +\fBpcre_exec()\fP in another thread). You can also replace the stack for a +pattern at any time. You can even free the previous stack before assigning a +replacement. +.P +(5) Should I allocate/free a stack every time before/after calling +\fBpcre_exec()\fP? +.sp +No, because this is too costly in terms of resources. However, you could +implement some clever idea which release the stack if it is not used in let's +say two minutes. The JIT callback can help to achive this without keeping a +list of the currently JIT studied patterns. +.P +(6) OK, the stack is for long term memory allocation. But what happens if a +pattern causes stack overflow with a stack of 1M? Is that 1M kept until the +stack is freed? +.sp +Especially on embedded sytems, it might be a good idea to release memory +sometimes without freeing the stack. There is no API for this at the moment. +Probably a function call which returns with the currently allocated memory for +any stack and another which allows releasing memory (shrinking the stack) would +be a good idea if someone needs this. +.P +(7) This is too much of a headache. Isn't there any better solution for JIT +stack handling? +.sp +No, thanks to Windows. If POSIX threads were used everywhere, we could throw +out this complicated API. +. +. +.SH "EXAMPLE CODE" +.rs +.sp +This is a single-threaded example that specifies a JIT stack without using a +callback. +.sp + int rc; + int ovector[30]; + pcre *re; + pcre_extra *extra; + pcre_jit_stack *jit_stack; +.sp + re = pcre_compile(pattern, 0, &error, &erroffset, NULL); + /* Check for errors */ + extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); + jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); + /* Check for error (NULL) */ + pcre_assign_jit_stack(extra, NULL, jit_stack); + rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30); + /* Check results */ + pcre_free(re); + pcre_free_study(extra); + pcre_jit_stack_free(jit_stack); +.sp +. +. +.SH "SEE ALSO" +.rs +.sp +\fBpcreapi\fP(3) +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel (FAQ by Zoltan Herczeg) +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 04 May 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff -Nru pcre3-8.12/doc/pcrelimits.3 pcre3-8.31/doc/pcrelimits.3 --- pcre3-8.12/doc/pcrelimits.3 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/doc/pcrelimits.3 2012-05-04 13:02:38.000000000 +0000 @@ -0,0 +1,66 @@ +.TH PCRELIMITS 3 "04 May 2012" "PCRE 8.30" +.SH NAME +PCRE - Perl-compatible regular expressions +.SH "SIZE AND OTHER LIMITATIONS" +.rs +.sp +There are some size limitations in PCRE but it is hoped that they will never in +practice be relevant. +.P +The maximum length of a compiled pattern is approximately 64K data units (bytes +for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled +with the default internal linkage size of 2 bytes. If you want to process +regular expressions that are truly enormous, you can compile PCRE with an +internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded +up to 4). See the \fBREADME\fP file in the source distribution and the +.\" HREF +\fBpcrebuild\fP +.\" +documentation for details. In these cases the limit is substantially larger. +However, the speed of execution is slower. +.P +All values in repeating quantifiers must be less than 65536. +.P +There is no limit to the number of parenthesized subpatterns, but there can be +no more than 65535 capturing subpatterns. +.P +There is a limit to the number of forward references to subsequent subpatterns +of around 200,000. Repeated forward references with fixed upper limits, for +example, (?2){0,100} when subpattern number 2 is to the right, are included in +the count. There is no limit to the number of backward references. +.P +The maximum length of name for a named subpattern is 32 characters, and the +maximum number of named subpatterns is 10000. +.P +The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb +is 255 for the 8-bit library and 65535 for the 16-bit library. +.P +The maximum length of a subject string is the largest positive number that an +integer variable can hold. However, when using the traditional matching +function, PCRE uses recursion to handle subpatterns and indefinite repetition. +This means that the available stack space may limit the size of a subject +string that can be processed by certain patterns. For a discussion of stack +issues, see the +.\" HREF +\fBpcrestack\fP +.\" +documentation. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 04 May 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff -Nru pcre3-8.12/doc/pcrematching.3 pcre3-8.31/doc/pcrematching.3 --- pcre3-8.12/doc/pcrematching.3 2010-11-24 17:38:33.000000000 +0000 +++ pcre3-8.31/doc/pcrematching.3 2012-03-31 18:02:00.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREMATCHING 3 +.TH PCREMATCHING 3 "08 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE MATCHING ALGORITHMS" @@ -6,14 +6,19 @@ .sp This document describes the two different algorithms that are available in PCRE for matching a compiled regular expression against a given subject string. The -"standard" algorithm is the one provided by the \fBpcre_exec()\fP function. -This works in the same was as Perl's matching function, and provides a -Perl-compatible matching operation. -.P -An alternative algorithm is provided by the \fBpcre_dfa_exec()\fP function; -this operates in a different way, and is not Perl-compatible. It has advantages -and disadvantages compared with the standard algorithm, and these are described -below. +"standard" algorithm is the one provided by the \fBpcre_exec()\fP and +\fBpcre16_exec()\fP functions. These work in the same was as Perl's matching +function, and provide a Perl-compatible matching operation. The just-in-time +(JIT) optimization that is described in the +.\" HREF +\fBpcrejit\fP +.\" +documentation is compatible with these functions. +.P +An alternative algorithm is provided by the \fBpcre_dfa_exec()\fP and +\fBpcre16_dfa_exec()\fP functions; they operate in a different way, and are not +Perl-compatible. This alternative has advantages and disadvantages compared +with the standard algorithm, and these are described below. .P When there is only one possible way in which a given subject string can match a pattern, the two algorithms give the same answer. A difference arises, however, @@ -28,6 +33,7 @@ there are three possible answers. The standard algorithm finds only one of them, whereas the alternative algorithm finds all three. . +. .SH "REGULAR EXPRESSIONS AS TREES" .rs .sp @@ -38,6 +44,7 @@ There are two ways to search a tree: depth-first and breadth-first, and these correspond to the two matching algorithms provided by PCRE. . +. .SH "THE STANDARD MATCHING ALGORITHM" .rs .sp @@ -63,6 +70,7 @@ matched by portions of the pattern in parentheses. This provides support for capturing parentheses and back references. . +. .SH "THE ALTERNATIVE MATCHING ALGORITHM" .rs .sp @@ -131,14 +139,15 @@ 6. Callouts are supported, but the value of the \fIcapture_top\fP field is always 1, and the value of the \fIcapture_last\fP field is always -1. .P -7. The \eC escape sequence, which (in the standard algorithm) matches a single -byte, even in UTF-8 mode, is not supported because the alternative algorithm -moves through the subject string one character at a time, for all active paths -through the tree. +7. The \eC escape sequence, which (in the standard algorithm) always matches a +single data unit, even in UTF-8 or UTF-16 modes, is not supported in these +modes, because the alternative algorithm moves through the subject string one +character (not data unit) at a time, for all active paths through the tree. .P 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not supported. (*FAIL) is supported, and behaves like a failing negative assertion. . +. .SH "ADVANTAGES OF THE ALTERNATIVE ALGORITHM" .rs .sp @@ -150,11 +159,11 @@ callouts. .P 2. Because the alternative algorithm scans the subject string just once, and -never needs to backtrack, it is possible to pass very long subject strings to -the matching function in several pieces, checking for partial matching each -time. Although it is possible to do multi-segment matching using the standard -algorithm (\fBpcre_exec()\fP), by retaining partially matched substrings, it is -more complicated. The +never needs to backtrack (except for lookbehinds), it is possible to pass very +long subject strings to the matching function in several pieces, checking for +partial matching each time. Although it is possible to do multi-segment +matching using the standard algorithm by retaining partially matched +substrings, it is more complicated. The .\" HREF \fBpcrepartial\fP .\" @@ -191,6 +200,6 @@ .rs .sp .nf -Last updated: 17 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 08 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrepartial.3 pcre3-8.31/doc/pcrepartial.3 --- pcre3-8.12/doc/pcrepartial.3 2010-11-24 17:38:33.000000000 +0000 +++ pcre3-8.31/doc/pcrepartial.3 2012-06-02 10:55:17.000000000 +0000 @@ -1,14 +1,14 @@ -.TH PCREPARTIAL 3 +.TH PCREPARTIAL 3 "24 February 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .SH "PARTIAL MATCHING IN PCRE" .rs .sp -In normal use of PCRE, if the subject string that is passed to -\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP matches as far as it goes, but is -too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There -are circumstances where it might be helpful to distinguish this case from other -cases in which there is no match. +In normal use of PCRE, if the subject string that is passed to a matching +function matches as far as it goes, but is too short to match the entire +pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might +be helpful to distinguish this case from other cases in which there is no +match. .P Consider, for example, an application where a human is required to type in data for a field with specific formatting requirements. An example might be a date @@ -25,40 +25,50 @@ long and is not all available at once. .P PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and -PCRE_PARTIAL_HARD options, which can be set when calling \fBpcre_exec()\fP or -\fBpcre_dfa_exec()\fP. For backwards compatibility, PCRE_PARTIAL is a synonym -for PCRE_PARTIAL_SOFT. The essential difference between the two options is -whether or not a partial match is preferred to an alternative complete match, -though the details differ between the two matching functions. If both options +PCRE_PARTIAL_HARD options, which can be set when calling any of the matching +functions. For backwards compatibility, PCRE_PARTIAL is a synonym for +PCRE_PARTIAL_SOFT. The essential difference between the two options is whether +or not a partial match is preferred to an alternative complete match, though +the details differ between the two types of matching function. If both options are set, PCRE_PARTIAL_HARD takes precedence. .P -Setting a partial matching option disables two of PCRE's optimizations. PCRE -remembers the last literal byte in a pattern, and abandons matching immediately -if such a byte is not present in the subject string. This optimization cannot -be used for a subject string that might match only partially. If the pattern -was studied, PCRE knows the minimum length of a matching string, and does not -bother to run the matching function on shorter strings. This optimization is -also disabled for partial matching. -. -. -.SH "PARTIAL MATCHING USING pcre_exec()" -.rs -.sp -A partial match occurs during a call to \fBpcre_exec()\fP when the end of the -subject string is reached successfully, but matching cannot continue because -more characters are needed. However, at least one character in the subject must -have been inspected. This character need not form part of the final matched -string; lookbehind assertions and the \eK escape sequence provide ways of -inspecting characters before the start of a matched substring. The requirement -for inspecting at least one character exists because an empty string can always -be matched; without such a restriction there would always be a partial match of -an empty string at the end of the subject. -.P -If there are at least two slots in the offsets vector when \fBpcre_exec()\fP -returns with a partial match, the first slot is set to the offset of the -earliest character that was inspected when the partial match was found. For -convenience, the second offset points to the end of the subject so that a -substring can easily be identified. +If you want to use partial matching with just-in-time optimized code, you must +call \fBpcre_study()\fP or \fBpcre16_study()\fP with one or both of these +options: +.sp + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE +.sp +PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial +matches on the same pattern. If the appropriate JIT study mode has not been set +for a match, the interpretive matching code is used. +.P +Setting a partial matching option disables two of PCRE's standard +optimizations. PCRE remembers the last literal data unit in a pattern, and +abandons matching immediately if it is not present in the subject string. This +optimization cannot be used for a subject string that might match only +partially. If the pattern was studied, PCRE knows the minimum length of a +matching string, and does not bother to run the matching function on shorter +strings. This optimization is also disabled for partial matching. +. +. +.SH "PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()" +.rs +.sp +A partial match occurs during a call to \fBpcre_exec()\fP or +\fBpcre16_exec()\fP when the end of the subject string is reached successfully, +but matching cannot continue because more characters are needed. However, at +least one character in the subject must have been inspected. This character +need not form part of the final matched string; lookbehind assertions and the +\eK escape sequence provide ways of inspecting characters before the start of a +matched substring. The requirement for inspecting at least one character exists +because an empty string can always be matched; without such a restriction there +would always be a partial match of an empty string at the end of the subject. +.P +If there are at least two slots in the offsets vector when a partial match is +returned, the first slot is set to the offset of the earliest character that +was inspected. For convenience, the second offset points to the end of the +subject so that a substring can easily be identified. .P For the majority of patterns, the first offset identifies the start of the partially matched string. However, for patterns that contain lookbehind @@ -76,13 +86,14 @@ partial matching options are set. . . -.SS "PCRE_PARTIAL_SOFT with pcre_exec()" +.SS "PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()" .rs .sp -If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP identifies a partial match, -the partial match is remembered, but matching continues as normal, and other -alternatives in the pattern are tried. If no complete match can be found, -\fBpcre_exec()\fP returns PCRE_ERROR_PARTIAL instead of PCRE_ERROR_NOMATCH. +If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP or \fBpcre16_exec()\fP +identifies a partial match, the partial match is remembered, but matching +continues as normal, and other alternatives in the pattern are tried. If no +complete match can be found, PCRE_ERROR_PARTIAL is returned instead of +PCRE_ERROR_NOMATCH. .P This option is "soft" because it prefers a complete match over a partial match. All the various matching items in a pattern behave as if the subject string is @@ -103,21 +114,24 @@ matches the second alternative.) . . -.SS "PCRE_PARTIAL_HARD with pcre_exec()" +.SS "PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()" .rs .sp -If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP, it returns -PCRE_ERROR_PARTIAL as soon as a partial match is found, without continuing to -search for possible complete matches. This option is "hard" because it prefers -an earlier partial match over a later complete match. For this reason, the -assumption is made that the end of the supplied subject string may not be the -true end of the available data, and so, if \ez, \eZ, \eb, \eB, or $ are -encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL. -.P -Setting PCRE_PARTIAL_HARD also affects the way \fBpcre_exec()\fP checks UTF-8 -subject strings for validity. Normally, an invalid UTF-8 sequence causes the -error PCRE_ERROR_BADUTF8. However, in the special case of a truncated UTF-8 -character at the end of the subject, PCRE_ERROR_SHORTUTF8 is returned when +If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP or \fBpcre16_exec()\fP, +PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without +continuing to search for possible complete matches. This option is "hard" +because it prefers an earlier partial match over a later complete match. For +this reason, the assumption is made that the end of the supplied subject string +may not be the true end of the available data, and so, if \ez, \eZ, \eb, \eB, +or $ are encountered at the end of the subject, the result is +PCRE_ERROR_PARTIAL, provided that at least one character in the subject has +been inspected. +.P +Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 +subject strings are checked for validity. Normally, an invalid sequence +causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the +special case of a truncated character at the end of the subject, +PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when PCRE_PARTIAL_HARD is set. . . @@ -137,25 +151,25 @@ .sp /dog(sbody)??/ .sp -In this case the result is always a complete match because \fBpcre_exec()\fP -finds that first, and it never continues after finding a match. It might be -easier to follow this explanation by thinking of the two patterns like this: +In this case the result is always a complete match because that is found first, +and matching never continues after finding a complete match. It might be easier +to follow this explanation by thinking of the two patterns like this: .sp /dog(sbody)?/ is the same as /dogsbody|dog/ /dog(sbody)??/ is the same as /dog|dogsbody/ .sp -The second pattern will never match "dogsbody" when \fBpcre_exec()\fP is -used, because it will always find the shorter match first. +The second pattern will never match "dogsbody", because it will always find the +shorter match first. . . -.SH "PARTIAL MATCHING USING pcre_dfa_exec()" +.SH "PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()" .rs .sp -The \fBpcre_dfa_exec()\fP function moves along the subject string character by -character, without backtracking, searching for all possible matches -simultaneously. If the end of the subject is reached before the end of the -pattern, there is the possibility of a partial match, again provided that at -least one character has been inspected. +The DFA functions move along the subject string character by character, without +backtracking, searching for all possible matches simultaneously. If the end of +the subject is reached before the end of the pattern, there is the possibility +of a partial match, again provided that at least one character has been +inspected. .P When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there have been no complete matches. Otherwise, the complete matches are returned. @@ -164,16 +178,16 @@ partial match was found is set as the first matching string, provided there are at least two slots in the offsets vector. .P -Because \fBpcre_dfa_exec()\fP always searches for all possible matches, and -there is no difference between greedy and ungreedy repetition, its behaviour is -different from \fBpcre_exec\fP when PCRE_PARTIAL_HARD is set. Consider the -string "dog" matched against the ungreedy pattern shown above: +Because the DFA functions always search for all possible matches, and there is +no difference between greedy and ungreedy repetition, their behaviour is +different from the standard functions when PCRE_PARTIAL_HARD is set. Consider +the string "dog" matched against the ungreedy pattern shown above: .sp /dog(sbody)??/ .sp -Whereas \fBpcre_exec()\fP stops as soon as it finds the complete match for -"dog", \fBpcre_dfa_exec()\fP also finds the partial match for "dogsbody", and -so returns that when PCRE_PARTIAL_HARD is set. +Whereas the standard functions stop as soon as they find the complete match for +"dog", the DFA functions also find the partial match for "dogsbody", and so +return that when PCRE_PARTIAL_HARD is set. . . .SH "PARTIAL MATCHING AND WORD BOUNDARIES" @@ -187,14 +201,11 @@ .sp This matches "cat", provided there is a word boundary at either end. If the subject string is "the cat", the comparison of the final "t" with a following -character cannot take place, so a partial match is found. However, -\fBpcre_exec()\fP carries on with normal matching, which matches \eb at the end -of the subject when the last character is a letter, thus finding a complete -match. The result, therefore, is \fInot\fP PCRE_ERROR_PARTIAL. The same thing -happens with \fBpcre_dfa_exec()\fP, because it also finds the complete match. -.P -Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because -then the partial match takes precedence. +character cannot take place, so a partial match is found. However, normal +matching carries on, and \eb matches at the end of the subject when the last +character is a letter, so a complete match is found. The result, therefore, is +\fInot\fP PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield +PCRE_ERROR_PARTIAL, because then the partial match takes precedence. . . .SH "FORMERLY RESTRICTED PATTERNS" @@ -204,7 +215,7 @@ optimizations were implemented in the \fBpcre_exec()\fP function, the PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with all patterns. From release 8.00 onwards, the restrictions no longer apply, and -partial matching with \fBpcre_exec()\fP can be requested for any pattern. +partial matching with can be requested for any pattern. .P Items that were formerly restricted were repeated single characters and repeated metasequences. If PCRE_PARTIAL was set for a pattern that did not @@ -237,23 +248,22 @@ The first data string is matched completely, so \fBpcretest\fP shows the matched substrings. The remaining four strings do not match the complete pattern, but the first two are partial matches. Similar output is obtained -when \fBpcre_dfa_exec()\fP is used. +if DFA matching is used. .P If the escape sequence \eP is present more than once in a \fBpcretest\fP data line, the PCRE_PARTIAL_HARD option is set for the match. . . -.SH "MULTI-SEGMENT MATCHING WITH pcre_dfa_exec()" +.SH "MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()" .rs .sp -When a partial match has been found using \fBpcre_dfa_exec()\fP, it is possible -to continue the match by providing additional subject data and calling -\fBpcre_dfa_exec()\fP again with the same compiled regular expression, this -time setting the PCRE_DFA_RESTART option. You must pass the same working -space as before, because this is where details of the previous partial match -are stored. Here is an example using \fBpcretest\fP, using the \eR escape -sequence to set the PCRE_DFA_RESTART option (\eD specifies the use of -\fBpcre_dfa_exec()\fP): +When a partial match has been found using a DFA matching function, it is +possible to continue the match by providing additional subject data and calling +the function again with the same compiled regular expression, this time setting +the PCRE_DFA_RESTART option. You must pass the same working space as before, +because this is where details of the previous partial match are stored. Here is +an example using \fBpcretest\fP, using the \eR escape sequence to set the +PCRE_DFA_RESTART option (\eD specifies the use of the DFA matching function): .sp re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/ data> 23ja\eP\eD @@ -269,36 +279,39 @@ .P You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with PCRE_DFA_RESTART to continue partial matching over multiple segments. This -facility can be used to pass very long subject strings to -\fBpcre_dfa_exec()\fP. +facility can be used to pass very long subject strings to the DFA matching +functions. . . -.SH "MULTI-SEGMENT MATCHING WITH pcre_exec()" +.SH "MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()" .rs .sp -From release 8.00, \fBpcre_exec()\fP can also be used to do multi-segment -matching. Unlike \fBpcre_dfa_exec()\fP, it is not possible to restart the -previous match with a new segment of data. Instead, new data must be added to -the previous subject string, and the entire match re-run, starting from the -point where the partial match occurred. Earlier data can be discarded. It is -best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the -end of a segment as the end of the subject when matching \ez, \eZ, \eb, \eB, -and $. Consider an unanchored pattern that matches dates: +From release 8.00, the standard matching functions can also be used to do +multi-segment matching. Unlike the DFA functions, it is not possible to +restart the previous match with a new segment of data. Instead, new data must +be added to the previous subject string, and the entire match re-run, starting +from the point where the partial match occurred. Earlier data can be discarded. +.P +It is best to use PCRE_PARTIAL_HARD in this situation, because it does not +treat the end of a segment as the end of the subject when matching \ez, \eZ, +\eb, \eB, and $. Consider an unanchored pattern that matches dates: .sp re> /\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed/ data> The date is 23ja\eP\eP Partial match: 23ja .sp At this stage, an application could discard the text preceding "23ja", add on -text from the next segment, and call \fBpcre_exec()\fP again. Unlike -\fBpcre_dfa_exec()\fP, the entire matching string must always be available, and -the complete matching process occurs for each call, so more memory and more +text from the next segment, and call the matching function again. Unlike the +DFA matching functions, the entire matching string must always be available, +and the complete matching process occurs for each call, so more memory and more processing time is needed. .P \fBNote:\fP If the pattern contains lookbehind assertions, or \eK, or starts -with \eb or \eB, the string that is returned for a partial match will include +with \eb or \eB, the string that is returned for a partial match includes characters that precede the partially matched string itself, because these must be retained when adding on more characters for a subsequent matching attempt. +However, in some cases you may need to retain even earlier characters, as +discussed in the next section. . . .SH "ISSUES WITH MULTI-SEGMENT MATCHING" @@ -313,14 +326,31 @@ doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL. .P -2. Lookbehind assertions at the start of a pattern are catered for in the -offsets that are returned for a partial match. However, in theory, a lookbehind -assertion later in the pattern could require even earlier characters to be -inspected, and it might not have been reached when a partial match occurs. This -is probably an extremely unlikely case; you could guard against it to a certain -extent by always including extra characters at the start. +2. Lookbehind assertions that have already been obeyed are catered for in the +offsets that are returned for a partial match. However a lookbehind assertion +later in the pattern could require even earlier characters to be inspected. You +can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the +\fBpcre_fullinfo()\fP or \fBpcre16_fullinfo()\fP functions to obtain the length +of the largest lookbehind in the pattern. This length is given in characters, +not bytes. If you always retain at least that many characters before the +partially matched string, all should be well. (Of course, near the start of the +subject, fewer characters may be present; in that case all characters should be +retained.) +.P +3. Because a partial match must always contain at least one character, what +might be considered a partial match of an empty string actually gives a "no +match" result. For example: +.sp + re> /c(?<=abc)x/ + data> ab\eP + No match +.sp +If the next segment begins "cx", a match should be found, but this will only +happen if characters from the previous segment are retained. For this reason, a +"no match" result should be interpreted as "partial match of an empty string" +when the pattern contains lookbehinds. .P -3. Matching a subject string that is split into multiple segments may not +4. Matching a subject string that is split into multiple segments may not always produce exactly the same result as matching over one single long string, especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and Word Boundaries" above describes an issue that arises if the pattern ends with @@ -341,14 +371,14 @@ 0: dogsbody 1: dog .sp -The first data line passes the string "dogsb" to \fBpcre_exec()\fP, setting the -PCRE_PARTIAL_SOFT option. Although the string is a partial match for -"dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string -"dog" is a complete match. Similarly, when the subject is presented to -\fBpcre_dfa_exec()\fP in several parts ("do" and "gsb" being the first two) the -match stops when "dog" has been found, and it is not possible to continue. On -the other hand, if "dogsbody" is presented as a single string, -\fBpcre_dfa_exec()\fP finds both matches. +The first data line passes the string "dogsb" to a standard matching function, +setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match +for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter +string "dog" is a complete match. Similarly, when the subject is presented to +a DFA matching function in several parts ("do" and "gsb" being the first two) +the match stops when "dog" has been found, and it is not possible to continue. +On the other hand, if "dogsbody" is presented as a single string, a DFA +matching function finds both matches. .P Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching multi-segment data. The example above then behaves differently: @@ -361,10 +391,9 @@ data> gsb\eR\eP\eP\eD Partial match: gsb .sp -4. Patterns that contain alternatives at the top level which do not all -start with the same pattern item may not work as expected when -PCRE_DFA_RESTART is used with \fBpcre_dfa_exec()\fP. For example, consider this -pattern: +5. Patterns that contain alternatives at the top level which do not all start +with the same pattern item may not work as expected when PCRE_DFA_RESTART is +used. For example, consider this pattern: .sp 1234|3789 .sp @@ -380,8 +409,8 @@ 1234|ABCD .sp where no string can be a partial match for both alternatives. This is not a -problem if \fBpcre_exec()\fP is used, because the entire match has to be rerun -each time: +problem if a standard matching function is used, because the entire match has +to be rerun each time: .sp re> /1234|3789/ data> ABC123\eP\eP @@ -390,7 +419,7 @@ 0: 3789 .sp Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running -the entire match can also be used with \fBpcre_dfa_exec()\fP. Another +the entire match can also be used with the DFA matching functions. Another possibility is to work with two buffers. If a partial match at offset \fIn\fP in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on the second buffer, you can then try a new match starting at offset \fIn+1\fP in @@ -411,6 +440,6 @@ .rs .sp .nf -Last updated: 07 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 24 February 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrepattern.3 pcre3-8.31/doc/pcrepattern.3 --- pcre3-8.12/doc/pcrepattern.3 2010-11-24 17:38:33.000000000 +0000 +++ pcre3-8.31/doc/pcrepattern.3 2012-06-20 15:08:50.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREPATTERN 3 +.TH PCREPATTERN 3 "04 May 2012" "PCRE 8.31" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION DETAILS" @@ -21,29 +21,27 @@ description of PCRE's regular expressions is intended as reference material. .P The original operation of PCRE was on strings of one-byte characters. However, -there is now also support for UTF-8 character strings. To use this, -PCRE must be built to include UTF-8 support, and you must call -\fBpcre_compile()\fP or \fBpcre_compile2()\fP with the PCRE_UTF8 option. There -is also a special sequence that can be given at the start of a pattern: +there is now also support for UTF-8 strings in the original library, and a +second library that supports 16-bit and UTF-16 character strings. To use these +features, PCRE must be built to include appropriate support. When using UTF +strings you must either call the compiling function with the PCRE_UTF8 or +PCRE_UTF16 option, or the pattern must start with one of these special +sequences: .sp (*UTF8) + (*UTF16) .sp -Starting a pattern with this sequence is equivalent to setting the PCRE_UTF8 -option. This feature is not Perl-compatible. How setting UTF-8 mode affects +Starting a pattern with such a sequence is equivalent to setting the relevant +option. This feature is not Perl-compatible. How setting a UTF mode affects pattern matching is mentioned in several places below. There is also a summary -of UTF-8 features in the -.\" HTML -.\" -section on UTF-8 support -.\" -in the main +of features in the .\" HREF -\fBpcre\fP +\fBpcreunicode\fP .\" page. .P Another special sequence that may appear at the start of a pattern or in -combination with (*UTF8) is: +combination with (*UTF8) or (*UTF16) is: .sp (*UCP) .sp @@ -58,13 +56,13 @@ of newlines; they are described below. .P The remainder of this document discusses the patterns that are supported by -PCRE when its main matching function, \fBpcre_exec()\fP, is used. -From release 6.0, PCRE offers a second matching function, -\fBpcre_dfa_exec()\fP, which matches using a different algorithm that is not -Perl-compatible. Some of the features discussed below are not available when -\fBpcre_dfa_exec()\fP is used. The advantages and disadvantages of the -alternative function, and how it differs from the normal function, are -discussed in the +PCRE when one its main matching functions, \fBpcre_exec()\fP (8-bit) or +\fBpcre16_exec()\fP (16-bit), is used. PCRE also has alternative matching +functions, \fBpcre_dfa_exec()\fP and \fBpcre16_dfa_exec()\fP, which match using +a different algorithm that is not Perl-compatible. Some of the features +discussed below are not available when DFA matching is used. The advantages and +disadvantages of the alternative functions, and how they differ from the normal +functions, are discussed in the .\" HREF \fBpcrematching\fP .\" @@ -99,9 +97,8 @@ (*ANYCRLF) any of the three above (*ANY) all Unicode newline sequences .sp -These override the default and the options given to \fBpcre_compile()\fP or -\fBpcre_compile2()\fP. For example, on a Unix system where LF is the default -newline sequence, the pattern +These override the default and the options given to the compiling function. For +example, on a Unix system where LF is the default newline sequence, the pattern .sp (*CR)a.b .sp @@ -135,13 +132,13 @@ .sp matches a portion of a subject string that is identical to itself. When caseless matching is specified (the PCRE_CASELESS option), letters are matched -independently of case. In UTF-8 mode, PCRE always understands the concept of +independently of case. In a UTF mode, PCRE always understands the concept of case for characters whose values are less than 128, so caseless matching is always possible. For characters with higher values, the concept of case is supported if PCRE is compiled with Unicode property support, but not otherwise. If you want to use caseless matching for characters 128 and above, you must ensure that PCRE is compiled with Unicode property support as well as with -UTF-8 support. +UTF support. .P The power of regular expressions comes from the ability to include alternatives and repetitions in the pattern. These are encoded in the pattern by the use of @@ -197,14 +194,14 @@ non-alphanumeric with backslash to specify that it stands for itself. In particular, if you want to match a backslash, you write \e\e. .P -In UTF-8 mode, only ASCII numbers and letters have any special meaning after a +In a UTF mode, only ASCII numbers and letters have any special meaning after a backslash. All other characters (in particular, those whose codepoints are greater than 127) are treated as literals. .P -If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the +If a pattern is compiled with the PCRE_EXTENDED option, white space in the pattern (other than in a character class) and characters between a # outside a character class and the next newline are ignored. An escaping backslash can -be used to include a whitespace or # character as part of the pattern. +be used to include a white space or # character as part of the pattern. .P If you want to remove the special meaning from a sequence of characters, you can do so by putting them between \eQ and \eE. This is different from Perl in @@ -220,7 +217,11 @@ \eQabc\eE\e$\eQxyz\eE abc$xyz abc$xyz .sp The \eQ...\eE sequence is recognized both inside and outside character classes. -An isolated \eE that is not preceded by \eQ is ignored. +An isolated \eE that is not preceded by \eQ is ignored. If \eQ is not followed +by \eE later in the pattern, the literal interpretation continues to the end of +the pattern (that is, \eE is assumed at the end). If the isolated \eQ is inside +a character class, this causes an error, because the character class is not +terminated. . . .\" HTML @@ -236,38 +237,53 @@ \ea alarm, that is, the BEL character (hex 07) \ecx "control-x", where x is any ASCII character \ee escape (hex 1B) - \ef formfeed (hex 0C) + \ef form feed (hex 0C) \en linefeed (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) \eddd character with octal code ddd, or back reference \exhh character with hex code hh - \ex{hhh..} character with hex code hhh.. + \ex{hhh..} character with hex code hhh.. (non-JavaScript mode) + \euhhhh character with hex code hhhh (JavaScript mode only) .sp The precise effect of \ecx is as follows: if x is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. Thus \ecz becomes hex 1A (z is 7A), but \ec{ becomes hex 3B ({ is 7B), while \ec; becomes hex 7B (; is 3B). If the byte following \ec has a value greater than 127, a compile-time error occurs. This locks out non-ASCII characters in -both byte mode and UTF-8 mode. (When PCRE is compiled in EBCDIC mode, all byte -values are valid. A lower case letter is converted to upper case, and then the -0xc0 bits are flipped.) -.P -After \ex, from zero to two hexadecimal digits are read (letters can be in -upper or lower case). Any number of hexadecimal digits may appear between \ex{ -and }, but the value of the character code must be less than 256 in non-UTF-8 -mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in -hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code -point, which is 10FFFF. +all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A +lower case letter is converted to upper case, and then the 0xc0 bits are +flipped.) +.P +By default, after \ex, from zero to two hexadecimal digits are read (letters +can be in upper or lower case). Any number of hexadecimal digits may appear +between \ex{ and }, but the character code is constrained as follows: +.sp + 8-bit non-UTF mode less than 0x100 + 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint + 16-bit non-UTF mode less than 0x10000 + 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint +.sp +Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called +"surrogate" codepoints). .P If characters other than hexadecimal digits appear between \ex{ and }, or if there is no terminating }, this form of escape is not recognized. Instead, the initial \ex will be interpreted as a basic hexadecimal escape, with no following digits, giving a character whose value is zero. .P +If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \ex is +as just described only when it is followed by two hexadecimal digits. +Otherwise, it matches a literal "x" character. In JavaScript mode, support for +code points greater than 256 is provided by \eu, which must be followed by +four hexadecimal digits; otherwise it matches a literal "u" character. +Character codes specified by \eu in JavaScript mode are constrained in the same +was as those specified by \ex in non-JavaScript mode. +.P Characters whose value is less than 256 can be defined by either of the two -syntaxes for \ex. There is no difference in the way they are handled. For -example, \exdc is exactly the same as \ex{dc}. +syntaxes for \ex (or by \eu in JavaScript mode). There is no difference in the +way they are handled. For example, \exdc is exactly the same as \ex{dc} (or +\eu00dc in JavaScript mode). .P After \e0 up to two further octal digits are read. If there are fewer than two digits, just those that are present are used. Thus the sequence \e0\ex\e07 @@ -293,9 +309,9 @@ Inside a character class, or if the decimal number is greater than 9 and there have not been that many capturing subpatterns, PCRE re-reads up to three octal digits following the backslash, and uses them to generate a data character. Any -subsequent digits stand for themselves. In non-UTF-8 mode, the value of a -character specified in octal must be less than \e400. In UTF-8 mode, values up -to \e777 are permitted. For example: +subsequent digits stand for themselves. The value of the character is +constrained in the same way as characters specified in hexadecimal. +For example: .sp \e040 is another way of writing a space .\" JOIN @@ -312,7 +328,7 @@ character with octal code 113 .\" JOIN \e377 might be a back reference, otherwise - the byte consisting entirely of 1 bits + the value 255 (decimal) .\" JOIN \e81 is either a back reference, or a binary zero followed by the two characters "8" and "1" @@ -321,12 +337,24 @@ zero, because no more than three octal digits are ever read. .P All the sequences that define a single character value can be used both inside -and outside character classes. In addition, inside a character class, the -sequence \eb is interpreted as the backspace character (hex 08). The sequences -\eB, \eN, \eR, and \eX are not special inside a character class. Like any other -unrecognized escape sequences, they are treated as the literal characters "B", -"N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is -set. Outside a character class, these sequences have different meanings. +and outside character classes. In addition, inside a character class, \eb is +interpreted as the backspace character (hex 08). +.P +\eN is not allowed in a character class. \eB, \eR, and \eX are not special +inside a character class. Like other unrecognized escape sequences, they are +treated as the literal characters "B", "R", and "X" by default, but cause an +error if the PCRE_EXTRA option is set. Outside a character class, these +sequences have different meanings. +. +. +.SS "Unsupported escape sequences" +.rs +.sp +In Perl, the sequences \el, \eL, \eu, and \eU are recognized by its string +handler and used to modify the case of following characters. By default, PCRE +does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT +option is set, \eU matches a "U" character, and \eu can be used to define a +character by code point, as described in the previous section. . . .SS "Absolute and relative back references" @@ -373,12 +401,12 @@ .sp \ed any decimal digit \eD any character that is not a decimal digit - \eh any horizontal whitespace character - \eH any character that is not a horizontal whitespace character - \es any whitespace character - \eS any character that is not a whitespace character - \ev any vertical whitespace character - \eV any character that is not a vertical whitespace character + \eh any horizontal white space character + \eH any character that is not a horizontal white space character + \es any white space character + \eS any character that is not a white space character + \ev any vertical white space character + \eV any character that is not a vertical white space character \ew any "word" character \eW any "non-word" character .sp @@ -388,7 +416,8 @@ .\" the "." metacharacter .\" -when PCRE_DOTALL is not set. +when PCRE_DOTALL is not set. Perl also uses \eN to match characters by name; +PCRE does not support this. .P Each pair of lower and upper case escape sequences partitions the complete set of characters into two disjoint sets. Any given character matches one, and only @@ -420,9 +449,9 @@ accented letters, and these are then matched by \ew. The use of locales with Unicode is discouraged. .P -By default, in UTF-8 mode, characters with values greater than 128 never match +By default, in a UTF mode, characters with values greater than 128 never match \ed, \es, or \ew, and always match \eD, \eS, and \eW. These sequences retain -their original meanings from before UTF-8 support was available, mainly for +their original meanings from before UTF support was available, mainly for efficiency reasons. However, if PCRE is compiled with Unicode property support, and the PCRE_UCP option is set, the behaviour is changed so that Unicode properties are used to determine character types, as follows: @@ -439,9 +468,8 @@ .P The sequences \eh, \eH, \ev, and \eV are features that were added to Perl at release 5.10. In contrast to the other sequences, which match only ASCII -characters by default, these always match certain high-valued codepoints in -UTF-8 mode, whether or not PCRE_UCP is set. The horizontal space characters -are: +characters by default, these always match certain high-valued codepoints, +whether or not PCRE_UCP is set. The horizontal space characters are: .sp U+0009 Horizontal tab U+0020 Space @@ -467,11 +495,14 @@ .sp U+000A Linefeed U+000B Vertical tab - U+000C Formfeed + U+000C Form feed U+000D Carriage return U+0085 Next line U+2028 Line separator U+2029 Paragraph separator +.sp +In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are +relevant. . . .\" HTML @@ -479,7 +510,8 @@ .rs .sp Outside a character class, by default, the escape sequence \eR matches any -Unicode newline sequence. In non-UTF-8 mode \eR is equivalent to the following: +Unicode newline sequence. In 8-bit non-UTF-8 mode \eR is equivalent to the +following: .sp (?>\er\en|\en|\ex0b|\ef|\er|\ex85) .sp @@ -490,11 +522,11 @@ .\" This particular group matches either the two-character sequence CR followed by LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab, -U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), or NEL (next +U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next line, U+0085). The two-character sequence is treated as a single unit that cannot be split. .P -In UTF-8 mode, two additional characters whose codepoints are greater than 255 +In other modes, two additional characters whose codepoints are greater than 255 are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029). Unicode character property support is not needed for these characters to be recognized. @@ -510,19 +542,19 @@ (*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence .sp -These override the default and the options given to \fBpcre_compile()\fP or -\fBpcre_compile2()\fP, but they can be overridden by options given to -\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. Note that these special settings, -which are not Perl-compatible, are recognized only at the very start of a -pattern, and that they must be in upper case. If more than one of them is -present, the last one is used. They can be combined with a change of newline -convention; for example, a pattern can start with: +These override the default and the options given to the compiling function, but +they can themselves be overridden by options given to a matching function. Note +that these special settings, which are not Perl-compatible, are recognized only +at the very start of a pattern, and that they must be in upper case. If more +than one of them is present, the last one is used. They can be combined with a +change of newline convention; for example, a pattern can start with: .sp (*ANY)(*BSR_ANYCRLF) .sp -They can also be combined with the (*UTF8) or (*UCP) special sequences. Inside -a character class, \eR is treated as an unrecognized escape sequence, and so -matches the letter "R" by default, but causes an error if PCRE_EXTRA is set. +They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special +sequences. Inside a character class, \eR is treated as an unrecognized escape +sequence, and so matches the letter "R" by default, but causes an error if +PCRE_EXTRA is set. . . .\" HTML @@ -531,7 +563,7 @@ .sp When PCRE is built with Unicode character property support, three additional escape sequences that match characters with specific properties are available. -When not in UTF-8 mode, these sequences are of course limited to testing +When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are: .sp @@ -566,13 +598,16 @@ Avestan, Balinese, Bamum, +Batak, Bengali, Bopomofo, +Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, +Chakma, Cham, Cherokee, Common, @@ -615,7 +650,11 @@ Lycian, Lydian, Malayalam, +Mandaic, Meetei_Mayek, +Meroitic_Cursive, +Meroitic_Hieroglyphs, +Miao, Mongolian, Myanmar, New_Tai_Lue, @@ -634,8 +673,10 @@ Runic, Samaritan, Saurashtra, +Sharada, Shavian, Sinhala, +Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, @@ -644,6 +685,7 @@ Tai_Le, Tai_Tham, Tai_Viet, +Takri, Tamil, Telugu, Thaana, @@ -718,9 +760,9 @@ a modifier or "other". .P The Cs (Surrogate) property applies only to characters in the range U+D800 to -U+DFFF. Such characters are not valid in UTF-8 strings (see RFC 3629) and so -cannot be tested by PCRE, unless UTF-8 validity checking has been turned off -(see the discussion of PCRE_NO_UTF8_CHECK in the +U+DFFF. Such characters are not valid in Unicode strings and so +cannot be tested by PCRE, unless UTF validity checking has been turned off +(see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the .\" HREF \fBpcreapi\fP .\" @@ -751,14 +793,16 @@ .\" Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in -non-UTF-8 mode \eX matches any one character. +8-bit non-UTF-8 mode \eX matches any one character. +.P +Note that recent versions of Perl have changed \eX to match what Unicode calls +an "extended grapheme cluster", which has a more complicated definition. .P Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \ed and \ew do not use Unicode properties in PCRE by default, though you can make them do so by setting the -PCRE_UCP option for \fBpcre_compile()\fP or by starting the pattern with -(*UCP). +PCRE_UCP option or by starting the pattern with (*UCP). . . .\" HTML @@ -777,7 +821,7 @@ Xwd Any Perl "word" character .sp Xan matches characters that have either the L (letter) or the N (number) -property. Xps matches the characters tab, linefeed, vertical tab, formfeed, or +property. Xps matches the characters tab, linefeed, vertical tab, form feed, or carriage return, and any other character that has the Z (separator) property. Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the same characters as Xan, plus underscore. @@ -847,7 +891,7 @@ A word boundary is a position in the subject string where the current character and the previous character do not both match \ew or \eW (i.e. one matches \ew and the other matches \eW), or the start or end of the string if the -first or last character matches \ew, respectively. In UTF-8 mode, the meanings +first or last character matches \ew, respectively. In a UTF mode, the meanings of \ew and \eW can be changed by setting the PCRE_UCP option. When this is done, it also affects \eb and \eB. Neither PCRE nor Perl has a separate "start of word" or "end of word" metasequence. However, whatever follows \eb normally @@ -942,7 +986,7 @@ .sp Outside a character class, a dot in the pattern matches any one character in the subject string except (by default) a character that signifies the end of a -line. In UTF-8 mode, the matched character may be more than one byte long. +line. .P When a line ending is defined as a single character, dot never matches that character; when the two-character sequence CRLF is used, dot does not match CR @@ -962,26 +1006,53 @@ .P The escape sequence \eN behaves like a dot, except that it is not affected by the PCRE_DOTALL option. In other words, it matches any character except one -that signifies the end of a line. +that signifies the end of a line. Perl also uses \eN to match characters by +name; PCRE does not support this. . . -.SH "MATCHING A SINGLE BYTE" +.SH "MATCHING A SINGLE DATA UNIT" .rs .sp -Outside a character class, the escape sequence \eC matches any one byte, both -in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending -characters. The feature is provided in Perl in order to match individual bytes -in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes, the -rest of the string may start with a malformed UTF-8 character. For this reason, -the \eC escape sequence is best avoided. +Outside a character class, the escape sequence \eC matches any one data unit, +whether or not a UTF mode is set. In the 8-bit library, one data unit is one +byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \eC always +matches line-ending characters. The feature is provided in Perl in order to +match individual bytes in UTF-8 mode, but it is unclear how it can usefully be +used. Because \eC breaks up characters into individual data units, matching one +unit with \eC in a UTF mode means that the rest of the string may start with a +malformed UTF character. This has undefined results, because PCRE assumes that +it is dealing with valid UTF strings (and by default it checks this at the +start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option +is used). .P PCRE does not allow \eC to appear in lookbehind assertions .\" HTML .\" -(described below), +(described below) .\" -because in UTF-8 mode this would make it impossible to calculate the length of +in a UTF mode, because this would make it impossible to calculate the length of the lookbehind. +.P +In general, the \eC escape sequence is best avoided. However, one +way of using it that avoids the problem of malformed UTF characters is to use a +lookahead to check the length of the next character, as in this pattern, which +could be used with a UTF-8 string (ignore white space and line breaks): +.sp + (?| (?=[\ex00-\ex7f])(\eC) | + (?=[\ex80-\ex{7ff}])(\eC)(\eC) | + (?=[\ex{800}-\ex{ffff}])(\eC)(\eC)(\eC) | + (?=[\ex{10000}-\ex{1fffff}])(\eC)(\eC)(\eC)(\eC)) +.sp +A group that starts with (?| resets the capturing parentheses numbers in each +alternative (see +.\" HTML +.\" +"Duplicate Subpattern Numbers" +.\" +below). The assertions at the start of each branch check the next UTF-8 +character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The +character's individual bytes are then captured by the appropriate number of +groups. . . .\" HTML @@ -995,12 +1066,12 @@ a member of the class, it should be the first data character in the class (after an initial circumflex, if present) or escaped with a backslash. .P -A character class matches a single character in the subject. In UTF-8 mode, the -character may be more than one byte long. A matched character must be in the -set of characters defined by the class, unless the first character in the class -definition is a circumflex, in which case the subject character must not be in -the set defined by the class. If a circumflex is actually required as a member -of the class, ensure it is not the first character, or escape it with a +A character class matches a single character in the subject. In a UTF mode, the +character may be more than one data unit long. A matched character must be in +the set of characters defined by the class, unless the first character in the +class definition is a circumflex, in which case the subject character must not +be in the set defined by the class. If a circumflex is actually required as a +member of the class, ensure it is not the first character, or escape it with a backslash. .P For example, the character class [aeiou] matches any lower case vowel, while @@ -1011,19 +1082,20 @@ string, and therefore it fails if the current pointer is at the end of the string. .P -In UTF-8 mode, characters with values greater than 255 can be included in a -class as a literal string of bytes, or by using the \ex{ escaping mechanism. +In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be +included in a class as a literal string of data units, or by using the \ex{ +escaping mechanism. .P When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a -caseful version would. In UTF-8 mode, PCRE always understands the concept of +caseful version would. In a UTF mode, PCRE always understands the concept of case for characters whose values are less than 128, so caseless matching is always possible. For characters with higher values, the concept of case is supported if PCRE is compiled with Unicode property support, but not otherwise. -If you want to use caseless matching in UTF8-mode for characters 128 and above, -you must ensure that PCRE is compiled with Unicode property support as well as -with UTF-8 support. +If you want to use caseless matching in a UTF mode for characters 128 and +above, you must ensure that PCRE is compiled with Unicode property support as +well as with UTF support. .P Characters that might indicate line breaks are never treated in any special way when matching character classes, whatever line-ending sequence is in use, and @@ -1045,22 +1117,21 @@ "]" can also be used to end a range. .P Ranges operate in the collating sequence of character values. They can also be -used for characters specified numerically, for example [\e000-\e037]. In UTF-8 -mode, ranges can include characters whose values are greater than 255, for -example [\ex{100}-\ex{2ff}]. +used for characters specified numerically, for example [\e000-\e037]. Ranges +can include any characters that are valid for the current mode. .P If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to -[][\e\e^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if character +[][\e\e^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character tables for a French locale are in use, [\exc8-\excb] matches accented E -characters in both cases. In UTF-8 mode, PCRE supports the concept of case for +characters in both cases. In UTF modes, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support. .P The character escape sequences \ed, \eD, \eh, \eH, \ep, \eP, \es, \eS, \ev, \eV, \ew, and \eW may appear in a character class, and add the characters that they match to the class. For example, [\edABCDEF] matches any hexadecimal -digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of \ed, \es, \ew +digit. In UTF modes, the PCRE_UCP option affects the meanings of \ed, \es, \ew and their upper case partners, just as it does when they appear outside a character class, as described in the section entitled .\" HTML @@ -1130,7 +1201,7 @@ syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not supported, and an error is given if they are encountered. .P -By default, in UTF-8 mode, characters with values greater than 128 do not match +By default, in UTF modes, characters with values greater than 128 do not match any of the POSIX character classes. However, if the PCRE_UCP option is passed to \fBpcre_compile()\fP, some of the classes are changed so that Unicode character properties are used. This is achieved by replacing the POSIX classes @@ -1218,17 +1289,17 @@ behaviour otherwise. .P \fBNote:\fP There are other PCRE-specific options that can be set by the -application when the compile or match functions are called. In some cases the -pattern can contain special leading sequences such as (*CRLF) to override what -the application has set or what has been defaulted. Details are given in the -section entitled +application when the compiling or matching functions are called. In some cases +the pattern can contain special leading sequences such as (*CRLF) to override +what the application has set or what has been defaulted. Details are given in +the section entitled .\" HTML .\" "Newline sequences" .\" -above. There are also the (*UTF8) and (*UCP) leading sequences that can be used -to set UTF-8 and Unicode property modes; they are equivalent to setting the -PCRE_UTF8 and the PCRE_UCP options, respectively. +above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that +can be used to set UTF and Unicode property modes; they are equivalent to +setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively. . . .\" HTML @@ -1247,10 +1318,13 @@ .sp 2. It sets up the subpattern as a capturing subpattern. This means that, when the whole pattern matches, that portion of the subject string that matched the -subpattern is passed back to the caller via the \fIovector\fP argument of -\fBpcre_exec()\fP. Opening parentheses are counted from left to right (starting -from 1) to obtain numbers for the capturing subpatterns. For example, if the -string "the red king" is matched against the pattern +subpattern is passed back to the caller via the \fIovector\fP argument of the +matching function. (This applies only to the traditional matching functions; +the DFA matching functions do not support capturing.) +.P +Opening parentheses are counted from left to right (starting from 1) to obtain +numbers for the capturing subpatterns. For example, if the string "the red +king" is matched against the pattern .sp the ((red|white) (king|queen)) .sp @@ -1313,9 +1387,9 @@ .sp /(?|(abc)|(def))\e1/ .sp -In contrast, a recursive or "subroutine" call to a numbered subpattern always -refers to the first one in the pattern with the given number. The following -pattern matches "abcabc" or "defabc": +In contrast, a subroutine call to a numbered subpattern always refers to the +first one in the pattern with the given number. The following pattern matches +"abcabc" or "defabc": .sp /(?|(abc)|(def))(?1)/ .sp @@ -1426,13 +1500,13 @@ a literal data character the dot metacharacter the \eC escape sequence - the \eX escape sequence (in UTF-8 mode with Unicode properties) + the \eX escape sequence the \eR escape sequence an escape such as \ed or \epL that matches a single character a character class a back reference (see next section) - a parenthesized subpattern (unless it is an assertion) - a recursive or "subroutine" call to a subpattern + a parenthesized subpattern (including assertions) + a subroutine call to a subpattern (recursive or otherwise) .sp The general repetition quantifier specifies a minimum and maximum number of permitted matches, by giving the two numbers in curly brackets (braces), @@ -1457,11 +1531,11 @@ quantifier, is taken as a literal character. For example, {,6} is not a quantifier, but a literal string of four characters. .P -In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual -bytes. Thus, for example, \ex{100}{2} matches two UTF-8 characters, each of -which is represented by a two-byte sequence. Similarly, when Unicode property -support is available, \eX{3} matches three Unicode extended sequences, each of -which may be several bytes long (and they may be of different lengths). +In UTF modes, quantifiers apply to characters rather than to individual data +units. Thus, for example, \ex{100}{2} matches two characters, each of +which is represented by a two-byte sequence in a UTF-8 string. Similarly, +\eX{3} matches three Unicode extended sequences, each of which may be several +data units long (and they may be of different lengths). .P The quantifier {0} is permitted, causing the expression to behave as if the previous item and the quantifier were not present. This may be useful for @@ -1771,7 +1845,7 @@ following a backslash are taken as part of a potential back reference number. If the pattern continues with a digit character, some delimiter must be used to terminate the back reference. If the PCRE_EXTENDED option is set, this can be -whitespace. Otherwise, the \eg{ syntax or an empty comment (see +white space. Otherwise, the \eg{ syntax or an empty comment (see .\" HTML .\" "Comments" @@ -1822,12 +1896,31 @@ that look behind it. An assertion subpattern is matched in the normal way, except that it does not cause the current matching position to be changed. .P -Assertion subpatterns are not capturing subpatterns, and may not be repeated, -because it makes no sense to assert the same thing several times. If any kind -of assertion contains capturing subpatterns within it, these are counted for -the purposes of numbering the capturing subpatterns in the whole pattern. -However, substring capturing is carried out only for positive assertions, -because it does not make sense for negative assertions. +Assertion subpatterns are not capturing subpatterns. If such an assertion +contains capturing subpatterns within it, these are counted for the purposes of +numbering the capturing subpatterns in the whole pattern. However, substring +capturing is carried out only for positive assertions, because it does not make +sense for negative assertions. +.P +For compatibility with Perl, assertion subpatterns may be repeated; though +it makes no sense to assert the same thing several times, the side effect of +capturing parentheses may occasionally be useful. In practice, there only three +cases: +.sp +(1) If the quantifier is {0}, the assertion is never obeyed during matching. +However, it may contain internal capturing parenthesized groups that are called +from elsewhere via the +.\" HTML +.\" +subroutine mechanism. +.\" +.sp +(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it +were {0,1}. At run time, the rest of the pattern match is tried with and +without the assertion, the order depending on the greediness of the quantifier. +.sp +(3) If the minimum repetition is greater than zero, the quantifier is ignored. +The assertion is obeyed just once when encountered during matching. . . .SS "Lookahead assertions" @@ -1905,10 +1998,11 @@ match. If there are insufficient characters before the current position, the assertion fails. .P -PCRE does not allow the \eC escape (which matches a single byte in UTF-8 mode) -to appear in lookbehind assertions, because it makes it impossible to calculate -the length of the lookbehind. The \eX and \eR escapes, which can match -different numbers of bytes, are also not permitted. +In a UTF mode, PCRE does not allow the \eC escape (which matches a single data +unit even in a UTF mode) to appear in lookbehind assertions, because it makes +it impossible to calculate the length of the lookbehind. The \eX and \eR +escapes, which can match different numbers of data units, are also not +permitted. .P .\" HTML .\" @@ -2102,13 +2196,13 @@ name DEFINE, the condition is always false. In this case, there may be only one alternative in the subpattern. It is always skipped if control reaches this point in the pattern; the idea of DEFINE is that it can be used to define -"subroutines" that can be referenced from elsewhere. (The use of +subroutines that can be referenced from elsewhere. (The use of .\" HTML .\" -"subroutines" +subroutines .\" is described below.) For example, a pattern to match an IPv4 address such as -"192.168.23.245" could be written like this (ignore whitespace and line +"192.168.23.245" could be written like this (ignore white space and line breaks): .sp (?(DEFINE) (? 2[0-4]\ed | 25[0-5] | 1\ed\ed | [1-9]?\ed) ) @@ -2155,7 +2249,7 @@ option is set, an unescaped # character also introduces a comment, which in this case continues to immediately after the next newline character or character sequence in the pattern. Which characters are interpreted as newlines -is controlled by the options passed to \fBpcre_compile()\fP or by a special +is controlled by the options passed to a compiling function or by a special sequence at the start of the pattern, as described in the section entitled .\" HTML .\" @@ -2200,11 +2294,11 @@ this kind of recursion was subsequently introduced into Perl at release 5.10. .P A special item that consists of (? followed by a number greater than zero and a -closing parenthesis is a recursive call of the subpattern of the given number, -provided that it occurs inside that subpattern. (If not, it is a +closing parenthesis is a recursive subroutine call of the subpattern of the +given number, provided that it occurs inside that subpattern. (If not, it is a .\" HTML .\" -"subroutine" +non-recursive subroutine .\" call, which is described in the next section.) The special item (?R) or (?0) is a recursive call of the entire regular expression. @@ -2239,7 +2333,7 @@ reference is not inside the parentheses that are referenced. They are always .\" HTML .\" -"subroutine" +non-recursive subroutine .\" calls, as described in the next section. .P @@ -2276,8 +2370,8 @@ .sp the value for the inner capturing parentheses (numbered 2) is "ef", which is the last value taken on at the top level. If a capturing subpattern is not -matched at the top level, its final value is unset, even if it is (temporarily) -set at a deeper level. +matched at the top level, its final captured value is unset, even if it was +(temporarily) set at a deeper level during the matching process. .P If there are more than 15 capturing parentheses in a pattern, PCRE has to obtain extra memory to store data during a recursion, which it does by using @@ -2297,15 +2391,16 @@ . . .\" HTML -.SS "Recursion difference from Perl" +.SS "Differences in recursion processing between PCRE and Perl" .rs .sp -In PCRE (like Python, but unlike Perl), a recursive subpattern call is always -treated as an atomic group. That is, once it has matched some of the subject -string, it is never re-entered, even if it contains untried alternatives and -there is a subsequent matching failure. This can be illustrated by the -following pattern, which purports to match a palindromic string that contains -an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"): +Recursion processing in PCRE differs from Perl in two important ways. In PCRE +(like Python, but unlike Perl), a recursive subpattern call is always treated +as an atomic group. That is, once it has matched some of the subject string, it +is never re-entered, even if it contains untried alternatives and there is a +subsequent matching failure. This can be illustrated by the following pattern, +which purports to match a palindromic string that contains an odd number of +characters (for example, "a", "aba", "abcba", "abcdcba"): .sp ^(.|(.)(?1)\e2)$ .sp @@ -2366,15 +2461,30 @@ PCRE finds the palindrome "aba" at the start, then fails at top level because the end of the string does not follow. Once again, it cannot jump back into the recursion to try other alternatives, so the entire match fails. +.P +The second way in which PCRE and Perl differ in their recursion processing is +in the handling of captured values. In Perl, when a subpattern is called +recursively or as a subpattern (see the next section), it has no access to any +values that were captured outside the recursion, whereas in PCRE these values +can be referenced. Consider this pattern: +.sp + ^(.)(\e1|a(?2)) +.sp +In PCRE, this pattern matches "bab". The first capturing parentheses match "b", +then in the second group, when the back reference \e1 fails to match "b", the +second alternative matches "a" and then recurses. In the recursion, \e1 does +now match "b" and so the whole match succeeds. In Perl, the pattern fails to +match because inside the recursive call \e1 cannot access the externally set +value. . . .\" HTML .SH "SUBPATTERNS AS SUBROUTINES" .rs .sp -If the syntax for a recursive subpattern reference (either by number or by +If the syntax for a recursive subpattern call (either by number or by name) is used outside the parentheses to which it refers, it operates like a -subroutine in a programming language. The "called" subpattern may be defined +subroutine in a programming language. The called subpattern may be defined before or after the reference. A numbered reference can be absolute or relative, as in these examples: .sp @@ -2394,15 +2504,15 @@ is used, it does match "sense and responsibility" as well as the other two strings. Another example is given in the discussion of DEFINE above. .P -Like recursive subpatterns, a subroutine call is always treated as an atomic -group. That is, once it has matched some of the subject string, it is never -re-entered, even if it contains untried alternatives and there is a subsequent -matching failure. Any capturing parentheses that are set during the subroutine -call revert to their previous values afterwards. -.P -When a subpattern is used as a subroutine, processing options such as -case-independence are fixed when the subpattern is defined. They cannot be -changed for different calls. For example, consider this pattern: +All subroutine calls, whether recursive or not, are always treated as atomic +groups. That is, once a subroutine has matched some of the subject string, it +is never re-entered, even if it contains untried alternatives and there is a +subsequent matching failure. Any capturing parentheses that are set during the +subroutine call revert to their previous values afterwards. +.P +Processing options such as case-independence are fixed when a subpattern is +defined, so if it is used as a subroutine, such options cannot be changed for +different calls. For example, consider this pattern: .sp (abc)(?i:(?-1)) .sp @@ -2441,8 +2551,9 @@ .P PCRE provides a similar feature, but of course it cannot obey arbitrary Perl code. The feature is called "callout". The caller of PCRE provides an external -function by putting its entry point in the global variable \fIpcre_callout\fP. -By default, this variable contains NULL, which disables all calling out. +function by putting its entry point in the global variable \fIpcre_callout\fP +(8-bit library) or \fIpcre16_callout\fP (16-bit library). By default, this +variable contains NULL, which disables all calling out. .P Within a regular expression, (?C) indicates the points at which the external function is to be called. If you want to identify different callout points, you @@ -2451,16 +2562,16 @@ .sp (?C1)abc(?C2)def .sp -If the PCRE_AUTO_CALLOUT flag is passed to \fBpcre_compile()\fP, callouts are +If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are automatically installed before each item in the pattern. They are all numbered 255. .P -During matching, when PCRE reaches a callout point (and \fIpcre_callout\fP is -set), the external function is called. It is provided with the number of the -callout, the position in the pattern, and, optionally, one item of data -originally supplied by the caller of \fBpcre_exec()\fP. The callout function -may cause matching to proceed, to backtrack, or to fail altogether. A complete -description of the interface to the callout function is given in the +During matching, when PCRE reaches a callout point, the external function is +called. It is provided with the number of the callout, the position in the +pattern, and, optionally, one item of data originally supplied by the caller of +the matching function. The callout function may cause matching to proceed, to +backtrack, or to fail altogether. A complete description of the interface to +the callout function is given in the .\" HREF \fBpcrecallout\fP .\" @@ -2478,24 +2589,35 @@ remarks apply to the PCRE features described in this section. .P Since these verbs are specifically related to backtracking, most of them can be -used only when the pattern is to be matched using \fBpcre_exec()\fP, which uses -a backtracking algorithm. With the exception of (*FAIL), which behaves like a -failing negative assertion, they cause an error if encountered by -\fBpcre_dfa_exec()\fP. -.P -If any of these verbs are used in an assertion or subroutine subpattern -(including recursive subpatterns), their effect is confined to that subpattern; -it does not extend to the surrounding pattern. Note that such subpatterns are -processed as anchored at the point where they are tested. +used only when the pattern is to be matched using one of the traditional +matching functions, which use a backtracking algorithm. With the exception of +(*FAIL), which behaves like a failing negative assertion, they cause an error +if encountered by a DFA matching function. +.P +If any of these verbs are used in an assertion or in a subpattern that is +called as a subroutine (whether or not recursively), their effect is confined +to that subpattern; it does not extend to the surrounding pattern, with one +exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in +a successful positive assertion \fIis\fP passed back when a match succeeds +(compare capturing parentheses in assertions). Note that such subpatterns are +processed as anchored at the point where they are tested. Note also that Perl's +treatment of subroutines and assertions is different in some cases. .P The new verbs make use of what was previously invalid syntax: an opening parenthesis followed by an asterisk. They are generally of the form (*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour, -depending on whether or not an argument is present. An name is a sequence of -letters, digits, and underscores. If the name is empty, that is, if the closing -parenthesis immediately follows the colon, the effect is as if the colon were -not there. Any number of these verbs may occur in a pattern. -.P +depending on whether or not an argument is present. A name is any sequence of +characters that does not include a closing parenthesis. The maximum length of +name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name +is empty, that is, if the closing parenthesis immediately follows the colon, +the effect is as if the colon were not there. Any number of these verbs may +occur in a pattern. +. +. +.\" HTML +.SS "Optimizations that affect backtracking verbs" +.rs +.sp PCRE contains some optimizations that are used to speed up matching by running some checks at the start of each match attempt. For example, it may know the minimum length of matching subject, or that a particular character must be @@ -2503,7 +2625,20 @@ included backtracking verbs will not, of course, be processed. You can suppress the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the -pattern with (*NO_START_OPT). +pattern with (*NO_START_OPT). There is more discussion of this option in the +section entitled +.\" HTML +.\" +"Option bits for \fBpcre_exec()\fP" +.\" +in the +.\" HREF +\fBpcreapi\fP +.\" +documentation. +.P +Experiments with Perl suggest that it too has similar optimizations, sometimes +leading to anomalous results. . . .SS "Verbs that act immediately" @@ -2515,9 +2650,10 @@ (*ACCEPT) .sp This verb causes the match to end successfully, skipping the remainder of the -pattern. When inside a recursion, only the innermost pattern is ended -immediately. If (*ACCEPT) is inside capturing parentheses, the data so far is -captured. (This feature was added to PCRE at release 8.00.) For example: +pattern. However, when it is inside a subpattern that is called as a +subroutine, only that subpattern is ended successfully. Matching then continues +at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so +far is captured. For example: .sp A((?:A|B(*ACCEPT)|C)D) .sp @@ -2526,7 +2662,7 @@ .sp (*FAIL) or (*F) .sp -This verb causes the match to fail, forcing backtracking to occur. It is +This verb causes a matching failure, forcing backtracking to occur. It is equivalent to (?!) but easier to read. The Perl documentation notes that it is probably useful only when combined with (?{}) or (??{}). Those are, of course, Perl features that are not present in PCRE. The nearest equivalent is the @@ -2550,22 +2686,21 @@ A name is always required with this verb. There may be as many instances of (*MARK) as you like in a pattern, and their names do not have to be unique. .P -When a match succeeds, the name of the last-encountered (*MARK) is passed back -to the caller via the \fIpcre_extra\fP data structure, as described in the +When a match succeeds, the name of the last-encountered (*MARK) on the matching +path is passed back to the caller as described in the section entitled .\" HTML .\" -section on \fIpcre_extra\fP +"Extra data for \fBpcre_exec()\fP" .\" in the .\" HREF \fBpcreapi\fP .\" -documentation. No data is returned for a partial match. Here is an example of -\fBpcretest\fP output, where the /K modifier requests the retrieval and -outputting of (*MARK) data: +documentation. Here is an example of \fBpcretest\fP output, where the /K +modifier requests the retrieval and outputting of (*MARK) data: .sp - /X(*MARK:A)Y|X(*MARK:B)Z/K - XY + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XY 0: XY MK: A XZ @@ -2577,31 +2712,29 @@ of obtaining this information than putting each alternative in its own capturing parentheses. .P -A name may also be returned after a failed match if the final path through the -pattern involves (*MARK). However, unless (*MARK) used in conjunction with -(*COMMIT), this is unlikely to happen for an unanchored pattern because, as the -starting point for matching is advanced, the final check is often with an empty -string, causing a failure before (*MARK) is reached. For example: -.sp - /X(*MARK:A)Y|X(*MARK:B)Z/K - XP - No match -.sp -There are three potential starting points for this match (starting with X, -starting with P, and with an empty string). If the pattern is anchored, the -result is different: +If (*MARK) is encountered in a positive assertion, its name is recorded and +passed back if it is the last-encountered. This does not happen for negative +assertions. +.P +After a partial match or a failed match, the name of the last encountered +(*MARK) in the entire match process is returned. For example: .sp - /^X(*MARK:A)Y|^X(*MARK:B)Z/K - XP + re> /X(*MARK:A)Y|X(*MARK:B)Z/K + data> XP No match, mark = B .sp -PCRE's start-of-match optimizations can also interfere with this. For example, -if, as a result of a call to \fBpcre_study()\fP, it knows the minimum -subject length for a match, a shorter subject will not be scanned at all. -.P -Note that similar anomalies (though different in detail) exist in Perl, no -doubt for the same reasons. The use of (*MARK) data after a failed match of an -unanchored pattern is not recommended, unless (*COMMIT) is involved. +Note that in this unanchored example the mark is retained from the match +attempt that started at the letter "X" in the subject. Subsequent match +attempts starting at "P" and then with an empty string do not get as far as the +(*MARK) item, but nevertheless do not reset it. +.P +If you are interested in (*MARK) values after failed matches, you should +probably set the PCRE_NO_START_OPTIMIZE option +.\" HTML +.\" +(see above) +.\" +to ensure that the match is always attempted. . . .SS "Verbs that act after backtracking" @@ -2638,8 +2771,8 @@ unless PCRE's start-of-match optimizations are turned off, as shown in this \fBpcretest\fP example: .sp - /(*COMMIT)abc/ - xyzabc + re> /(*COMMIT)abc/ + data> xyzabc 0: abc xyzabc\eY No match @@ -2660,10 +2793,8 @@ the right, backtracking cannot cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alternative to an atomic group or possessive quantifier, but there are some uses of (*PRUNE) that cannot be expressed in any other way. -The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the -match fails completely; the name is passed back if this is the final attempt. -(*PRUNE:NAME) does not pass back a name if the match succeeds. In an anchored -pattern (*PRUNE) has the same effect as (*COMMIT). +The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an +anchored pattern (*PRUNE) has the same effect as (*COMMIT). .sp (*SKIP) .sp @@ -2689,41 +2820,75 @@ searched for the most recent (*MARK) that has the same name. If one is found, the "bumpalong" advance is to the subject position that corresponds to that (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a -matching name is found, normal "bumpalong" of one character happens (the -(*SKIP) is ignored). +matching name is found, the (*SKIP) is ignored. .sp (*THEN) or (*THEN:NAME) .sp -This verb causes a skip to the next alternation in the innermost enclosing -group if the rest of the pattern does not match. That is, it cancels pending -backtracking, but only within the current alternation. Its name comes from the -observation that it can be used for a pattern-based if-then-else block: +This verb causes a skip to the next innermost alternative if the rest of the +pattern does not match. That is, it cancels pending backtracking, but only +within the current alternative. Its name comes from the observation that it can +be used for a pattern-based if-then-else block: .sp ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ... .sp If the COND1 pattern matches, FOO is tried (and possibly further items after -the end of the group if FOO succeeds); on failure the matcher skips to the +the end of the group if FOO succeeds); on failure, the matcher skips to the second alternative and tries COND2, without backtracking into COND1. The -behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN) if the -overall match fails. If (*THEN) is not directly inside an alternation, it acts -like (*PRUNE). -. -.P -The above verbs provide four different "strengths" of control when subsequent -matching fails. (*THEN) is the weakest, carrying on the match at the next -alternation. (*PRUNE) comes next, failing the match at the current starting -position, but allowing an advance to the next character (for an unanchored -pattern). (*SKIP) is similar, except that the advance may be more than one -character. (*COMMIT) is the strongest, causing the entire match to fail. +behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN). +If (*THEN) is not inside an alternation, it acts like (*PRUNE). .P -If more than one is present in a pattern, the "stongest" one wins. For example, -consider this pattern, where A, B, etc. are complex pattern fragments: +Note that a subpattern that does not contain a | character is just a part of +the enclosing alternative; it is not a nested alternation with only one +alternative. The effect of (*THEN) extends beyond such a subpattern to the +enclosing alternative. Consider this pattern, where A, B, etc. are complex +pattern fragments that do not contain any | characters at this level: +.sp + A (B(*THEN)C) | D +.sp +If A and B are matched, but there is a failure in C, matching does not +backtrack into A; instead it moves to the next alternative, that is, D. +However, if the subpattern containing (*THEN) is given an alternative, it +behaves differently: +.sp + A (B(*THEN)C | (*FAIL)) | D +.sp +The effect of (*THEN) is now confined to the inner subpattern. After a failure +in C, matching moves to (*FAIL), which causes the whole subpattern to fail +because there are no more alternatives to try. In this case, matching does now +backtrack into A. +.P +Note also that a conditional subpattern is not considered as having two +alternatives, because only one is ever used. In other words, the | character in +a conditional subpattern has a different meaning. Ignoring white space, +consider: +.sp + ^.*? (?(?=a) a | b(*THEN)c ) +.sp +If the subject is "ba", this pattern does not match. Because .*? is ungreedy, +it initially matches zero characters. The condition (?=a) then fails, the +character "b" is matched, but "c" is not. At this point, matching does not +backtrack to .*? as might perhaps be expected from the presence of the | +character. The conditional subpattern is part of the single alternative that +comprises the whole pattern, and so the match fails. (If there was a backtrack +into .*?, allowing it to match "b", the match would succeed.) +.P +The verbs just described provide four different "strengths" of control when +subsequent matching fails. (*THEN) is the weakest, carrying on the match at the +next alternative. (*PRUNE) comes next, failing the match at the current +starting position, but allowing an advance to the next character (for an +unanchored pattern). (*SKIP) is similar, except that the advance may be more +than one character. (*COMMIT) is the strongest, causing the entire match to +fail. +.P +If more than one such verb is present in a pattern, the "strongest" one wins. +For example, consider this pattern, where A, B, etc. are complex pattern +fragments: .sp (A(*COMMIT)B(*THEN)C|D) .sp Once A has matched, PCRE is committed to this match, at the current starting position. If subsequently B matches, but C does not, the normal (*THEN) action -of trying the next alternation (that is, D) does not happen because (*COMMIT) +of trying the next alternative (that is, D) does not happen because (*COMMIT) overrides. . . @@ -2731,7 +2896,7 @@ .rs .sp \fBpcreapi\fP(3), \fBpcrecallout\fP(3), \fBpcrematching\fP(3), -\fBpcresyntax\fP(3), \fBpcre\fP(3). +\fBpcresyntax\fP(3), \fBpcre\fP(3), \fBpcre16(3)\fP. . . .SH AUTHOR @@ -2748,6 +2913,6 @@ .rs .sp .nf -Last updated: 21 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 17 June 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcreperform.3 pcre3-8.31/doc/pcreperform.3 --- pcre3-8.12/doc/pcreperform.3 2010-06-03 19:15:23.000000000 +0000 +++ pcre3-8.31/doc/pcreperform.3 2012-03-31 18:03:11.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREPERFORM 3 +.TH PCREPERFORM 3 "09 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE PERFORMANCE" @@ -11,9 +11,9 @@ .SH "COMPILED PATTERN MEMORY USAGE" .rs .sp -Patterns are compiled by PCRE into a reasonably efficient byte code, so that -most simple patterns do not use much memory. However, there is one case where -the memory usage of a compiled pattern can be unexpectedly large. If a +Patterns are compiled by PCRE into a reasonably efficient interpretive code, so +that most simple patterns do not use much memory. However, there is one case +where the memory usage of a compiled pattern can be unexpectedly large. If a parenthesized subpattern has a quantifier with a minimum greater than 1 and/or a limited maximum, the whole subpattern is repeated in the compiled code. For example, the pattern @@ -34,12 +34,12 @@ .sp ((ab){1,1000}c){1,3} .sp -uses 51K bytes when compiled. When PCRE is compiled with its default internal -pointer size of two bytes, the size limit on a compiled pattern is 64K, and -this is reached with the above pattern if the outer repetition is increased -from 3 to 4. PCRE can be compiled to use larger internal pointers and thus -handle larger compiled patterns, but it is better to try to rewrite your -pattern to use less memory if you can. +uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled +with its default internal pointer size of two bytes, the size limit on a +compiled pattern is 64K data units, and this is reached with the above pattern +if the outer repetition is increased from 3 to 4. PCRE can be compiled to use +larger internal pointers and thus handle larger compiled patterns, but it is +better to try to rewrite your pattern to use less memory if you can. .P One way of reducing the memory usage for such patterns is to make use of PCRE's .\" HTML @@ -68,11 +68,11 @@ .SH "STACK USAGE AT RUN TIME" .rs .sp -When \fBpcre_exec()\fP is used for matching, certain kinds of pattern can cause -it to use large amounts of the process stack. In some environments the default -process stack is quite small, and if it runs out the result is often SIGSEGV. -This issue is probably the most frequently raised problem with PCRE. Rewriting -your pattern can often help. The +When \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used for matching, certain +kinds of pattern can cause it to use large amounts of the process stack. In +some environments the default process stack is quite small, and if it runs out +the result is often SIGSEGV. This issue is probably the most frequently raised +problem with PCRE. Rewriting your pattern can often help. The .\" HREF \fBpcrestack\fP .\" @@ -101,8 +101,9 @@ backwards compatibility, and partly for performance reasons. However, you can set PCRE_UCP if you want Unicode character properties to be used. This can double the matching time for items such as \ed, when matched with -\fBpcre_exec()\fP; the performance loss is less with \fBpcre_dfa_exec()\fP, and -in both cases there is not much difference for \eb. +a traditional matching function; the performance loss is less with +a DFA matching function, and in both cases there is not much difference for +\eb. .P When a pattern begins with .* not in parentheses, or in parentheses that are not the subject of a backreference, and the PCRE_DOTALL option is set, the @@ -172,6 +173,6 @@ .rs .sp .nf -Last updated: 16 May 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 09 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcreposix.3 pcre3-8.31/doc/pcreposix.3 --- pcre3-8.12/doc/pcreposix.3 2010-05-16 18:38:26.000000000 +0000 +++ pcre3-8.31/doc/pcreposix.3 2012-03-31 18:03:27.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREPOSIX 3 +.TH PCREPOSIX 3 "09 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions. .SH "SYNOPSIS OF POSIX API" @@ -24,13 +24,14 @@ .SH DESCRIPTION .rs .sp -This set of functions provides a POSIX-style API to the PCRE regular expression -package. See the +This set of functions provides a POSIX-style API for the PCRE regular +expression 8-bit library. See the .\" HREF \fBpcreapi\fP .\" documentation for a description of PCRE's native API, which contains much -additional functionality. +additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit +library. .P The functions described here are just wrapper functions that ultimately call the PCRE native API. Their prototypes are defined in the \fBpcreposix.h\fP @@ -264,6 +265,6 @@ .rs .sp .nf -Last updated: 16 May 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 09 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcreprecompile.3 pcre3-8.31/doc/pcreprecompile.3 --- pcre3-8.12/doc/pcreprecompile.3 2011-01-11 16:34:02.000000000 +0000 +++ pcre3-8.31/doc/pcreprecompile.3 2012-03-31 18:03:43.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCREPRECOMPILE 3 +.TH PCREPRECOMPILE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "SAVING AND RE-USING PRECOMPILED PCRE PATTERNS" @@ -12,25 +12,31 @@ \fBpcre_maketables()\fP .\" documentation), this is relatively straightforward. If you are using private -tables, it is a little bit more complicated. +tables, it is a little bit more complicated. However, if you are using the +just-in-time optimization feature, it is not possible to save and reload the +JIT data. .P If you save compiled patterns to a file, you can copy them to a different host -and run them there. This works even if the new host has the opposite endianness -to the one on which the patterns were compiled. There may be a small -performance penalty, but it should be insignificant. However, compiling regular -expressions with one version of PCRE for use with a different version is not -guaranteed to work and may cause crashes. +and run them there. If the two hosts have different endianness (byte order), +you should run the \fBpcre[16]_pattern_to_host_byte_order()\fP function on the +new host before trying to match the pattern. The matching functions return +PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness. +.P +Compiling regular expressions with one version of PCRE for use with a different +version is not guaranteed to work and may cause crashes, and saving and +restoring a compiled pattern loses any JIT optimization data. . . .SH "SAVING A COMPILED PATTERN" .rs .sp -The value returned by \fBpcre_compile()\fP points to a single block of memory -that holds the compiled pattern and associated data. You can find the length of -this block in bytes by calling \fBpcre_fullinfo()\fP with an argument of -PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is -sample code that compiles a pattern and writes it to a file. It assumes that -the variable \fIfd\fP refers to a file that is open for output: +The value returned by \fBpcre[16]_compile()\fP points to a single block of +memory that holds the compiled pattern and associated data. You can find the +length of this block in bytes by calling \fBpcre[16]_fullinfo()\fP with an +argument of PCRE_INFO_SIZE. You can then save the data in any appropriate +manner. Here is sample code for the 8-bit library that compiles a pattern and +writes it to a file. It assumes that the variable \fIfd\fP refers to a file +that is open for output: .sp int erroroffset, rc, size; char *error; @@ -58,10 +64,12 @@ some daemon process that passes them via sockets to the processes that want them. .P -If the pattern has been studied, it is also possible to save the study data in -a similar way to the compiled pattern itself. When studying generates -additional information, \fBpcre_study()\fP returns a pointer to a -\fBpcre_extra\fP data block. Its format is defined in the +If the pattern has been studied, it is also possible to save the normal study +data in a similar way to the compiled pattern itself. However, if the +PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot +be saved because it is too dependent on the current environment. When studying +generates additional information, \fBpcre[16]_study()\fP returns a pointer to a +\fBpcre[16]_extra\fP data block. Its format is defined in the .\" HTML .\" section on matching a pattern @@ -71,26 +79,27 @@ \fBpcreapi\fP .\" documentation. The \fIstudy_data\fP field points to the binary study data, and -this is what you must save (not the \fBpcre_extra\fP block itself). The length -of the study data can be obtained by calling \fBpcre_fullinfo()\fP with an -argument of PCRE_INFO_STUDYSIZE. Remember to check that \fBpcre_study()\fP did -return a non-NULL value before trying to save the study data. +this is what you must save (not the \fBpcre[16]_extra\fP block itself). The +length of the study data can be obtained by calling \fBpcre[16]_fullinfo()\fP +with an argument of PCRE_INFO_STUDYSIZE. Remember to check that +\fBpcre[16]_study()\fP did return a non-NULL value before trying to save the +study data. . . .SH "RE-USING A PRECOMPILED PATTERN" .rs .sp Re-using a precompiled pattern is straightforward. Having reloaded it into main -memory, you pass its pointer to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP in -the usual way. This should work even on another host, and even if that host has -the opposite endianness to the one where the pattern was compiled. +memory, called \fBpcre[16]_pattern_to_host_byte_order()\fP if necessary, +you pass its pointer to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP in +the usual way. .P However, if you passed a pointer to custom character tables when the pattern -was compiled (the \fItableptr\fP argument of \fBpcre_compile()\fP), you must -now pass a similar pointer to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, -because the value saved with the compiled pattern will obviously be nonsense. A -field in a \fBpcre_extra()\fP block is used to pass this data, as described in -the +was compiled (the \fItableptr\fP argument of \fBpcre[16]_compile()\fP), you +must now pass a similar pointer to \fBpcre[16]_exec()\fP or +\fBpcre[16]_dfa_exec()\fP, because the value saved with the compiled pattern +will obviously be nonsense. A field in a \fBpcre[16]_extra()\fP block is used +to pass this data, as described in the .\" HTML .\" section on matching a pattern @@ -102,16 +111,17 @@ documentation. .P If you did not provide custom character tables when the pattern was compiled, -the pointer in the compiled pattern is NULL, which causes \fBpcre_exec()\fP to -use PCRE's internal tables. Thus, you do not need to take any special action at -run time in this case. +the pointer in the compiled pattern is NULL, which causes the matching +functions to use PCRE's internal tables. Thus, you do not need to take any +special action at run time in this case. .P If you saved study data with the compiled pattern, you need to create your own -\fBpcre_extra\fP data block and set the \fIstudy_data\fP field to point to the +\fBpcre[16]_extra\fP data block and set the \fIstudy_data\fP field to point to the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the \fIflags\fP field to indicate that study data is present. Then pass the -\fBpcre_extra\fP block to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP in the -usual way. +\fBpcre[16]_extra\fP block to the matching function in the usual way. If the +pattern was studied for just-in-time optimization, that data cannot be saved, +and so is lost by a save/restore cycle. . . .SH "COMPATIBILITY WITH DIFFERENT PCRE RELEASES" @@ -136,6 +146,6 @@ .rs .sp .nf -Last updated: 17 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 10 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcresample.3 pcre3-8.31/doc/pcresample.3 --- pcre3-8.12/doc/pcresample.3 2010-11-17 17:49:27.000000000 +0000 +++ pcre3-8.31/doc/pcresample.3 2012-03-31 18:04:01.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRESAMPLE 3 +.TH PCRESAMPLE 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE SAMPLE PROGRAM" @@ -13,11 +13,12 @@ documentation. If you do not have a copy of the PCRE distribution, you can save this listing to re-create \fIpcredemo.c\fP. .P -The program compiles the regular expression that is its first argument, and -matches it against the subject string in its second argument. No PCRE options -are set, and default character tables are used. If matching succeeds, the -program outputs the portion of the subject that matched, together with the -contents of any captured substrings. +The demonstration program, which uses the original PCRE 8-bit library, compiles +the regular expression that is its first argument, and matches it against the +subject string in its second argument. No PCRE options are set, and default +character tables are used. If matching succeeds, the program outputs the +portion of the subject that matched, together with the contents of any captured +substrings. .P If the -g option is given on the command line, the program then goes on to check for further matches of the same regular expression in the same subject @@ -55,8 +56,8 @@ .\" HREF \fBpcretest\fP, .\" -which supports many more facilities for testing regular expressions and the -PCRE library. The +which supports many more facilities for testing regular expressions and both +PCRE libraries. The .\" HREF \fBpcredemo\fP .\" @@ -93,6 +94,6 @@ .rs .sp .nf -Last updated: 17 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 10 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcrestack.3 pcre3-8.31/doc/pcrestack.3 --- pcre3-8.12/doc/pcrestack.3 2010-01-06 10:20:46.000000000 +0000 +++ pcre3-8.31/doc/pcrestack.3 2012-03-31 18:04:16.000000000 +0000 @@ -1,14 +1,17 @@ -.TH PCRESTACK 3 +.TH PCRESTACK 3 "21 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE DISCUSSION OF STACK USAGE" .rs .sp -When you call \fBpcre_exec()\fP, it makes use of an internal function called -\fBmatch()\fP. This calls itself recursively at branch points in the pattern, -in order to remember the state of the match so that it can back up and try a -different alternative if the first one fails. As matching proceeds deeper and -deeper into the tree of possibilities, the recursion depth increases. +When you call \fBpcre[16]_exec()\fP, it makes use of an internal function +called \fBmatch()\fP. This calls itself recursively at branch points in the +pattern, in order to remember the state of the match so that it can back up and +try a different alternative if the first one fails. As matching proceeds deeper +and deeper into the tree of possibilities, the recursion depth increases. The +\fBmatch()\fP function is also called in other circumstances, for example, +whenever a parenthesized sub-pattern is entered, and in certain cases of +repetition. .P Not all calls of \fBmatch()\fP increase the recursion depth; for an item such as a* it may be called several times at the same level, after matching @@ -16,21 +19,32 @@ the recursive call would immediately be passed back as the result of the current call (a "tail recursion"), the function is just restarted instead. .P -The \fBpcre_dfa_exec()\fP function operates in an entirely different way, and -uses recursion only when there is a regular expression recursion or subroutine -call in the pattern. This includes the processing of assertion and "once-only" -subpatterns, which are handled like subroutine calls. Normally, these are never -very deep, and the limit on the complexity of \fBpcre_dfa_exec()\fP is -controlled by the amount of workspace it is given. However, it is possible to -write patterns with runaway infinite recursions; such patterns will cause -\fBpcre_dfa_exec()\fP to run out of stack. At present, there is no protection -against this. +The above comments apply when \fBpcre[16]_exec()\fP is run in its normal +interpretive manner. If the pattern was studied with the +PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and +the options passed to \fBpcre[16]_exec()\fP were not incompatible, the matching +process uses the JIT-compiled code instead of the \fBmatch()\fP function. In +this case, the memory requirements are handled entirely differently. See the +.\" HREF +\fBpcrejit\fP +.\" +documentation for details. +.P +The \fBpcre[16]_dfa_exec()\fP function operates in an entirely different way, +and uses recursion only when there is a regular expression recursion or +subroutine call in the pattern. This includes the processing of assertion and +"once-only" subpatterns, which are handled like subroutine calls. Normally, +these are never very deep, and the limit on the complexity of +\fBpcre[16]_dfa_exec()\fP is controlled by the amount of workspace it is given. +However, it is possible to write patterns with runaway infinite recursions; +such patterns will cause \fBpcre[16]_dfa_exec()\fP to run out of stack. At +present, there is no protection against this. .P -The comments that follow do NOT apply to \fBpcre_dfa_exec()\fP; they are -relevant only for \fBpcre_exec()\fP. +The comments that follow do NOT apply to \fBpcre[16]_dfa_exec()\fP; they are +relevant only for \fBpcre[16]_exec()\fP without the JIT optimization. . . -.SS "Reducing \fBpcre_exec()\fP's stack usage" +.SS "Reducing \fBpcre[16]_exec()\fP's stack usage" .rs .sp Each time that \fBmatch()\fP is actually called recursively, it uses memory @@ -65,41 +79,42 @@ than one character whenever possible. . . -.SS "Compiling PCRE to use heap instead of stack for \fBpcre_exec()\fP" +.SS "Compiling PCRE to use heap instead of stack for \fBpcre[16]_exec()\fP" .rs .sp In environments where stack memory is constrained, you might want to compile PCRE to use heap memory instead of stack for remembering back-up points when -\fBpcre_exec()\fP is running. This makes it run a lot more slowly, however. +\fBpcre[16]_exec()\fP is running. This makes it run a lot more slowly, however. Details of how to do this are given in the .\" HREF \fBpcrebuild\fP .\" documentation. When built in this way, instead of using the stack, PCRE obtains and frees memory by calling the functions that are pointed to by the -\fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP variables. By default, these -point to \fBmalloc()\fP and \fBfree()\fP, but you can replace the pointers to -cause PCRE to use your own functions. Since the block sizes are always the -same, and are always freed in reverse order, it may be possible to implement -customized memory handlers that are more efficient than the standard functions. +\fBpcre[16]_stack_malloc\fP and \fBpcre[16]_stack_free\fP variables. By +default, these point to \fBmalloc()\fP and \fBfree()\fP, but you can replace +the pointers to cause PCRE to use your own functions. Since the block sizes are +always the same, and are always freed in reverse order, it may be possible to +implement customized memory handlers that are more efficient than the standard +functions. . . -.SS "Limiting \fBpcre_exec()\fP's stack usage" +.SS "Limiting \fBpcre[16]_exec()\fP's stack usage" .rs .sp You can set limits on the number of times that \fBmatch()\fP is called, both in -total and recursively. If a limit is exceeded, \fBpcre_exec()\fP returns an +total and recursively. If a limit is exceeded, \fBpcre[16]_exec()\fP returns an error code. Setting suitable limits should prevent it from running out of stack. The default values of the limits are very large, and unlikely ever to operate. They can be changed when PCRE is built, and they can also be set when -\fBpcre_exec()\fP is called. For details of these interfaces, see the +\fBpcre[16]_exec()\fP is called. For details of these interfaces, see the .\" HREF \fBpcrebuild\fP .\" documentation and the .\" HTML .\" -section on extra data for \fBpcre_exec()\fP +section on extra data for \fBpcre[16]_exec()\fP .\" in the .\" HREF @@ -108,18 +123,43 @@ documentation. .P As a very rough rule of thumb, you should reckon on about 500 bytes per -recursion. Thus, if you want to limit your stack usage to 8Mb, you -should set the limit at 16000 recursions. A 64Mb stack, on the other hand, can -support around 128000 recursions. +recursion. Thus, if you want to limit your stack usage to 8Mb, you should set +the limit at 16000 recursions. A 64Mb stack, on the other hand, can support +around 128000 recursions. .P In Unix-like environments, the \fBpcretest\fP test program has a command line option (\fB-S\fP) that can be used to increase the size of its stack. As long as the stack is large enough, another option (\fB-M\fP) can be used to find the smallest limits that allow a particular pattern to match a given subject -string. This is done by calling \fBpcre_exec()\fP repeatedly with different +string. This is done by calling \fBpcre[16]_exec()\fP repeatedly with different limits. . . +.SS "Obtaining an estimate of stack usage" +.rs +.sp +The actual amount of stack used per recursion can vary quite a lot, depending +on the compiler that was used to build PCRE and the optimization or debugging +options that were set for it. The rule of thumb value of 500 bytes mentioned +above may be larger or smaller than what is actually needed. A better +approximation can be obtained by running this command: +.sp + pcretest -m -C +.sp +The \fB-C\fP option causes \fBpcretest\fP to output information about the +options with which PCRE was compiled. When \fB-m\fP is also given (before +\fB-C\fP), information about stack use is given in a line like this: +.sp + Match recursion uses stack: approximate frame size = 640 bytes +.sp +The value is approximate because some recursions need a bit more (up to perhaps +16 more bytes). +.P +If the above command is given when PCRE is compiled to use the heap instead of +the stack for recursion, the value that is output is the size of each block +that is obtained from the heap. +. +. .SS "Changing stack size in Unix-like systems" .rs .sp @@ -141,7 +181,7 @@ .sp This reads the current limits (soft and hard) using \fBgetrlimit()\fP, then attempts to increase the soft limit to 100Mb using \fBsetrlimit()\fP. You must -do this before calling \fBpcre_exec()\fP. +do this before calling \fBpcre[16]_exec()\fP. . . .SS "Changing stack size in Mac OS X" @@ -170,6 +210,6 @@ .rs .sp .nf -Last updated: 03 January 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 21 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcresyntax.3 pcre3-8.31/doc/pcresyntax.3 --- pcre3-8.12/doc/pcresyntax.3 2010-11-21 17:59:50.000000000 +0000 +++ pcre3-8.31/doc/pcresyntax.3 2012-05-26 14:21:10.000000000 +0000 @@ -1,4 +1,4 @@ -.TH PCRESYNTAX 3 +.TH PCRESYNTAX 3 "10 January 2012" "PCRE 8.30" .SH NAME PCRE - Perl-compatible regular expressions .SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY" @@ -9,8 +9,7 @@ .\" HREF \fBpcrepattern\fP .\" -documentation. This document contains just a quick-reference summary of the -syntax. +documentation. This document contains a quick-reference summary of the syntax. . . .SH "QUOTING" @@ -26,7 +25,7 @@ \ea alarm, that is, the BEL character (hex 07) \ecx "control-x", where x is any ASCII character \ee escape (hex 1B) - \ef formfeed (hex 0C) + \ef form feed (hex 0C) \en newline (hex 0A) \er carriage return (hex 0D) \et tab (hex 09) @@ -40,25 +39,25 @@ .sp . any character except newline; in dotall mode, any character whatsoever - \eC one byte, even in UTF-8 mode (best avoided) + \eC one data unit, even in UTF mode (best avoided) \ed a decimal digit \eD a character that is not a decimal digit - \eh a horizontal whitespace character - \eH a character that is not a horizontal whitespace character + \eh a horizontal white space character + \eH a character that is not a horizontal white space character \eN a character that is not a newline \ep{\fIxx\fP} a character with the \fIxx\fP property \eP{\fIxx\fP} a character without the \fIxx\fP property \eR a newline sequence - \es a whitespace character - \eS a character that is not a whitespace character - \ev a vertical whitespace character - \eV a character that is not a vertical whitespace character + \es a white space character + \eS a character that is not a white space character + \ev a vertical white space character + \eV a character that is not a vertical white space character \ew a "word" character \eW a "non-word" character \eX an extended Unicode sequence .sp In PCRE, by default, \ed, \eD, \es, \eS, \ew, and \eW recognize only ASCII -characters, even in UTF-8 mode. However, this can be changed by setting the +characters, even in a UTF mode. However, this can be changed by setting the PCRE_UCP option. . . @@ -128,13 +127,16 @@ Avestan, Balinese, Bamum, +Batak, Bengali, Bopomofo, +Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, +Chakma, Cham, Cherokee, Common, @@ -177,7 +179,11 @@ Lycian, Lydian, Malayalam, +Mandaic, Meetei_Mayek, +Meroitic_Cursive, +Meroitic_Hieroglyphs, +Miao, Mongolian, Myanmar, New_Tai_Lue, @@ -196,8 +202,10 @@ Runic, Samaritan, Saurashtra, +Sharada, Shavian, Sinhala, +Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac, @@ -206,6 +214,7 @@ Tai_Le, Tai_Tham, Tai_Viet, +Takri, Tamil, Telugu, Thaana, @@ -236,7 +245,7 @@ lower lower case letter print printing, including space punct printing, excluding alphanumeric - space whitespace + space white space upper upper case letter word same as \ew xdigit hexadecimal digit @@ -337,7 +346,8 @@ newline-setting options with similar syntax: .sp (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE) - (*UTF8) set UTF-8 mode (PCRE_UTF8) + (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8) + (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16) (*UCP) set PCRE_UCP (use Unicode properties for \ed etc) . . @@ -411,6 +421,7 @@ .sp (*ACCEPT) force successful match (*FAIL) force backtrack; synonym (*F) + (*MARK:NAME) set name to be passed back; synonym (*:NAME) .sp The following act only when a subsequent match failure causes a backtrack to reach them. They all force a match failure, but they differ in what happens @@ -419,15 +430,19 @@ .sp (*COMMIT) overall failure, no advance of starting point (*PRUNE) advance to next starting character - (*SKIP) advance start to current matching position + (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE) + (*SKIP) advance to current matching position + (*SKIP:NAME) advance to position corresponding to an earlier + (*MARK:NAME); if not found, the (*SKIP) is ignored (*THEN) local failure, backtrack to next alternation + (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN) . . .SH "NEWLINE CONVENTIONS" .rs .sp These are recognized only at the very start of the pattern or after a -(*BSR_...) or (*UTF8) or (*UCP) option. +(*BSR_...), (*UTF8), (*UTF16) or (*UCP) option. .sp (*CR) carriage return only (*LF) linefeed only @@ -440,7 +455,7 @@ .rs .sp These are recognized only at the very start of the pattern or after a -(*...) option that sets the newline convention or UTF-8 or UCP mode. +(*...) option that sets the newline convention or a UTF or UCP mode. .sp (*BSR_ANYCRLF) CR, LF, or CRLF (*BSR_UNICODE) any Unicode newline sequence @@ -474,6 +489,6 @@ .rs .sp .nf -Last updated: 21 November 2010 -Copyright (c) 1997-2010 University of Cambridge. +Last updated: 10 January 2012 +Copyright (c) 1997-2012 University of Cambridge. .fi diff -Nru pcre3-8.12/doc/pcretest.1 pcre3-8.31/doc/pcretest.1 --- pcre3-8.12/doc/pcretest.1 2010-11-24 17:38:33.000000000 +0000 +++ pcre3-8.31/doc/pcretest.1 2012-06-02 10:55:17.000000000 +0000 @@ -1,10 +1,10 @@ -.TH PCRETEST 1 +.TH PCRETEST 1 "21 February 2012" "PCRE 8.31" .SH NAME pcretest - a program for testing Perl-compatible regular expressions. .SH SYNOPSIS .rs .sp -.B pcretest "[options] [source] [destination]" +.B pcretest "[options] [input file [output file]]" .sp \fBpcretest\fP was written as a test program for the PCRE regular expression library itself, but it can also be used for experimenting with regular @@ -18,67 +18,151 @@ .\" HREF \fBpcreapi\fP .\" -documentation. +and +.\" HREF +\fBpcre16\fP +.\" +documentation. The input for \fBpcretest\fP is a sequence of regular expression +patterns and strings to be matched, as described below. The output shows the +result of each match. Options on the command line and the patterns control PCRE +options and exactly what is output. +. +. +.SH "PCRE's 8-BIT and 16-BIT LIBRARIES" +.rs +.sp +From release 8.30, two separate PCRE libraries can be built. The original one +supports 8-bit character strings, whereas the newer 16-bit library supports +character strings encoded in 16-bit units. The \fBpcretest\fP program can be +used to test both libraries. However, it is itself still an 8-bit program, +reading 8-bit input and writing 8-bit output. When testing the 16-bit library, +the patterns and data strings are converted to 16-bit format before being +passed to the PCRE library functions. Results are converted to 8-bit for +output. +.P +References to functions and structures of the form \fBpcre[16]_xx\fP below +mean "\fBpcre_xx\fP when using the 8-bit library or \fBpcre16_xx\fP when using +the 16-bit library". . . -.SH OPTIONS +.SH "COMMAND LINE OPTIONS" .rs .TP 10 +\fB-16\fP +If both the 8-bit and the 16-bit libraries have been built, this option causes +the 16-bit library to be used. If only the 16-bit library has been built, this +is the default (so has no effect). If only the 8-bit library has been built, +this option causes an error. +.TP 10 \fB-b\fP -Behave as if each regex has the \fB/B\fP (show bytecode) modifier; the internal -form is output after compilation. +Behave as if each pattern has the \fB/B\fP (show byte code) modifier; the +internal form is output after compilation. .TP 10 \fB-C\fP Output the version number of the PCRE library, and all available information -about the optional features that are included, and then exit. +about the optional features that are included, and then exit. All other options +are ignored. +.TP 10 +\fB-C\fP \fIoption\fP +Output information about a specific build-time option, then exit. This +functionality is intended for use in scripts such as \fBRunTest\fP. The +following options output the value indicated: +.sp + linksize the internal link size (2, 3, or 4) + newline the default newline setting: + CR, LF, CRLF, ANYCRLF, or ANY +.sp +The following options output 1 for true or zero for false: +.sp + jit just-in-time support is available + pcre16 the 16-bit library was built + pcre8 the 8-bit library was built + ucp Unicode property support is available + utf UTF-8 and/or UTF-16 support is available .TP 10 \fB-d\fP -Behave as if each regex has the \fB/D\fP (debug) modifier; the internal +Behave as if each pattern has the \fB/D\fP (debug) modifier; the internal form and information about the compiled pattern is output after compilation; \fB-d\fP is equivalent to \fB-b -i\fP. .TP 10 \fB-dfa\fP Behave as if each data line contains the \eD escape sequence; this causes the -alternative matching function, \fBpcre_dfa_exec()\fP, to be used instead of the -standard \fBpcre_exec()\fP function (more detail is given below). +alternative matching function, \fBpcre[16]_dfa_exec()\fP, to be used instead of +the standard \fBpcre[16]_exec()\fP function (more detail is given below). .TP 10 \fB-help\fP Output a brief summary these options and then exit. .TP 10 \fB-i\fP -Behave as if each regex has the \fB/I\fP modifier; information about the +Behave as if each pattern has the \fB/I\fP modifier; information about the compiled pattern is given after compilation. .TP 10 \fB-M\fP Behave as if each data line contains the \eM escape sequence; this causes PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by -calling \fBpcre_exec()\fP repeatedly with different limits. +calling \fBpcre[16]_exec()\fP repeatedly with different limits. .TP 10 \fB-m\fP Output the size of each compiled pattern after it has been compiled. This is -equivalent to adding \fB/M\fP to each regular expression. For compatibility -with earlier versions of pcretest, \fB-s\fP is a synonym for \fB-m\fP. +equivalent to adding \fB/M\fP to each regular expression. The size is given in +bytes for both libraries. .TP 10 \fB-o\fP \fIosize\fP Set the number of elements in the output vector that is used when calling -\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP to be \fIosize\fP. The default value -is 45, which is enough for 14 capturing subexpressions for \fBpcre_exec()\fP or -22 different matches for \fBpcre_dfa_exec()\fP. The vector size can be -changed for individual matching calls by including \eO in the data line (see -below). +\fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP to be \fIosize\fP. The +default value is 45, which is enough for 14 capturing subexpressions for +\fBpcre[16]_exec()\fP or 22 different matches for \fBpcre[16]_dfa_exec()\fP. +The vector size can be changed for individual matching calls by including \eO +in the data line (see below). .TP 10 \fB-p\fP -Behave as if each regex has the \fB/P\fP modifier; the POSIX wrapper API is +Behave as if each pattern has the \fB/P\fP modifier; the POSIX wrapper API is used to call PCRE. None of the other options has any effect when \fB-p\fP is -set. +set. This option can be used only with the 8-bit library. .TP 10 \fB-q\fP Do not output the version number of \fBpcretest\fP at the start of execution. .TP 10 \fB-S\fP \fIsize\fP -On Unix-like systems, set the size of the runtime stack to \fIsize\fP +On Unix-like systems, set the size of the run-time stack to \fIsize\fP megabytes. .TP 10 +\fB-s\fP or \fB-s+\fP +Behave as if each pattern has the \fB/S\fP modifier; in other words, force each +pattern to be studied. If \fB-s+\fP is used, all the JIT compile options are +passed to \fBpcre[16]_study()\fP, causing just-in-time optimization to be set +up if it is available, for both full and partial matching. Specific JIT compile +options can be selected by following \fB-s+\fP with a digit in the range 1 to +7, which selects the JIT compile modes as follows: +.sp + 1 normal match only + 2 soft partial match only + 3 normal match and soft partial match + 4 hard partial match only + 6 soft and hard partial match + 7 all three modes (default) +.sp +If \fB-s++\fP is used instead of \fB-s+\fP (with or without a following digit), +the text "(JIT)" is added to the first output line after a match or no match +when JIT-compiled code was actually used. +.P +If the \fB/I\fP or \fB/D\fP option is present on a pattern (requesting output +about the compiled pattern), information about the result of studying is not +included when studying is caused only by \fB-s\fP and neither \fB-i\fP nor +\fB-d\fP is present on the command line. This behaviour means that the output +from tests that are run with and without \fB-s\fP should be identical, except +when options that output information about the actual running of a match are +set. +.sp +The \fB-M\fP, \fB-t\fP, and \fB-tm\fP options, which give information about +resources used, are likely to produce different output with and without +\fB-s\fP. Output may also differ if the \fB/C\fP option is present on an +individual pattern. This uses callouts to trace the the matching process, and +this may be different between studied and non-studied patterns. If the pattern +contains (*MARK) items there may also be differences, for the same reason. The +\fB-s\fP command line option can be overridden for specific patterns that +should never be studied (see the \fB/S\fP pattern modifier below). +.TP 10 \fB-t\fP Run each compile, study, and match many times with a timer, and output resulting time per compile or match (in milliseconds). Do not set \fB-m\fP with @@ -154,13 +238,13 @@ A pattern may be followed by any number of modifiers, which are mostly single characters. Following Perl usage, these are referred to below as, for example, "the \fB/i\fP modifier", even though the delimiter of the pattern need not -always be a slash, and no slash is used when writing modifiers. Whitespace may +always be a slash, and no slash is used when writing modifiers. White space may appear between the final pattern delimiter and the first modifier, and between the modifiers themselves. .P The \fB/i\fP, \fB/m\fP, \fB/s\fP, and \fB/x\fP modifiers set the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when -\fBpcre_compile()\fP is called. These four modifier letters have the same +\fBpcre[16]_compile()\fP is called. These four modifier letters have the same effect as they do in Perl. For example: .sp /caseless/i @@ -168,8 +252,12 @@ The following table shows additional modifiers for setting PCRE compile-time options that do not correspond to anything in Perl: .sp - \fB/8\fP PCRE_UTF8 - \fB/?\fP PCRE_NO_UTF8_CHECK + \fB/8\fP PCRE_UTF8 ) when using the 8-bit + \fB/?\fP PCRE_NO_UTF8_CHECK ) library +.sp + \fB/8\fP PCRE_UTF16 ) when using the 16-bit + \fB/?\fP PCRE_NO_UTF16_CHECK ) library +.sp \fB/A\fP PCRE_ANCHORED \fB/C\fP PCRE_AUTO_CALLOUT \fB/E\fP PCRE_DOLLAR_ENDONLY @@ -190,15 +278,17 @@ \fB/\fP PCRE_BSR_UNICODE .sp The modifiers that are enclosed in angle brackets are literal strings as shown, -including the angle brackets, but the letters can be in either case. This -example sets multiline matching with CRLF as the line ending sequence: +including the angle brackets, but the letters within can be in either case. +This example sets multiline matching with CRLF as the line ending sequence: .sp - /^abc/m + /^abc/m .sp -As well as turning on the PCRE_UTF8 option, the \fB/8\fP modifier also causes -any non-printing characters in output strings to be printed using the -\ex{hh...} notation if they are valid UTF-8 sequences. Full details of the PCRE -options are given in the +As well as turning on the PCRE_UTF8/16 option, the \fB/8\fP modifier causes +all non-printing characters in output strings to be printed using the +\ex{hh...} notation. Otherwise, those less than 0x100 are output in hex without +the curly brackets. +.P +Full details of the PCRE options are given in the .\" HREF \fBpcreapi\fP .\" @@ -212,13 +302,13 @@ by the \fB/g\fP or \fB/G\fP modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The difference between \fB/g\fP and \fB/G\fP is that the former uses the \fIstartoffset\fP argument to -\fBpcre_exec()\fP to start searching at a new point within the entire string -(which is in effect what Perl does), whereas the latter passes over a shortened -substring. This makes a difference to the matching process if the pattern -begins with a lookbehind assertion (including \eb or \eB). +\fBpcre[16]_exec()\fP to start searching at a new point within the entire +string (which is in effect what Perl does), whereas the latter passes over a +shortened substring. This makes a difference to the matching process if the +pattern begins with a lookbehind assertion (including \eb or \eB). .P -If any call to \fBpcre_exec()\fP in a \fB/g\fP or \fB/G\fP sequence matches an -empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and +If any call to \fBpcre[16]_exec()\fP in a \fB/g\fP or \fB/G\fP sequence matches +an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED flags set in order to search for another, non-empty, match at the same point. If this second match fails, the start offset is advanced, and the normal match is retried. This imitates the way Perl handles such cases when @@ -235,42 +325,53 @@ operates. .P The \fB/+\fP modifier requests that as well as outputting the substring that -matched the entire pattern, pcretest should in addition output the remainder of -the subject string. This is useful for tests where the subject contains -multiple copies of the same substring. +matched the entire pattern, \fBpcretest\fP should in addition output the +remainder of the subject string. This is useful for tests where the subject +contains multiple copies of the same substring. If the \fB+\fP modifier appears +twice, the same action is taken for captured substrings. In each case the +remainder is output on the following line with a plus character following the +capture number. Note that this modifier must not immediately follow the /S +modifier because /S+ and /S++ have other meanings. +.P +The \fB/=\fP modifier requests that the values of all potential captured +parentheses be output after a match. By default, only those up to the highest +one actually used in the match are output (corresponding to the return code +from \fBpcre[16]_exec()\fP). Values in the offsets vector corresponding to +higher numbers should be set to -1, and these are output as "". This +modifier gives a way of checking that this is happening. .P The \fB/B\fP modifier is a debugging feature. It requests that \fBpcretest\fP -output a representation of the compiled byte code after compilation. Normally -this information contains length and offset values; however, if \fB/Z\fP is -also present, this data is replaced by spaces. This is a special feature for -use in the automatic test scripts; it ensures that the same output is generated -for different internal link sizes. +output a representation of the compiled code after compilation. Normally this +information contains length and offset values; however, if \fB/Z\fP is also +present, this data is replaced by spaces. This is a special feature for use in +the automatic test scripts; it ensures that the same output is generated for +different internal link sizes. .P The \fB/D\fP modifier is a PCRE debugging feature, and is equivalent to \fB/BI\fP, that is, both the \fB/B\fP and the \fB/I\fP modifiers. .P The \fB/F\fP modifier causes \fBpcretest\fP to flip the byte order of the -fields in the compiled pattern that contain 2-byte and 4-byte numbers. This -facility is for testing the feature in PCRE that allows it to execute patterns -that were compiled on a host with a different endianness. This feature is not -available when the POSIX interface to PCRE is being used, that is, when the -\fB/P\fP pattern modifier is specified. See also the section about saving and -reloading compiled patterns below. +2-byte and 4-byte fields in the compiled pattern. This facility is for testing +the feature in PCRE that allows it to execute patterns that were compiled on a +host with a different endianness. This feature is not available when the POSIX +interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is +specified. See also the section about saving and reloading compiled patterns +below. .P The \fB/I\fP modifier requests that \fBpcretest\fP output information about the compiled pattern (whether it is anchored, has a fixed first character, and -so on). It does this by calling \fBpcre_fullinfo()\fP after compiling a +so on). It does this by calling \fBpcre[16]_fullinfo()\fP after compiling a pattern. If the pattern is studied, the results of that are also output. .P The \fB/K\fP modifier requests \fBpcretest\fP to show names from backtracking -control verbs that are returned from calls to \fBpcre_exec()\fP. It causes -\fBpcretest\fP to create a \fBpcre_extra\fP block if one has not already been -created by a call to \fBpcre_study()\fP, and to set the PCRE_EXTRA_MARK flag -and the \fBmark\fP field within it, every time that \fBpcre_exec()\fP is -called. If the variable that the \fBmark\fP field points to is non-NULL for a -match, non-match, or partial match, \fBpcretest\fP prints the string to which -it points. For a match, this is shown on a line by itself, tagged with "MK:". -For a non-match it is added to the message. +control verbs that are returned from calls to \fBpcre[16]_exec()\fP. It causes +\fBpcretest\fP to create a \fBpcre[16]_extra\fP block if one has not already +been created by a call to \fBpcre[16]_study()\fP, and to set the +PCRE_EXTRA_MARK flag and the \fBmark\fP field within it, every time that +\fBpcre[16]_exec()\fP is called. If the variable that the \fBmark\fP field +points to is non-NULL for a match, non-match, or partial match, \fBpcretest\fP +prints the string to which it points. For a match, this is shown on a line by +itself, tagged with "MK:". For a non-match it is added to the message. .P The \fB/L\fP modifier must be followed directly by the name of a locale, for example, @@ -278,22 +379,58 @@ /pattern/Lfr_FR .sp For this reason, it must be the last modifier. The given locale is set, -\fBpcre_maketables()\fP is called to build a set of character tables for the -locale, and this is then passed to \fBpcre_compile()\fP when compiling the -regular expression. Without an \fB/L\fP (or \fB/T\fP) modifier, NULL is passed -as the tables pointer; that is, \fB/L\fP applies only to the expression on -which it appears. -.P -The \fB/M\fP modifier causes the size of memory block used to hold the compiled -pattern to be output. -.P -The \fB/S\fP modifier causes \fBpcre_study()\fP to be called after the -expression has been compiled, and the results used when the expression is -matched. +\fBpcre[16]_maketables()\fP is called to build a set of character tables for +the locale, and this is then passed to \fBpcre[16]_compile()\fP when compiling +the regular expression. Without an \fB/L\fP (or \fB/T\fP) modifier, NULL is +passed as the tables pointer; that is, \fB/L\fP applies only to the expression +on which it appears. +.P +The \fB/M\fP modifier causes the size in bytes of the memory block used to hold +the compiled pattern to be output. This does not include the size of the +\fBpcre[16]\fP block; it is just the actual compiled data. If the pattern is +successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the +JIT compiled code is also output. +.P +If the \fB/S\fP modifier appears once, it causes \fBpcre[16]_study()\fP to be +called after the expression has been compiled, and the results used when the +expression is matched. If \fB/S\fP appears twice, it suppresses studying, even +if it was requested externally by the \fB-s\fP command line option. This makes +it possible to specify that certain patterns are always studied, and others are +never studied, independently of \fB-s\fP. This feature is used in the test +files in a few cases where the output is different when the pattern is studied. +.P +If the \fB/S\fP modifier is immediately followed by a + character, the call to +\fBpcre[16]_study()\fP is made with all the JIT study options, requesting +just-in-time optimization support if it is available, for both normal and +partial matching. If you want to restrict the JIT compiling modes, you can +follow \fB/S+\fP with a digit in the range 1 to 7: +.sp + 1 normal match only + 2 soft partial match only + 3 normal match and soft partial match + 4 hard partial match only + 6 soft and hard partial match + 7 all three modes (default) +.sp +If \fB/S++\fP is used instead of \fB/S+\fP (with or without a following digit), +the text "(JIT)" is added to the first output line after a match or no match +when JIT-compiled code was actually used. +.P +Note that there is also an independent \fB/+\fP modifier; it must not be given +immediately after \fB/S\fP or \fB/S+\fP because this will be misinterpreted. +.P +If JIT studying is successful, the compiled JIT code will automatically be used +when \fBpcre[16]_exec()\fP is run, except when incompatible run-time options +are specified. For more details, see the +.\" HREF +\fBpcrejit\fP +.\" +documentation. See also the \fB\eJ\fP escape sequence below for a way of +setting the size of the JIT stack. .P The \fB/T\fP modifier must be followed by a single digit. It causes a specific -set of built-in character tables to be passed to \fBpcre_compile()\fP. It is -used in the standard PCRE tests to check behaviour with different character +set of built-in character tables to be passed to \fBpcre[16]_compile()\fP. It +is used in the standard PCRE tests to check behaviour with different character tables. The digit specifies the tables as follows: .sp 0 the default ASCII tables, as distributed in @@ -308,8 +445,9 @@ .rs .sp The \fB/P\fP modifier causes \fBpcretest\fP to call PCRE via the POSIX wrapper -API rather than its native API. When \fB/P\fP is set, the following modifiers -set options for the \fBregcomp()\fP function: +API rather than its native API. This supports only the 8-bit library. When +\fB/P\fP is set, the following modifiers set options for the \fBregcomp()\fP +function: .sp /i REG_ICASE /m REG_NEWLINE @@ -326,9 +464,9 @@ .SH "DATA LINES" .rs .sp -Before each data line is passed to \fBpcre_exec()\fP, leading and trailing -whitespace is removed, and it is then scanned for \e escapes. Some of these are -pretty esoteric features, intended for checking out some of the more +Before each data line is passed to \fBpcre[16]_exec()\fP, leading and trailing +white space is removed, and it is then scanned for \e escapes. Some of these +are pretty esoteric features, intended for checking out some of the more complicated features of PCRE. If you are just testing "ordinary" regular expressions, you probably don't need any of these. The following escapes are recognized: @@ -336,7 +474,7 @@ \ea alarm (BEL, \ex07) \eb backspace (\ex08) \ee escape (\ex27) - \ef formfeed (\ex0c) + \ef form feed (\ex0c) \en newline (\ex0a) .\" JOIN \eqdd set the PCRE_MATCH_LIMIT limit to dd @@ -344,23 +482,21 @@ \er carriage return (\ex0d) \et tab (\ex09) \ev vertical tab (\ex0b) - \ennn octal character (up to 3 octal digits) - always a byte unless > 255 in UTF-8 mode + \ennn octal character (up to 3 octal digits); always + a byte unless > 255 in UTF-8 or 16-bit mode \exhh hexadecimal byte (up to 2 hex digits) + \ex{hh...} hexadecimal character (any number of hex digits) .\" JOIN - \ex{hh...} hexadecimal character, any number of digits - in UTF-8 mode -.\" JOIN - \eA pass the PCRE_ANCHORED option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \eA pass the PCRE_ANCHORED option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \eB pass the PCRE_NOTBOL option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \eB pass the PCRE_NOTBOL option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \eCdd call pcre_copy_substring() for substring dd + \eCdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32) .\" JOIN - \eCname call pcre_copy_named_substring() for substring + \eCname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin- ated by next non alphanumeric character) .\" JOIN @@ -376,72 +512,82 @@ .\" JOIN \eC*n pass the number n (may be negative) as callout data; this is used as the callout return value - \eD use the \fBpcre_dfa_exec()\fP match function - \eF only shortest match for \fBpcre_dfa_exec()\fP + \eD use the \fBpcre[16]_dfa_exec()\fP match function + \eF only shortest match for \fBpcre[16]_dfa_exec()\fP .\" JOIN - \eGdd call pcre_get_substring() for substring dd + \eGdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32) .\" JOIN - \eGname call pcre_get_named_substring() for substring + \eGname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin- ated by next non-alphanumeric character) .\" JOIN - \eL call pcre_get_substringlist() after a + \eJdd set up a JIT stack of dd kilobytes maximum (any + number of digits) +.\" JOIN + \eL call pcre[16]_get_substringlist() after a successful match .\" JOIN \eM discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings .\" JOIN - \eN pass the PCRE_NOTEMPTY option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP; if used twice, pass the + \eN pass the PCRE_NOTEMPTY option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the PCRE_NOTEMPTY_ATSTART option .\" JOIN \eOdd set the size of the output vector passed to - \fBpcre_exec()\fP to dd (any number of digits) + \fBpcre[16]_exec()\fP to dd (any number of digits) .\" JOIN - \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP; if used twice, pass the + \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the PCRE_PARTIAL_HARD option .\" JOIN \eQdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits) - \eR pass the PCRE_DFA_RESTART option to \fBpcre_dfa_exec()\fP + \eR pass the PCRE_DFA_RESTART option to \fBpcre[16]_dfa_exec()\fP \eS output details of memory get/free calls during matching .\" JOIN - \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \eZ pass the PCRE_NOTEOL option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \eZ pass the PCRE_NOTEOL option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e? pass the PCRE_NO_UTF8_CHECK option to - \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP + \e? pass the PCRE_NO_UTF[8|16]_CHECK option to + \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN \e>dd start the match at offset dd (optional "-"; then any number of digits); this sets the \fIstartoffset\fP - argument for \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP + argument for \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e pass the PCRE_NEWLINE_CR option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \e pass the PCRE_NEWLINE_CR option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e pass the PCRE_NEWLINE_LF option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \e pass the PCRE_NEWLINE_LF option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e pass the PCRE_NEWLINE_CRLF option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \e pass the PCRE_NEWLINE_CRLF option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .\" JOIN - \e pass the PCRE_NEWLINE_ANY option to \fBpcre_exec()\fP - or \fBpcre_dfa_exec()\fP + \e pass the PCRE_NEWLINE_ANY option to \fBpcre[16]_exec()\fP + or \fBpcre[16]_dfa_exec()\fP .sp -Note that \exhh always specifies one byte, even in UTF-8 mode; this makes it -possible to construct invalid UTF-8 sequences for testing purposes. On the -other hand, \ex{hh} is interpreted as a UTF-8 character in UTF-8 mode, -generating more than one byte if the value is greater than 127. When not in -UTF-8 mode, it generates one byte for values less than 256, and causes an error -for greater values. +The use of \ex{hh...} is not dependent on the use of the \fB/8\fP modifier on +the pattern. It is recognized always. There may be any number of hexadecimal +digits inside the braces; invalid values provoke error messages. +.P +Note that \exhh specifies one byte rather than one character in UTF-8 mode; +this makes it possible to construct invalid UTF-8 sequences for testing +purposes. On the other hand, \ex{hh} is interpreted as a UTF-8 character in +UTF-8 mode, generating more than one byte if the value is greater than 127. +When testing the 8-bit library not in UTF-8 mode, \ex{hh} generates one byte +for values less than 256, and causes an error for greater values. +.P +In UTF-16 mode, all 4-digit \ex{hhhh} values are accepted. This makes it +possible to construct invalid UTF-16 sequences for testing purposes. .P The escapes that specify line ending sequences are literal strings, exactly as shown. No more than one newline setting should be present in any data line. @@ -451,42 +597,43 @@ passing an empty line as data, since a real empty line terminates the data input. .P -If \eM is present, \fBpcretest\fP calls \fBpcre_exec()\fP several times, with -different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP -fields of the \fBpcre_extra\fP data structure, until it finds the minimum -numbers for each parameter that allow \fBpcre_exec()\fP to complete. The -\fImatch_limit\fP number is a measure of the amount of backtracking that takes -place, and checking it out can be instructive. For most simple matches, the -number is quite small, but for patterns with very large numbers of matching -possibilities, it can become large very quickly with increasing length of -subject string. The \fImatch_limit_recursion\fP number is a measure of how much -stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed -to complete the match attempt. +The \fB\eJ\fP escape provides a way of setting the maximum stack size that is +used by the just-in-time optimization code. It is ignored if JIT optimization +is not being used. Providing a stack that is larger than the default 32K is +necessary only for very complicated patterns. +.P +If \eM is present, \fBpcretest\fP calls \fBpcre[16]_exec()\fP several times, +with different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP +fields of the \fBpcre[16]_extra\fP data structure, until it finds the minimum +numbers for each parameter that allow \fBpcre[16]_exec()\fP to complete without +error. Because this is testing a specific feature of the normal interpretive +\fBpcre[16]_exec()\fP execution, the use of any JIT optimization that might +have been set up by the \fB/S+\fP qualifier of \fB-s+\fP option is disabled. +.P +The \fImatch_limit\fP number is a measure of the amount of backtracking +that takes place, and checking it out can be instructive. For most simple +matches, the number is quite small, but for patterns with very large numbers of +matching possibilities, it can become large very quickly with increasing length +of subject string. The \fImatch_limit_recursion\fP number is a measure of how +much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is +needed to complete the match attempt. .P When \eO is used, the value specified may be higher or lower than the size set by the \fB-O\fP command line option (or defaulted to 45); \eO applies only to -the call of \fBpcre_exec()\fP for the line in which it appears. +the call of \fBpcre[16]_exec()\fP for the line in which it appears. .P If the \fB/P\fP modifier was present on the pattern, causing the POSIX wrapper API to be used, the only option-setting sequences that have any effect are \eB, \eN, and \eZ, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to \fBregexec()\fP. -.P -The use of \ex{hh...} to represent UTF-8 characters is not dependent on the use -of the \fB/8\fP modifier on the pattern. It is recognized always. There may be -any number of hexadecimal digits inside the braces. The result is from one to -six bytes, encoded according to the original UTF-8 rules of RFC 2279. This -allows for values in the range 0 to 0x7FFFFFFF. Note that not all of those are -valid Unicode code points, or indeed valid UTF-8 characters according to the -later rules in RFC 3629. . . .SH "THE ALTERNATIVE MATCHING FUNCTION" .rs .sp By default, \fBpcretest\fP uses the standard PCRE matching function, -\fBpcre_exec()\fP to match each data line. From release 6.0, PCRE supports an -alternative matching function, \fBpcre_dfa_test()\fP, which operates in a +\fBpcre[16]_exec()\fP to match each data line. PCRE also supports an +alternative matching function, \fBpcre[16]_dfa_test()\fP, which operates in a different way, and has some restrictions. The differences between the two functions are described in the .\" HREF @@ -495,7 +642,7 @@ documentation. .P If a data line contains the \eD escape sequence, or if the command line -contains the \fB-dfa\fP option, the alternative matching function is called. +contains the \fB-dfa\fP option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, the \eF escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match. @@ -505,20 +652,23 @@ .rs .sp This section describes the output when the normal matching function, -\fBpcre_exec()\fP, is being used. +\fBpcre[16]_exec()\fP, is being used. .P -When a match succeeds, pcretest outputs the list of captured substrings that -\fBpcre_exec()\fP returns, starting with number 0 for the string that matched -the whole pattern. Otherwise, it outputs "No match" when the return is +When a match succeeds, \fBpcretest\fP outputs the list of captured substrings +that \fBpcre[16]_exec()\fP returns, starting with number 0 for the string that +matched the whole pattern. Otherwise, it outputs "No match" when the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching -substring when \fBpcre_exec()\fP returns PCRE_ERROR_PARTIAL. (Note that this is -the entire substring that was inspected during the partial match; it may -include characters before the actual match start if a lookbehind assertion, -\eK, \eb, or \eB was involved.) For any other returns, it outputs the PCRE -negative error number. Here is an example of an interactive \fBpcretest\fP run. +substring when \fBpcre[16]_exec()\fP returns PCRE_ERROR_PARTIAL. (Note that +this is the entire substring that was inspected during the partial match; it +may include characters before the actual match start if a lookbehind assertion, +\eK, \eb, or \eB was involved.) For any other return, \fBpcretest\fP outputs +the PCRE negative error number and a short descriptive phrase. If the error is +a failed UTF string check, the offset of the start of the failing character and +the reason code are also output, provided that the size of the output vector is +at least two. Here is an example of an interactive \fBpcretest\fP run. .sp $ pcretest - PCRE version 7.0 30-Nov-2006 + PCRE version 8.13 2011-04-30 .sp re> /^abc(\ed+)/ data> abc123 @@ -527,11 +677,11 @@ data> xyz No match .sp -Note that unset capturing substrings that are not followed by one that is set -are not returned by \fBpcre_exec()\fP, and are not shown by \fBpcretest\fP. In -the following example, there are two capturing substrings, but when the first -data line is matched, the second, unset substring is not shown. An "internal" -unset substring is shown as "", as for the second data line. +Unset capturing substrings that are not followed by one that is set are not +returned by \fBpcre[16]_exec()\fP, and are not shown by \fBpcretest\fP. In the +following example, there are two capturing substrings, but when the first data +line is matched, the second, unset substring is not shown. An "internal" unset +substring is shown as "", as for the second data line. .sp re> /(a)|(b)/ data> a @@ -542,11 +692,12 @@ 1: 2: b .sp -If the strings contain any non-printing characters, they are output as \e0x -escapes, or as \ex{...} escapes if the \fB/8\fP modifier was present on the -pattern. See below for the definition of non-printing characters. If the -pattern has the \fB/+\fP modifier, the output for substring 0 is followed by -the the rest of the subject string, identified by "0+" like this: +If the strings contain any non-printing characters, they are output as \exhh +escapes if the value is less than 256 and UTF mode is not set. Otherwise they +are output as \ex{hh...} escapes. See below for the definition of non-printing +characters. If the pattern has the \fB/+\fP modifier, the output for substring +0 is followed by the the rest of the subject string, identified by "0+" like +this: .sp re> /cat/+ data> cataract @@ -565,7 +716,13 @@ 0: ipp 1: pp .sp -"No match" is output only if the first match attempt fails. +"No match" is output only if the first match attempt fails. Here is an example +of a failure message (the offset 4 that is specified by \e>4 is past the end of +the subject string): +.sp + re> /xyz/ + data> xyz\e>4 + Error -24 (bad offset value) .P If any of the sequences \fB\eC\fP, \fB\eG\fP, or \fB\eL\fP are present in a data line that is successfully matched, the substrings extracted by the @@ -584,7 +741,7 @@ .SH "OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION" .rs .sp -When the alternative matching function, \fBpcre_dfa_exec()\fP, is used (by +When the alternative matching function, \fBpcre[16]_dfa_exec()\fP, is used (by means of the \eD escape sequence or the \fB-dfa\fP command line option), the output consists of a list of all the matches that start at the first point in the subject where there is at least one match. For example: @@ -646,15 +803,15 @@ is called during matching. This works with both matching functions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the next pattern item to be -tested. For example, the output +tested. For example: .sp --->pqrabcdef 0 ^ ^ \ed .sp -indicates that callout number 0 occurred for a match attempt starting at the -fourth character of the subject string, when the pointer was at the seventh -character of the data, and when the next pattern item was \ed. Just one -circumflex is output if the start and current positions are the same. +This output indicates that callout number 0 occurred for a match attempt +starting at the fourth character of the subject string, when the pointer was at +the seventh character of the data, and when the next pattern item was \ed. Just +one circumflex is output if the start and current positions are the same. .P Callouts numbered 255 are assumed to be automatic callouts, inserted as a result of the \fB/C\fP pattern modifier. In this case, instead of showing the @@ -670,9 +827,27 @@ +10 ^ ^ 0: E* .sp +If a pattern contains (*MARK) items, an additional line is output whenever +a change of latest mark is passed to the callout function. For example: +.sp + re> /a(*MARK:X)bc/C + data> abc + --->abc + +0 ^ a + +1 ^^ (*MARK:X) + +10 ^^ b + Latest Mark: X + +11 ^ ^ c + +12 ^ ^ + 0: abc +.sp +The mark changes between matching "a" and "b", but stays the same for the rest +of the match, so nothing more is output. If, as a result of backtracking, the +mark reverts to being unset, the text "" is output. +.P The callout function in \fBpcretest\fP returns zero (carry on matching) by default, but you can use a \eC item in a data line (as described above) to -change this. +change this and other parameters of the callout. .P Inserting callouts can be helpful when using \fBpcretest\fP to check complicated regular expressions. For further information about callouts, see @@ -702,7 +877,7 @@ .rs .sp The facilities described in this section are not available when the POSIX -inteface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is +interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is specified. .P When the POSIX interface is not in use, you can cause \fBpcretest\fP to write a @@ -716,6 +891,8 @@ \fBpcreprecompile\fP .\" documentation for a discussion about saving and re-using compiled patterns. +Note that if the pattern was successfully studied with JIT optimization, the +JIT data cannot be saved. .P The data that is written is binary. The first eight bytes are the length of the compiled pattern data followed by the length of the optional study data, each @@ -723,26 +900,35 @@ there is no study data (either the pattern was not studied, or studying did not return any data), the second length is zero. The lengths are followed by an exact copy of the compiled pattern. If there is additional study data, this -follows immediately after the compiled pattern. After writing the file, -\fBpcretest\fP expects to read a new pattern. +(excluding any JIT data) follows immediately after the compiled pattern. After +writing the file, \fBpcretest\fP expects to read a new pattern. .P -A saved pattern can be reloaded into \fBpcretest\fP by specifing < and a file +A saved pattern can be reloaded into \fBpcretest\fP by specifying < and a file name instead of a pattern. The name of the file must not contain a < character, as otherwise \fBpcretest\fP will interpret the line as a pattern delimited by < characters. For example: .sp re> PCRE_BSR_UNICODE The modifiers that are enclosed in angle brackets are literal strings - as shown, including the angle brackets, but the letters can be in - either case. This example sets multiline matching with CRLF as the line - ending sequence: - - /^abc/m - - As well as turning on the PCRE_UTF8 option, the /8 modifier also causes - any non-printing characters in output strings to be printed using the - \x{hh...} notation if they are valid UTF-8 sequences. Full details of - the PCRE options are given in the pcreapi documentation. + as shown, including the angle brackets, but the letters within can be + in either case. This example sets multiline matching with CRLF as the + line ending sequence: + + /^abc/m + + As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes + all non-printing characters in output strings to be printed using the + \x{hh...} notation. Otherwise, those less than 0x100 are output in hex + without the curly brackets. + + Full details of the PCRE options are given in the pcreapi documenta- + tion. Finding all matches in a string - Searching for all possible matches within each subject string can be - requested by the /g or /G modifier. After finding a match, PCRE is + Searching for all possible matches within each subject string can be + requested by the /g or /G modifier. After finding a match, PCRE is called again to search the remainder of the subject string. The differ- ence between /g and /G is that the former uses the startoffset argument - to pcre_exec() to start searching at a new point within the entire - string (which is in effect what Perl does), whereas the latter passes - over a shortened substring. This makes a difference to the matching + to pcre[16]_exec() to start searching at a new point within the entire + string (which is in effect what Perl does), whereas the latter passes + over a shortened substring. This makes a difference to the matching process if the pattern begins with a lookbehind assertion (including \b or \B). - If any call to pcre_exec() in a /g or /G sequence matches an empty - string, the next call is done with the PCRE_NOTEMPTY_ATSTART and - PCRE_ANCHORED flags set in order to search for another, non-empty, - match at the same point. If this second match fails, the start offset - is advanced, and the normal match is retried. This imitates the way + If any call to pcre[16]_exec() in a /g or /G sequence matches an empty + string, the next call is done with the PCRE_NOTEMPTY_ATSTART and + PCRE_ANCHORED flags set in order to search for another, non-empty, + match at the same point. If this second match fails, the start offset + is advanced, and the normal match is retried. This imitates the way Perl handles such cases when using the /g modifier or the split() func- - tion. Normally, the start offset is advanced by one character, but if - the newline convention recognizes CRLF as a newline, and the current + tion. Normally, the start offset is advanced by one character, but if + the newline convention recognizes CRLF as a newline, and the current character is CR followed by LF, an advance of two is used. Other modifiers There are yet more modifiers for controlling the way pcretest operates. - The /+ modifier requests that as well as outputting the substring that - matched the entire pattern, pcretest should in addition output the - remainder of the subject string. This is useful for tests where the - subject contains multiple copies of the same substring. + The /+ modifier requests that as well as outputting the substring that + matched the entire pattern, pcretest should in addition output the + remainder of the subject string. This is useful for tests where the + subject contains multiple copies of the same substring. If the + modi- + fier appears twice, the same action is taken for captured substrings. + In each case the remainder is output on the following line with a plus + character following the capture number. Note that this modifier must + not immediately follow the /S modifier because /S+ and /S++ have other + meanings. + + The /= modifier requests that the values of all potential captured + parentheses be output after a match. By default, only those up to the + highest one actually used in the match are output (corresponding to the + return code from pcre[16]_exec()). Values in the offsets vector corre- + sponding to higher numbers should be set to -1, and these are output as + "". This modifier gives a way of checking that this is happen- + ing. The /B modifier is a debugging feature. It requests that pcretest out- - put a representation of the compiled byte code after compilation. Nor- - mally this information contains length and offset values; however, if - /Z is also present, this data is replaced by spaces. This is a special - feature for use in the automatic test scripts; it ensures that the same + put a representation of the compiled code after compilation. Normally + this information contains length and offset values; however, if /Z is + also present, this data is replaced by spaces. This is a special fea- + ture for use in the automatic test scripts; it ensures that the same output is generated for different internal link sizes. The /D modifier is a PCRE debugging feature, and is equivalent to /BI, that is, both the /B and the /I modifiers. - The /F modifier causes pcretest to flip the byte order of the fields in - the compiled pattern that contain 2-byte and 4-byte numbers. This - facility is for testing the feature in PCRE that allows it to execute - patterns that were compiled on a host with a different endianness. This - feature is not available when the POSIX interface to PCRE is being - used, that is, when the /P pattern modifier is specified. See also the - section about saving and reloading compiled patterns below. + The /F modifier causes pcretest to flip the byte order of the 2-byte + and 4-byte fields in the compiled pattern. This facility is for testing + the feature in PCRE that allows it to execute patterns that were com- + piled on a host with a different endianness. This feature is not avail- + able when the POSIX interface to PCRE is being used, that is, when the + /P pattern modifier is specified. See also the section about saving and + reloading compiled patterns below. The /I modifier requests that pcretest output information about the compiled pattern (whether it is anchored, has a fixed first character, - and so on). It does this by calling pcre_fullinfo() after compiling a - pattern. If the pattern is studied, the results of that are also out- + and so on). It does this by calling pcre[16]_fullinfo() after compiling + a pattern. If the pattern is studied, the results of that are also out- put. The /K modifier requests pcretest to show names from backtracking con- - trol verbs that are returned from calls to pcre_exec(). It causes - pcretest to create a pcre_extra block if one has not already been cre- - ated by a call to pcre_study(), and to set the PCRE_EXTRA_MARK flag and - the mark field within it, every time that pcre_exec() is called. If the - variable that the mark field points to is non-NULL for a match, non- - match, or partial match, pcretest prints the string to which it points. - For a match, this is shown on a line by itself, tagged with "MK:". For - a non-match it is added to the message. + trol verbs that are returned from calls to pcre[16]_exec(). It causes + pcretest to create a pcre[16]_extra block if one has not already been + created by a call to pcre[16]_study(), and to set the PCRE_EXTRA_MARK + flag and the mark field within it, every time that pcre[16]_exec() is + called. If the variable that the mark field points to is non-NULL for a + match, non-match, or partial match, pcretest prints the string to which + it points. For a match, this is shown on a line by itself, tagged with + "MK:". For a non-match it is added to the message. The /L modifier must be followed directly by the name of a locale, for example, @@ -261,22 +361,57 @@ /pattern/Lfr_FR For this reason, it must be the last modifier. The given locale is set, - pcre_maketables() is called to build a set of character tables for the - locale, and this is then passed to pcre_compile() when compiling the - regular expression. Without an /L (or /T) modifier, NULL is passed as - the tables pointer; that is, /L applies only to the expression on which - it appears. - - The /M modifier causes the size of memory block used to hold the com- - piled pattern to be output. - - The /S modifier causes pcre_study() to be called after the expression - has been compiled, and the results used when the expression is matched. + pcre[16]_maketables() is called to build a set of character tables for + the locale, and this is then passed to pcre[16]_compile() when compil- + ing the regular expression. Without an /L (or /T) modifier, NULL is + passed as the tables pointer; that is, /L applies only to the expres- + sion on which it appears. + + The /M modifier causes the size in bytes of the memory block used to + hold the compiled pattern to be output. This does not include the size + of the pcre[16] block; it is just the actual compiled data. If the pat- + tern is successfully studied with the PCRE_STUDY_JIT_COMPILE option, + the size of the JIT compiled code is also output. + + If the /S modifier appears once, it causes pcre[16]_study() to be + called after the expression has been compiled, and the results used + when the expression is matched. If /S appears twice, it suppresses + studying, even if it was requested externally by the -s command line + option. This makes it possible to specify that certain patterns are + always studied, and others are never studied, independently of -s. This + feature is used in the test files in a few cases where the output is + different when the pattern is studied. + + If the /S modifier is immediately followed by a + character, the call + to pcre[16]_study() is made with all the JIT study options, requesting + just-in-time optimization support if it is available, for both normal + and partial matching. If you want to restrict the JIT compiling modes, + you can follow /S+ with a digit in the range 1 to 7: + + 1 normal match only + 2 soft partial match only + 3 normal match and soft partial match + 4 hard partial match only + 6 soft and hard partial match + 7 all three modes (default) + + If /S++ is used instead of /S+ (with or without a following digit), the + text "(JIT)" is added to the first output line after a match or no + match when JIT-compiled code was actually used. + + Note that there is also an independent /+ modifier; it must not be + given immediately after /S or /S+ because this will be misinterpreted. + + If JIT studying is successful, the compiled JIT code will automatically + be used when pcre[16]_exec() is run, except when incompatible run-time + options are specified. For more details, see the pcrejit documentation. + See also the \J escape sequence below for a way of setting the size of + the JIT stack. The /T modifier must be followed by a single digit. It causes a spe- - cific set of built-in character tables to be passed to pcre_compile(). - It is used in the standard PCRE tests to check behaviour with different - character tables. The digit specifies the tables as follows: + cific set of built-in character tables to be passed to pcre[16]_com- + pile(). It is used in the standard PCRE tests to check behaviour with + different character tables. The digit specifies the tables as follows: 0 the default ASCII tables, as distributed in pcre_chartables.c.dist @@ -288,8 +423,9 @@ Using the POSIX wrapper API The /P modifier causes pcretest to call PCRE via the POSIX wrapper API - rather than its native API. When /P is set, the following modifiers set - options for the regcomp() function: + rather than its native API. This supports only the 8-bit library. When + /P is set, the following modifiers set options for the regcomp() func- + tion: /i REG_ICASE /m REG_NEWLINE @@ -299,41 +435,40 @@ /W REG_UCP ) the POSIX standard /8 REG_UTF8 ) - The /+ modifier works as described above. All other modifiers are + The /+ modifier works as described above. All other modifiers are ignored. DATA LINES - Before each data line is passed to pcre_exec(), leading and trailing - whitespace is removed, and it is then scanned for \ escapes. Some of - these are pretty esoteric features, intended for checking out some of - the more complicated features of PCRE. If you are just testing "ordi- - nary" regular expressions, you probably don't need any of these. The - following escapes are recognized: + Before each data line is passed to pcre[16]_exec(), leading and trail- + ing white space is removed, and it is then scanned for \ escapes. Some + of these are pretty esoteric features, intended for checking out some + of the more complicated features of PCRE. If you are just testing + "ordinary" regular expressions, you probably don't need any of these. + The following escapes are recognized: \a alarm (BEL, \x07) \b backspace (\x08) \e escape (\x27) - \f formfeed (\x0c) + \f form feed (\x0c) \n newline (\x0a) \qdd set the PCRE_MATCH_LIMIT limit to dd (any number of digits) \r carriage return (\x0d) \t tab (\x09) \v vertical tab (\x0b) - \nnn octal character (up to 3 octal digits) - always a byte unless > 255 in UTF-8 mode + \nnn octal character (up to 3 octal digits); always + a byte unless > 255 in UTF-8 or 16-bit mode \xhh hexadecimal byte (up to 2 hex digits) - \x{hh...} hexadecimal character, any number of digits - in UTF-8 mode - \A pass the PCRE_ANCHORED option to pcre_exec() - or pcre_dfa_exec() - \B pass the PCRE_NOTBOL option to pcre_exec() - or pcre_dfa_exec() - \Cdd call pcre_copy_substring() for substring dd + \x{hh...} hexadecimal character (any number of hex digits) + \A pass the PCRE_ANCHORED option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \B pass the PCRE_NOTBOL option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \Cdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32) - \Cname call pcre_copy_named_substring() for substring + \Cname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin- ated by next non alphanumeric character) \C+ show the current captured substrings at callout @@ -345,55 +480,66 @@ reached for the nth time \C*n pass the number n (may be negative) as callout data; this is used as the callout return value - \D use the pcre_dfa_exec() match function - \F only shortest match for pcre_dfa_exec() - \Gdd call pcre_get_substring() for substring dd + \D use the pcre[16]_dfa_exec() match function + \F only shortest match for pcre[16]_dfa_exec() + \Gdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32) - \Gname call pcre_get_named_substring() for substring + \Gname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin- ated by next non-alphanumeric character) - \L call pcre_get_substringlist() after a + \Jdd set up a JIT stack of dd kilobytes maximum (any + number of digits) + \L call pcre[16]_get_substringlist() after a successful match \M discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings - \N pass the PCRE_NOTEMPTY option to pcre_exec() - or pcre_dfa_exec(); if used twice, pass the + \N pass the PCRE_NOTEMPTY option to pcre[16]_exec() + or pcre[16]_dfa_exec(); if used twice, pass the PCRE_NOTEMPTY_ATSTART option \Odd set the size of the output vector passed to - pcre_exec() to dd (any number of digits) - \P pass the PCRE_PARTIAL_SOFT option to pcre_exec() - or pcre_dfa_exec(); if used twice, pass the + pcre[16]_exec() to dd (any number of digits) + \P pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec() + or pcre[16]_dfa_exec(); if used twice, pass the PCRE_PARTIAL_HARD option \Qdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits) - \R pass the PCRE_DFA_RESTART option to pcre_dfa_exec() + \R pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec() \S output details of memory get/free calls during matching - \Y pass the PCRE_NO_START_OPTIMIZE option to pcre_exec() - or pcre_dfa_exec() - \Z pass the PCRE_NOTEOL option to pcre_exec() - or pcre_dfa_exec() - \? pass the PCRE_NO_UTF8_CHECK option to - pcre_exec() or pcre_dfa_exec() + \Y pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \Z pass the PCRE_NOTEOL option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \? pass the PCRE_NO_UTF[8|16]_CHECK option to + pcre[16]_exec() or pcre[16]_dfa_exec() \>dd start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset - argument for pcre_exec() or pcre_dfa_exec() - \ pass the PCRE_NEWLINE_CR option to pcre_exec() - or pcre_dfa_exec() - \ pass the PCRE_NEWLINE_LF option to pcre_exec() - or pcre_dfa_exec() - \ pass the PCRE_NEWLINE_CRLF option to pcre_exec() - or pcre_dfa_exec() - \ pass the PCRE_NEWLINE_ANYCRLF option to pcre_exec() - or pcre_dfa_exec() - \ pass the PCRE_NEWLINE_ANY option to pcre_exec() - or pcre_dfa_exec() - - Note that \xhh always specifies one byte, even in UTF-8 mode; this - makes it possible to construct invalid UTF-8 sequences for testing pur- - poses. On the other hand, \x{hh} is interpreted as a UTF-8 character in - UTF-8 mode, generating more than one byte if the value is greater than - 127. When not in UTF-8 mode, it generates one byte for values less than - 256, and causes an error for greater values. + argument for pcre[16]_exec() or pcre[16]_dfa_exec() + \ pass the PCRE_NEWLINE_CR option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \ pass the PCRE_NEWLINE_LF option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \ pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \ pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec() + or pcre[16]_dfa_exec() + \ pass the PCRE_NEWLINE_ANY option to pcre[16]_exec() + or pcre[16]_dfa_exec() + + The use of \x{hh...} is not dependent on the use of the /8 modifier on + the pattern. It is recognized always. There may be any number of hexa- + decimal digits inside the braces; invalid values provoke error mes- + sages. + + Note that \xhh specifies one byte rather than one character in UTF-8 + mode; this makes it possible to construct invalid UTF-8 sequences for + testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8 + character in UTF-8 mode, generating more than one byte if the value is + greater than 127. When testing the 8-bit library not in UTF-8 mode, + \x{hh} generates one byte for values less than 256, and causes an error + for greater values. + + In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it + possible to construct invalid UTF-16 sequences for testing purposes. The escapes that specify line ending sequences are literal strings, exactly as shown. No more than one newline setting should be present in @@ -404,70 +550,75 @@ way of passing an empty line as data, since a real empty line termi- nates the data input. - If \M is present, pcretest calls pcre_exec() several times, with dif- - ferent values in the match_limit and match_limit_recursion fields of - the pcre_extra data structure, until it finds the minimum numbers for - each parameter that allow pcre_exec() to complete. The match_limit num- - ber is a measure of the amount of backtracking that takes place, and - checking it out can be instructive. For most simple matches, the number - is quite small, but for patterns with very large numbers of matching - possibilities, it can become large very quickly with increasing length - of subject string. The match_limit_recursion number is a measure of how - much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) - memory is needed to complete the match attempt. + The \J escape provides a way of setting the maximum stack size that is + used by the just-in-time optimization code. It is ignored if JIT opti- + mization is not being used. Providing a stack that is larger than the + default 32K is necessary only for very complicated patterns. + + If \M is present, pcretest calls pcre[16]_exec() several times, with + different values in the match_limit and match_limit_recursion fields of + the pcre[16]_extra data structure, until it finds the minimum numbers + for each parameter that allow pcre[16]_exec() to complete without + error. Because this is testing a specific feature of the normal inter- + pretive pcre[16]_exec() execution, the use of any JIT optimization that + might have been set up by the /S+ qualifier of -s+ option is disabled. + + The match_limit number is a measure of the amount of backtracking that + takes place, and checking it out can be instructive. For most simple + matches, the number is quite small, but for patterns with very large + numbers of matching possibilities, it can become large very quickly + with increasing length of subject string. The match_limit_recursion + number is a measure of how much stack (or, if PCRE is compiled with + NO_RECURSE, how much heap) memory is needed to complete the match + attempt. When \O is used, the value specified may be higher or lower than the size set by the -O command line option (or defaulted to 45); \O applies - only to the call of pcre_exec() for the line in which it appears. + only to the call of pcre[16]_exec() for the line in which it appears. If the /P modifier was present on the pattern, causing the POSIX wrap- per API to be used, the only option-setting sequences that have any effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively, to be passed to regexec(). - The use of \x{hh...} to represent UTF-8 characters is not dependent on - the use of the /8 modifier on the pattern. It is recognized always. - There may be any number of hexadecimal digits inside the braces. The - result is from one to six bytes, encoded according to the original - UTF-8 rules of RFC 2279. This allows for values in the range 0 to - 0x7FFFFFFF. Note that not all of those are valid Unicode code points, - or indeed valid UTF-8 characters according to the later rules in RFC - 3629. - THE ALTERNATIVE MATCHING FUNCTION - By default, pcretest uses the standard PCRE matching function, - pcre_exec() to match each data line. From release 6.0, PCRE supports an - alternative matching function, pcre_dfa_test(), which operates in a - different way, and has some restrictions. The differences between the - two functions are described in the pcrematching documentation. + By default, pcretest uses the standard PCRE matching function, + pcre[16]_exec() to match each data line. PCRE also supports an alterna- + tive matching function, pcre[16]_dfa_test(), which operates in a dif- + ferent way, and has some restrictions. The differences between the two + functions are described in the pcrematching documentation. - If a data line contains the \D escape sequence, or if the command line - contains the -dfa option, the alternative matching function is called. + If a data line contains the \D escape sequence, or if the command line + contains the -dfa option, the alternative matching function is used. This function finds all possible matches at a given point. If, however, - the \F escape sequence is present in the data line, it stops after the + the \F escape sequence is present in the data line, it stops after the first match is found. This is always the shortest possible match. DEFAULT OUTPUT FROM PCRETEST - This section describes the output when the normal matching function, - pcre_exec(), is being used. + This section describes the output when the normal matching function, + pcre[16]_exec(), is being used. When a match succeeds, pcretest outputs the list of captured substrings - that pcre_exec() returns, starting with number 0 for the string that - matched the whole pattern. Otherwise, it outputs "No match" when the - return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the par- - tially matching substring when pcre_exec() returns PCRE_ERROR_PARTIAL. - (Note that this is the entire substring that was inspected during the - partial match; it may include characters before the actual match start - if a lookbehind assertion, \K, \b, or \B was involved.) For any other - returns, it outputs the PCRE negative error number. Here is an example - of an interactive pcretest run. + that pcre[16]_exec() returns, starting with number 0 for the string + that matched the whole pattern. Otherwise, it outputs "No match" when + the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the + partially matching substring when pcre[16]_exec() returns + PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was + inspected during the partial match; it may include characters before + the actual match start if a lookbehind assertion, \K, \b, or \B was + involved.) For any other return, pcretest outputs the PCRE negative + error number and a short descriptive phrase. If the error is a failed + UTF string check, the offset of the start of the failing character and + the reason code are also output, provided that the size of the output + vector is at least two. Here is an example of an interactive pcretest + run. $ pcretest - PCRE version 7.0 30-Nov-2006 + PCRE version 8.13 2011-04-30 re> /^abc(\d+)/ data> abc123 @@ -476,12 +627,12 @@ data> xyz No match - Note that unset capturing substrings that are not followed by one that - is set are not returned by pcre_exec(), and are not shown by pcretest. - In the following example, there are two capturing substrings, but when - the first data line is matched, the second, unset substring is not - shown. An "internal" unset substring is shown as "", as for the - second data line. + Unset capturing substrings that are not followed by one that is set are + not returned by pcre[16]_exec(), and are not shown by pcretest. In the + following example, there are two capturing substrings, but when the + first data line is matched, the second, unset substring is not shown. + An "internal" unset substring is shown as "", as for the second + data line. re> /(a)|(b)/ data> a @@ -492,19 +643,19 @@ 1: 2: b - If the strings contain any non-printing characters, they are output as - \0x escapes, or as \x{...} escapes if the /8 modifier was present on - the pattern. See below for the definition of non-printing characters. - If the pattern has the /+ modifier, the output for substring 0 is fol- - lowed by the the rest of the subject string, identified by "0+" like - this: + If the strings contain any non-printing characters, they are output as + \xhh escapes if the value is less than 256 and UTF mode is not set. + Otherwise they are output as \x{hh...} escapes. See below for the defi- + nition of non-printing characters. If the pattern has the /+ modifier, + the output for substring 0 is followed by the the rest of the subject + string, identified by "0+" like this: re> /cat/+ data> cataract 0: cat 0+ aract - If the pattern has the /g or /G modifier, the results of successive + If the pattern has the /g or /G modifier, the results of successive matching attempts are output in sequence, like this: re> /\Bi(\w\w)/g @@ -516,27 +667,34 @@ 0: ipp 1: pp - "No match" is output only if the first match attempt fails. + "No match" is output only if the first match attempt fails. Here is an + example of a failure message (the offset 4 that is specified by \>4 is + past the end of the subject string): + + re> /xyz/ + data> xyz\>4 + Error -24 (bad offset value) - If any of the sequences \C, \G, or \L are present in a data line that - is successfully matched, the substrings extracted by the convenience + If any of the sequences \C, \G, or \L are present in a data line that + is successfully matched, the substrings extracted by the convenience functions are output with C, G, or L after the string number instead of a colon. This is in addition to the normal full list. The string length - (that is, the return from the extraction function) is given in paren- + (that is, the return from the extraction function) is given in paren- theses after each string for \C and \G. Note that whereas patterns can be continued over several lines (a plain ">" prompt is used for continuations), data lines may not. However new- - lines can be included in data by means of the \n escape (or \r, \r\n, + lines can be included in data by means of the \n escape (or \r, \r\n, etc., depending on the newline sequence setting). OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION - When the alternative matching function, pcre_dfa_exec(), is used (by - means of the \D escape sequence or the -dfa command line option), the - output consists of a list of all the matches that start at the first - point in the subject where there is at least one match. For example: + When the alternative matching function, pcre[16]_dfa_exec(), is used + (by means of the \D escape sequence or the -dfa command line option), + the output consists of a list of all the matches that start at the + first point in the subject where there is at least one match. For exam- + ple: re> /(tang|tangerine|tan)/ data> yellow tangerine\D @@ -592,16 +750,16 @@ tion is called during matching. This works with both matching func- tions. By default, the called function displays the callout number, the start and current positions in the text at the callout time, and the - next pattern item to be tested. For example, the output + next pattern item to be tested. For example: --->pqrabcdef 0 ^ ^ \d - indicates that callout number 0 occurred for a match attempt starting - at the fourth character of the subject string, when the pointer was at - the seventh character of the data, and when the next pattern item was - \d. Just one circumflex is output if the start and current positions - are the same. + This output indicates that callout number 0 occurred for a match + attempt starting at the fourth character of the subject string, when + the pointer was at the seventh character of the data, and when the next + pattern item was \d. Just one circumflex is output if the start and + current positions are the same. Callouts numbered 255 are assumed to be automatic callouts, inserted as a result of the /C pattern modifier. In this case, instead of showing @@ -617,41 +775,62 @@ +10 ^ ^ 0: E* - The callout function in pcretest returns zero (carry on matching) by - default, but you can use a \C item in a data line (as described above) - to change this. + If a pattern contains (*MARK) items, an additional line is output when- + ever a change of latest mark is passed to the callout function. For + example: + + re> /a(*MARK:X)bc/C + data> abc + --->abc + +0 ^ a + +1 ^^ (*MARK:X) + +10 ^^ b + Latest Mark: X + +11 ^ ^ c + +12 ^ ^ + 0: abc + + The mark changes between matching "a" and "b", but stays the same for + the rest of the match, so nothing more is output. If, as a result of + backtracking, the mark reverts to being unset, the text "" is + output. + + The callout function in pcretest returns zero (carry on matching) by + default, but you can use a \C item in a data line (as described above) + to change this and other parameters of the callout. - Inserting callouts can be helpful when using pcretest to check compli- - cated regular expressions. For further information about callouts, see + Inserting callouts can be helpful when using pcretest to check compli- + cated regular expressions. For further information about callouts, see the pcrecallout documentation. NON-PRINTING CHARACTERS - When pcretest is outputting text in the compiled version of a pattern, - bytes other than 32-126 are always treated as non-printing characters + When pcretest is outputting text in the compiled version of a pattern, + bytes other than 32-126 are always treated as non-printing characters are are therefore shown as hex escapes. - When pcretest is outputting text that is a matched part of a subject - string, it behaves in the same way, unless a different locale has been - set for the pattern (using the /L modifier). In this case, the + When pcretest is outputting text that is a matched part of a subject + string, it behaves in the same way, unless a different locale has been + set for the pattern (using the /L modifier). In this case, the isprint() function to distinguish printing and non-printing characters. SAVING AND RELOADING COMPILED PATTERNS - The facilities described in this section are not available when the - POSIX inteface to PCRE is being used, that is, when the /P pattern mod- - ifier is specified. + The facilities described in this section are not available when the + POSIX interface to PCRE is being used, that is, when the /P pattern + modifier is specified. When the POSIX interface is not in use, you can cause pcretest to write - a compiled pattern to a file, by following the modifiers with > and a + a compiled pattern to a file, by following the modifiers with > and a file name. For example: /pattern/im >/some/file - See the pcreprecompile documentation for a discussion about saving and - re-using compiled patterns. + See the pcreprecompile documentation for a discussion about saving and + re-using compiled patterns. Note that if the pattern was successfully + studied with JIT optimization, the JIT data cannot be saved. The data that is written is binary. The first eight bytes are the length of the compiled pattern data followed by the length of the @@ -659,45 +838,56 @@ (most significant byte first). If there is no study data (either the pattern was not studied, or studying did not return any data), the sec- ond length is zero. The lengths are followed by an exact copy of the - compiled pattern. If there is additional study data, this follows imme- - diately after the compiled pattern. After writing the file, pcretest - expects to read a new pattern. - - A saved pattern can be reloaded into pcretest by specifing < and a file - name instead of a pattern. The name of the file must not contain a < - character, as otherwise pcretest will interpret the line as a pattern + compiled pattern. If there is additional study data, this (excluding + any JIT data) follows immediately after the compiled pattern. After + writing the file, pcretest expects to read a new pattern. + + A saved pattern can be reloaded into pcretest by specifying < and a + file name instead of a pattern. The name of the file must not contain a + < character, as otherwise pcretest will interpret the line as a pattern delimited by < characters. For example: re> +.\" +\fBpcre16_compile()\fP +.\" +with the PCRE_UTF16 option flag, or the pattern must start with the sequence +(*UTF16). When either of these is the case, both the pattern and any subject +strings that are matched against it are treated as UTF-16 strings instead of +strings of 16-bit characters. +. +. +.SH "UTF SUPPORT OVERHEAD" +.rs +.sp +If you compile PCRE with UTF support, but do not use it at run time, the +library will be a bit bigger, but the additional run time overhead is limited +to testing the PCRE_UTF8/16 flag occasionally, so should not be very big. +. +. +.SH "UNICODE PROPERTY SUPPORT" +.rs +.sp +If PCRE is built with Unicode character property support (which implies UTF +support), the escape sequences \ep{..}, \eP{..}, and \eX can be used. +The available properties that can be tested are limited to the general +category properties such as Lu for an upper case letter or Nd for a decimal +number, the Unicode script names such as Arabic or Han, and the derived +properties Any and L&. A full list is given in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. Only the short names for properties are supported. For example, +\ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported. +Furthermore, in Perl, many properties may optionally be prefixed by "Is", for +compatibility with Perl 5.6. PCRE does not support this. +. +. +.\" HTML +.SS "Validity of UTF-8 strings" +.rs +.sp +When you set the PCRE_UTF8 flag, the byte strings passed as patterns and +subjects are (by default) checked for validity on entry to the relevant +functions. The entire string is checked before any other processing takes +place. From release 7.3 of PCRE, the check is according the rules of RFC 3629, +which are themselves derived from the Unicode specification. Earlier releases +of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit +values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0 +to U+10FFFF, excluding U+D800 to U+DFFF. +.P +The excluded code points are the "Surrogate Area" of Unicode. They are reserved +for use by UTF-16, where they are used in pairs to encode codepoints with +values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs +are available independently in the UTF-8 encoding. (In other words, the whole +surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.) +.P +If an invalid UTF-8 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first byte +of the failing character. The run-time functions \fBpcre_exec()\fP and +\fBpcre_dfa_exec()\fP also pass back this information, as well as a more +detailed reason code if the caller has provided memory in which to do this. +.P +In some situations, you may already know that your strings are valid, and +therefore want to skip these checks in order to improve performance, for +example in the case of a long subject string that is being scanned repeatedly +with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time +or at run time, PCRE assumes that the pattern or subject it is given +(respectively) contains only valid UTF-8 codes. In this case, it does not +diagnose an invalid UTF-8 string. +.P +If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what +happens depends on why the string is invalid. If the string conforms to the +"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters +in the range 0 to 0x7FFFFFFF by \fBpcre_dfa_exec()\fP and the interpreted +version of \fBpcre_exec()\fP. In other words, apart from the initial validity +test, these functions (when in UTF-8 mode) handle strings according to the more +liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for +\fBpcre_exec()\fP supports only RFC 3629. If you are using JIT optimization, or +if the string does not even conform to RFC 2279, the result is undefined. Your +program may crash. +.P +If you want to process strings of values in the full range 0 to 0x7FFFFFFF, +encoded in a UTF-8-like manner as per the old RFC, you can set +PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this +situation, you will have to apply your own validity check, and avoid the use of +JIT optimization. +. +. +.\" HTML +.SS "Validity of UTF-16 strings" +.rs +.sp +When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are +passed as patterns and subjects are (by default) checked for validity on entry +to the relevant functions. Values other than those in the surrogate range +U+D800 to U+DFFF are independent code points. Values in the surrogate range +must be used in pairs in the correct manner. +.P +If an invalid UTF-16 string is passed to PCRE, an error return is given. At +compile time, the only additional information is the offset to the first data +unit of the failing character. The run-time functions \fBpcre16_exec()\fP and +\fBpcre16_dfa_exec()\fP also pass back this information, as well as a more +detailed reason code if the caller has provided memory in which to do this. +.P +In some situations, you may already know that your strings are valid, and +therefore want to skip these checks in order to improve performance. If you set +the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that +the pattern or subject it is given (respectively) contains only valid UTF-16 +sequences. In this case, it does not diagnose an invalid UTF-16 string. +. +. +.SS "General comments about UTF modes" +.rs +.sp +1. Codepoints less than 256 can be specified by either braced or unbraced +hexadecimal escape sequences (for example, \ex{b3} or \exb3). Larger values +have to use braced sequences. +.P +2. Octal numbers up to \e777 are recognized, and in UTF-8 mode, they match +two-byte characters for values greater than \e177. +.P +3. Repeat quantifiers apply to complete UTF characters, not to individual +data units, for example: \ex{100}{3}. +.P +4. The dot metacharacter matches one UTF character instead of a single data +unit. +.P +5. The escape sequence \eC can be used to match a single byte in UTF-8 mode, or +a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange +effects because it breaks up multi-unit characters (see the description of \eC +in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation). The use of \eC is not supported in the alternative matching +function \fBpcre[16]_dfa_exec()\fP, nor is it supported in UTF mode by the JIT +optimization of \fBpcre[16]_exec()\fP. If JIT optimization is requested for a +UTF pattern that contains \eC, it will not succeed, and so the matching will +be carried out by the normal interpretive function. +.P +6. The character escapes \eb, \eB, \ed, \eD, \es, \eS, \ew, and \eW correctly +test characters of any code value, but, by default, the characters that PCRE +recognizes as digits, spaces, or word characters remain the same set as in +non-UTF mode, all with values less than 256. This remains true even when PCRE +is built to include Unicode property support, because to do otherwise would +slow down PCRE in many common cases. Note in particular that this applies to +\eb and \eB, because they are defined in terms of \ew and \eW. If you really +want to test for a wider sense of, say, "digit", you can use explicit Unicode +property tests such as \ep{Nd}. Alternatively, if you set the PCRE_UCP option, +the way that the character escapes work is changed so that Unicode properties +are used to determine which characters match. There are more details in the +section on +.\" HTML +.\" +generic character types +.\" +in the +.\" HREF +\fBpcrepattern\fP +.\" +documentation. +.P +7. Similarly, characters that match the POSIX named character classes are all +low-valued characters, unless the PCRE_UCP option is set. +.P +8. However, the horizontal and vertical white space matching escapes (\eh, \eH, +\ev, and \eV) do match all the appropriate Unicode characters, whether or not +PCRE_UCP is set. +.P +9. Case-insensitive matching applies only to characters whose values are less +than 128, unless PCRE is built with Unicode property support. Even when Unicode +property support is available, PCRE still uses its own character tables when +checking the case of low-valued characters, so as not to degrade performance. +The Unicode property information is used only for characters with higher +values. Furthermore, PCRE supports case-insensitive matching only when there is +a one-to-one mapping between a letter's cases. There are a small number of +many-to-one mappings in Unicode; these are not supported by PCRE. +. +. +.SH AUTHOR +.rs +.sp +.nf +Philip Hazel +University Computing Service +Cambridge CB2 3QH, England. +.fi +. +. +.SH REVISION +.rs +.sp +.nf +Last updated: 14 April 2012 +Copyright (c) 1997-2012 University of Cambridge. +.fi diff -Nru pcre3-8.12/doc/perltest.txt pcre3-8.31/doc/perltest.txt --- pcre3-8.12/doc/perltest.txt 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/doc/perltest.txt 2012-01-21 16:00:28.000000000 +0000 @@ -3,30 +3,40 @@ The perltest.pl script tests Perl's regular expressions; it has the same specification as pcretest, and so can be given identical input, except that -input patterns can be followed only by Perl's lower case modifiers and /+ (as -used by pcretest), which is recognized and handled by the program. +input patterns can be followed only by Perl's lower case modifiers and certain +other pcretest modifiers that are either handled or ignored: -The data lines are processed as Perl double-quoted strings, so if they contain -" $ or @ characters, these have to be escaped. For this reason, all such -characters in testinput1, testinput4, testinput6, and testinput11 are escaped -so that they can be used for perltest as well as for pcretest. The special -upper case pattern modifiers such as /A that pcretest recognizes, and its -special data line escapes, are not used in these files. The output should be -identical, apart from the initial identifying banner. + /+ recognized and handled by perltest + /++ the second + is ignored + /8 recognized and handled by perltest + /J ignored + /K ignored + /W ignored + /S ignored + /SS ignored + /Y ignored + +The pcretest \Y escape in data lines is removed before matching. The data lines +are processed as Perl double-quoted strings, so if they contain " $ or @ +characters, these have to be escaped. For this reason, all such characters in +the Perl-compatible testinput1 file are escaped so that they can be used for +perltest as well as for pcretest. The special upper case pattern modifiers such +as /A that pcretest recognizes, and its special data line escapes, are not used +in the Perl-compatible test file. The output should be identical, apart from +the initial identifying banner. The perltest.pl script can also test UTF-8 features. It recognizes the special modifier /8 that pcretest uses to invoke UTF-8 functionality. The testinput4 and testinput6 files can be fed to perltest to run compatible UTF-8 tests. -However, it is necessary to add "use utf8;" to the script to make this work -correctly. - -The testinput11 file contains tests that use features of Perl 5.10, so does not -work with Perl 5.8. +However, it is necessary to add "use utf8; require Encode" to the script to +make this work correctly. I have not managed to find a way to handle this +automatically. The other testinput files are not suitable for feeding to perltest.pl, since they make use of the special upper case modifiers and escapes that pcretest -uses to test some features of PCRE. Some of these files also contains malformed -regular expressions, in order to check that PCRE diagnoses them correctly. +uses to test certain features of PCRE. Some of these files also contain +malformed regular expressions, in order to check that PCRE diagnoses them +correctly. Philip Hazel -October 2009 +January 2012 diff -Nru pcre3-8.12/libpcre.pc.in pcre3-8.31/libpcre.pc.in --- pcre3-8.12/libpcre.pc.in 2009-09-01 16:20:54.000000000 +0000 +++ pcre3-8.31/libpcre.pc.in 2011-12-28 16:57:58.000000000 +0000 @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libpcre -Description: PCRE - Perl compatible regular expressions C library +Description: PCRE - Perl compatible regular expressions C library with 8 bit character support Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpcre Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ diff -Nru pcre3-8.12/libpcre16.pc.in pcre3-8.31/libpcre16.pc.in --- pcre3-8.12/libpcre16.pc.in 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/libpcre16.pc.in 2012-01-01 14:36:09.000000000 +0000 @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libpcre16 +Description: PCRE - Perl compatible regular expressions C library with 16 bit character support +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lpcre16 +Cflags: -I${includedir} @PCRE_STATIC_CFLAG@ diff -Nru pcre3-8.12/ltmain.sh pcre3-8.31/ltmain.sh --- pcre3-8.12/ltmain.sh 2011-01-15 11:27:55.000000000 +0000 +++ pcre3-8.31/ltmain.sh 2012-07-06 09:01:59.000000000 +0000 @@ -1,6 +1,5 @@ -# Generated from ltmain.m4sh. -# libtool (GNU libtool) 2.2.10 +# libtool (GNU libtool) 2.4 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, @@ -70,17 +69,19 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.2.10 +# $progname: (GNU libtool) 2.4 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . PROGRAM=libtool PACKAGE=libtool -VERSION=2.2.10 +VERSION=2.4 TIMESTAMP="" -package_revision=1.3175 +package_revision=1.3293 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then @@ -163,6 +164,27 @@ dirname="s,/[^/]*$,," basename="s,^.*/,," +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: @@ -177,17 +199,31 @@ # those functions but instead duplicate the functionality here. func_dirname_and_basename () { - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation -# Generated shell functions inserted here. # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' @@ -370,6 +406,15 @@ # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. @@ -398,7 +443,7 @@ # name if it has been set yet. func_echo () { - $ECHO "$progname${mode+: }$mode: $*" + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... @@ -424,14 +469,14 @@ # Echo program name prefixed message to standard error. func_error () { - $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { - $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : @@ -650,11 +695,30 @@ fi } +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + # func_version # Echo version message to standard output and exit. func_version () { + $opt_debug + $SED -n '/(C)/!b go :more /\./!{ @@ -676,6 +740,8 @@ # Echo short help message to standard output and exit. func_usage () { + $opt_debug + $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// @@ -692,7 +758,10 @@ # unless 'noexit' is passed as argument. func_help () { + $opt_debug + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print s/^# // s/^# *$// s*\$progname*'$progname'* @@ -705,7 +774,11 @@ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p - }' < "$progpath" + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" ret=$? if test -z "$1"; then exit $ret @@ -717,12 +790,39 @@ # exit_cmd. func_missing_arg () { + $opt_debug + func_error "missing argument for $1." exit_cmd=exit } -exit_cmd=: +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: @@ -732,25 +832,64 @@ magic_exe="%%%MAGIC EXE variable%%%" # Global variables. -# $mode is unset nonopt= -execute_dlfiles= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 -opt_dry_run=false -opt_duplicate_deps=false -opt_silent=false -opt_debug=: - # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. @@ -840,129 +979,204 @@ esac } -# Parse options once, thoroughly. This comes as soon as possible in -# the script to make things like `libtool --version' happen quickly. +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () { + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_verbose=: +opt_silent=false +opt_verbose=false - # Shorthand for --mode=foo, only valid as the first argument - case $1 in - clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; - compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; - execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; - finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; - install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; - link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; - uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; - esac - # Parse non-mode specific arguments: - while test "$#" -gt 0; do +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do opt="$1" shift - case $opt in - --config) func_config ;; - - --debug) preserve_args="$preserve_args $opt" + --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" - opt_debug='set -x' $opt_debug ;; - - -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break - execute_dlfiles="$execute_dlfiles $1" - shift + --dry-run|--dryrun|-n) + opt_dry_run=: ;; - - --dry-run | -n) opt_dry_run=: ;; - --features) func_features ;; - --finish) mode="finish" ;; - - --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break - case $1 in - # Valid mode arguments: - clean) ;; - compile) ;; - execute) ;; - finish) ;; - install) ;; - link) ;; - relink) ;; - uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; - esac - - mode="$1" + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" shift ;; - --preserve-dup-deps) - opt_duplicate_deps=: ;; - - --quiet|--silent) preserve_args="$preserve_args $opt" - opt_silent=: - opt_verbose=false + opt_preserve_dup_deps=: ;; - - --no-quiet|--no-silent) - preserve_args="$preserve_args $opt" - opt_silent=false + --features) + opt_features=: +func_features ;; - - --verbose| -v) preserve_args="$preserve_args $opt" + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) opt_silent=false - opt_verbose=: +func_append preserve_args " $opt" ;; - - --no-verbose) preserve_args="$preserve_args $opt" + --no-verbose) opt_verbose=false +func_append preserve_args " $opt" ;; - - --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break - preserve_args="$preserve_args $opt $1" - func_enable_tag "$1" # tagname is set here + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" shift ;; + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + # Separate optargs to long options: - -dlopen=*|--mode=*|--tag=*) - func_opt_split "$opt" - set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; - -\?|-h) func_usage ;; - --help) opt_help=: ;; - --help-all) opt_help=': help-all' ;; - --version) func_version ;; - - -*) func_fatal_help "unrecognized option \`$opt'" ;; - - *) nonopt="$opt" - break + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) @@ -970,82 +1184,44 @@ opt_duplicate_compiler_generated_deps=: ;; *) - opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac - # Having warned about all mis-specified options, bail out if - # anything was wrong. - $exit_cmd $EXIT_FAILURE -} + $opt_help || { + # Sanity checks first: + func_check_version_match -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" fi - exit $EXIT_MISMATCH - fi -} - + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" -## ----------- ## -## Main. ## -## ----------- ## - -$opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi - test -z "$mode" && func_fatal_error "error: you must specify a MODE." + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$mode' for more information." -} +## ----------- ## +## Main. ## +## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. @@ -1110,12 +1286,9 @@ # temporary ltwrapper_script. func_ltwrapper_scriptname () { - func_ltwrapper_scriptname_result="" - if func_ltwrapper_executable_p "$1"; then - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" - fi + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file @@ -1161,6 +1334,37 @@ } +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. @@ -1173,8 +1377,7 @@ if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do - func_quote_for_eval "$arg" - CC_quoted="$CC_quoted $func_quote_for_eval_result" + func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` @@ -1193,8 +1396,7 @@ CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. - func_quote_for_eval "$arg" - CC_quoted="$CC_quoted $func_quote_for_eval_result" + func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` @@ -1226,42 +1428,522 @@ -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () { - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi + func_to_host_path_result="$1" +} +# end func_convert_path_noop - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - $opt_dry_run || { - cat >${write_libobj}T < "$lockfile" fi $opt_dry_run || $RM $removelist - removelist="$removelist $lockfile" + func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result @@ -1515,7 +2194,7 @@ if test -z "$output_obj"; then # Place PIC objects in $objdir - command="$command -o $lobj" + func_append command " -o $lobj" fi func_show_eval_locale "$command" \ @@ -1562,11 +2241,11 @@ command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then - command="$command -o $obj" + func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" + func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' @@ -1611,13 +2290,13 @@ } $opt_help || { - test "$mode" = compile && func_mode_compile ${1+"$@"} + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. - case $mode in + case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. @@ -1793,7 +2472,7 @@ ;; *) - func_fatal_help "invalid operation mode \`$mode'" + func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac @@ -1808,13 +2487,13 @@ else { func_help noexit - for mode in compile link execute install finish uninstall clean; do + for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit - for mode in compile link execute install finish uninstall clean; do + for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done @@ -1843,13 +2522,16 @@ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do + for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" @@ -1871,7 +2553,7 @@ dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" + func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" @@ -1928,8 +2610,7 @@ ;; esac # Quote arguments (to preserve shell metacharacters). - func_quote_for_eval "$file" - args="$args $func_quote_for_eval_result" + func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then @@ -1961,22 +2642,59 @@ fi } -test "$mode" = execute && func_mode_execute ${1+"$@"} +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug - libdirs="$nonopt" + libs= + libdirs= admincmds= - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. @@ -1986,7 +2704,7 @@ if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done @@ -1995,53 +2713,55 @@ # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi exit $EXIT_SUCCESS } -test "$mode" = finish && func_mode_finish ${1+"$@"} +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... @@ -2066,7 +2786,7 @@ # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" - install_prog="$install_prog$func_quote_for_eval_result" + func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; @@ -2086,7 +2806,7 @@ do arg2= if test -n "$dest"; then - files="$files $dest" + func_append files " $dest" dest=$arg continue fi @@ -2124,11 +2844,11 @@ # Aesthetically quote the argument. func_quote_for_eval "$arg" - install_prog="$install_prog $func_quote_for_eval_result" + func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi - install_shared_prog="$install_shared_prog $func_quote_for_eval_result" + func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ @@ -2140,7 +2860,7 @@ if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" - install_shared_prog="$install_shared_prog -m $func_quote_for_eval_result" + func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi @@ -2198,10 +2918,13 @@ case $file in *.$libext) # Do the static libraries later. - staticlibs="$staticlibs $file" + func_append staticlibs " $file" ;; *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" @@ -2215,19 +2938,19 @@ if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; + *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; + *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" - dir="$dir$objdir" + func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. @@ -2304,7 +3027,7 @@ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) @@ -2501,7 +3224,7 @@ fi } -test "$mode" = install && func_mode_install ${1+"$@"} +test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p @@ -2548,6 +3271,18 @@ #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + /* External symbol declarations for the compiler. */\ " @@ -2559,8 +3294,9 @@ # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do - func_verbose "extracting global C symbols from \`$progfile'" - $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then @@ -2609,10 +3345,52 @@ func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac done $opt_dry_run || { @@ -2650,26 +3428,9 @@ const char *name; void *address; } lt_dlsymlist; -" - case $host in - *cygwin* | *mingw* | *cegcc* ) - echo >> "$output_objdir/$my_dlsyms" "\ -/* DATA imports from DLLs on WIN32 con't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs. */" - lt_dlsym_const= ;; - *osf5*) - echo >> "$output_objdir/$my_dlsyms" "\ -/* This system does not cope well with relocations in const data */" - lt_dlsym_const= ;; - *) - lt_dlsym_const=const ;; - esac - - echo >> "$output_objdir/$my_dlsyms" "\ -extern $lt_dlsym_const lt_dlsymlist +extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; -$lt_dlsym_const lt_dlsymlist +LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," @@ -2725,7 +3486,7 @@ for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; - *) symtab_cflags="$symtab_cflags $arg" ;; + *) func_append symtab_cflags " $arg" ;; esac done @@ -2788,7 +3549,8 @@ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - win32_nmres=`eval $NM -f posix -A $1 | + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ @@ -2817,6 +3579,131 @@ $ECHO "$win32_libid_type" } +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} # func_extract_an_archive dir oldlib @@ -3195,6 +4082,18 @@ if test -f \"\$progdir/\$program\"; then" + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ @@ -3209,14 +4108,6 @@ " fi - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. @@ -3234,166 +4125,6 @@ } -# func_to_host_path arg -# -# Convert paths to host format when used with build tools. -# Intended for use with "native" mingw (where libtool itself -# is running under the msys shell), or in the following cross- -# build environments: -# $build $host -# mingw (msys) mingw [e.g. native] -# cygwin mingw -# *nix + wine mingw -# where wine is equipped with the `winepath' executable. -# In the native mingw case, the (msys) shell automatically -# converts paths for any non-msys applications it launches, -# but that facility isn't available from inside the cwrapper. -# Similar accommodations are necessary for $host mingw and -# $build cygwin. Calling this function does no harm for other -# $host/$build combinations not listed above. -# -# ARG is the path (on $build) that should be converted to -# the proper representation for $host. The result is stored -# in $func_to_host_path_result. -func_to_host_path () -{ - func_to_host_path_result="$1" - if test -n "$1"; then - case $host in - *mingw* ) - lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - case $build in - *mingw* ) # actually, msys - # awkward: cmd appends spaces to result - func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` - ;; - *cygwin* ) - func_to_host_path_result=`cygpath -w "$1" | - $SED -e "$lt_sed_naive_backslashify"` - ;; - * ) - # Unfortunately, winepath does not exit with a non-zero - # error code, so we are forced to check the contents of - # stdout. On the other hand, if the command is not - # found, the shell will set an exit code of 127 and print - # *an error message* to stdout. So we must check for both - # error code of zero AND non-empty stdout, which explains - # the odd construction: - func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` - if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then - func_to_host_path_result=`$ECHO "$func_to_host_path_tmp1" | - $SED -e "$lt_sed_naive_backslashify"` - else - # Allow warning below. - func_to_host_path_result= - fi - ;; - esac - if test -z "$func_to_host_path_result" ; then - func_error "Could not determine host path corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_path_result="$1" - fi - ;; - esac - fi -} -# end: func_to_host_path - -# func_to_host_pathlist arg -# -# Convert pathlists to host format when used with build tools. -# See func_to_host_path(), above. This function supports the -# following $build/$host combinations (but does no harm for -# combinations not listed here): -# $build $host -# mingw (msys) mingw [e.g. native] -# cygwin mingw -# *nix + wine mingw -# -# Path separators are also converted from $build format to -# $host format. If ARG begins or ends with a path separator -# character, it is preserved (but converted to $host format) -# on output. -# -# ARG is a pathlist (on $build) that should be converted to -# the proper representation on $host. The result is stored -# in $func_to_host_pathlist_result. -func_to_host_pathlist () -{ - func_to_host_pathlist_result="$1" - if test -n "$1"; then - case $host in - *mingw* ) - lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_pathlist_tmp1=$func_stripname_result - case $build in - *mingw* ) # Actually, msys. - # Awkward: cmd appends spaces to result. - func_to_host_pathlist_result=` - ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` - ;; - *cygwin* ) - func_to_host_pathlist_result=`cygpath -w -p "$func_to_host_pathlist_tmp1" | - $SED -e "$lt_sed_naive_backslashify"` - ;; - * ) - # unfortunately, winepath doesn't convert pathlists - func_to_host_pathlist_result="" - func_to_host_pathlist_oldIFS=$IFS - IFS=: - for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do - IFS=$func_to_host_pathlist_oldIFS - if test -n "$func_to_host_pathlist_f" ; then - func_to_host_path "$func_to_host_pathlist_f" - if test -n "$func_to_host_path_result" ; then - if test -z "$func_to_host_pathlist_result" ; then - func_to_host_pathlist_result="$func_to_host_path_result" - else - func_append func_to_host_pathlist_result ";$func_to_host_path_result" - fi - fi - fi - done - IFS=$func_to_host_pathlist_oldIFS - ;; - esac - if test -z "$func_to_host_pathlist_result"; then - func_error "Could not determine the host path(s) corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This may break if $1 contains DOS-style drive - # specifications. The fix is not to complicate the expression - # below, but for the user to provide a working wine installation - # with winepath so that path translation in the cross-to-mingw - # case works properly. - lt_replace_pathsep_nix_to_dos="s|:|;|g" - func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ - $SED -e "$lt_replace_pathsep_nix_to_dos"` - fi - # Now, add the leading and trailing path separators back - case "$1" in - :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" - ;; - esac - case "$1" in - *: ) func_append func_to_host_pathlist_result ";" - ;; - esac - ;; - esac - fi -} -# end: func_to_host_pathlist - # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because @@ -3563,14 +4294,14 @@ EOF cat </dev/null` + if test "$want_nocaseglob" = yes; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | @@ -6999,7 +7812,7 @@ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" + func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi @@ -7024,7 +7837,7 @@ ;; *) # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" + func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. @@ -7040,7 +7853,7 @@ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" + func_append newdeplibs " $a_deplib" a_deplib="" ;; esac @@ -7053,7 +7866,7 @@ potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" + func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi @@ -7078,7 +7891,7 @@ ;; *) # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" + func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. @@ -7182,7 +7995,7 @@ *) case " $deplibs " in *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; + func_append new_libs " -L$path/$objdir" ;; esac ;; esac @@ -7192,10 +8005,10 @@ -L*) case " $new_libs " in *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; + *) func_append new_libs " $deplib" ;; esac ;; - *) new_libs="$new_libs $deplib" ;; + *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" @@ -7212,10 +8025,12 @@ hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else @@ -7224,18 +8039,18 @@ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" + func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; + *) func_apped perm_rpath " $libdir" ;; esac fi done @@ -7253,7 +8068,7 @@ # We should set the runpath_var. rpath= for dir in $perm_rpath; do - rpath="$rpath$dir:" + func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi @@ -7261,7 +8076,7 @@ fi shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi @@ -7287,7 +8102,7 @@ linknames= for link do - linknames="$linknames $link" + func_append linknames " $link" done # Use standard objects if they are pic @@ -7298,7 +8113,7 @@ if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" - delfiles="$delfiles $export_symbols" + func_append delfiles " $export_symbols" fi orig_export_symbols= @@ -7329,13 +8144,45 @@ $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do + for cmd1 in $cmds; do IFS="$save_ifs" - eval cmd=\"$cmd\" - func_len " $cmd" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. @@ -7369,7 +8216,7 @@ # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi @@ -7379,7 +8226,7 @@ case " $convenience " in *" $test_deplib "*) ;; *) - tmp_deplibs="$tmp_deplibs $test_deplib" + func_append tmp_deplibs " $test_deplib" ;; esac done @@ -7399,21 +8246,21 @@ test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" + func_append generated " $gentop" func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" + func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" + func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then + if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi @@ -7475,10 +8322,13 @@ echo 'INPUT (' > $output for obj in $save_libobjs do - $ECHO "$obj" >> $output + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output - delfiles="$delfiles $output" + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" @@ -7492,10 +8342,12 @@ fi for obj do - $ECHO "$obj" >> $output + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output done - delfiles="$delfiles $output" - output=$firstobj\"$file_list_spec$output\" + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." @@ -7546,7 +8398,7 @@ if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi - delfiles="$delfiles $output" + func_append delfiles " $output" else output= @@ -7580,7 +8432,7 @@ lt_exit=$? # Restore the uninstalled library and exit - if test "$mode" = relink; then + if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -7613,7 +8465,7 @@ # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi @@ -7654,10 +8506,10 @@ # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" + func_append generated " $gentop" func_extract_archives $gentop $dlprefiles - libobjs="$libobjs $func_extract_archives_result" + func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi @@ -7673,7 +8525,7 @@ lt_exit=$? # Restore the uninstalled library and exit - if test "$mode" = relink; then + if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -7685,7 +8537,7 @@ IFS="$save_ifs" # Restore the uninstalled library and exit - if test "$mode" = relink; then + if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then @@ -7769,13 +8621,16 @@ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" - generated="$generated $gentop" + func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test @@ -7849,8 +8704,8 @@ if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" ;; esac fi @@ -7870,7 +8725,7 @@ *) case " $compile_deplibs " in *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; + func_append new_libs " -L$path/$objdir" ;; esac ;; esac @@ -7880,17 +8735,17 @@ -L*) case " $new_libs " in *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; + *) func_append new_libs " $deplib" ;; esac ;; - *) new_libs="$new_libs $deplib" ;; + *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. @@ -7898,7 +8753,7 @@ # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; + *) func_append finalize_rpath " $libdir" ;; esac done fi @@ -7917,18 +8772,18 @@ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" + func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; + *) func_append perm_rpath " $libdir" ;; esac fi case $host in @@ -7937,12 +8792,12 @@ case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; - *) dllsearchpath="$dllsearchpath:$libdir";; + *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; - *) dllsearchpath="$dllsearchpath:$testbindir";; + *) func_append dllsearchpath ":$testbindir";; esac ;; esac @@ -7968,18 +8823,18 @@ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" + func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + *) func_append finalize_perm_rpath " $libdir" ;; esac fi done @@ -8030,6 +8885,12 @@ exit_status=0 func_show_eval "$link_command" 'exit_status=$?' + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' @@ -8052,7 +8913,7 @@ # We should set the runpath_var. rpath= for dir in $perm_rpath; do - rpath="$rpath$dir:" + func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi @@ -8060,7 +8921,7 @@ # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" + func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi @@ -8075,6 +8936,13 @@ $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + exit $EXIT_SUCCESS fi @@ -8108,6 +8976,12 @@ func_show_eval "$link_command" 'exit $?' + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + # Now create the wrapper script. func_verbose "creating $output" @@ -8205,7 +9079,7 @@ else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then - oldobjs="$oldobjs $symfileobj" + func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" @@ -8213,10 +9087,10 @@ if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" + func_append generated " $gentop" func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" + func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. @@ -8227,10 +9101,10 @@ # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" + func_append generated " $gentop" func_extract_archives $gentop $dlprefiles - oldobjs="$oldobjs $func_extract_archives_result" + func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have @@ -8248,7 +9122,7 @@ else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" + func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= @@ -8272,9 +9146,9 @@ esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" ;; - *) oldobjs="$oldobjs $obj" ;; + *) func_append oldobjs " $obj" ;; esac done fi @@ -8284,6 +9158,16 @@ len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." @@ -8380,9 +9264,19 @@ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" - newdependency_libs="$newdependency_libs $libdir/$name" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; + *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" @@ -8396,9 +9290,9 @@ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" - newdlfiles="$newdlfiles $libdir/$name" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; - *) newdlfiles="$newdlfiles $lib" ;; + *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" @@ -8415,7 +9309,7 @@ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" - newdlprefiles="$newdlprefiles $libdir/$name" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done @@ -8427,7 +9321,7 @@ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac - newdlfiles="$newdlfiles $abs" + func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= @@ -8436,7 +9330,7 @@ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac - newdlprefiles="$newdlprefiles $abs" + func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi @@ -8521,7 +9415,7 @@ exit $EXIT_SUCCESS } -{ test "$mode" = link || test "$mode" = relink; } && +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} @@ -8541,9 +9435,9 @@ for arg do case $arg in - -f) RM="$RM $arg"; rmforce=yes ;; - -*) RM="$RM $arg" ;; - *) files="$files $arg" ;; + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; esac done @@ -8552,24 +9446,23 @@ rmdirs= - origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then - objdir="$origobjdir" + odir="$objdir" else - objdir="$dir/$origobjdir" + odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" - test "$mode" = uninstall && objdir="$dir" + test "$opt_mode" = uninstall && odir="$dir" - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; esac fi @@ -8595,18 +9488,17 @@ # Delete the libtool libraries and symlinks. for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" + func_append rmfiles " $odir/$n" done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test -n "$old_library" && func_append rmfiles " $odir/$old_library" - case "$mode" in + case "$opt_mode" in clean) - case " $library_names " in - # " " in the beginning catches empty $dlname + case " $library_names " in *" $dlname "*) ;; - *) rmfiles="$rmfiles $objdir/$dlname" ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac - test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then @@ -8634,19 +9526,19 @@ # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" + func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" + func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) - if test "$mode" = clean ; then + if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) @@ -8656,7 +9548,7 @@ noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe - rmfiles="$rmfiles $file" + func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. @@ -8665,7 +9557,7 @@ func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result - rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename @@ -8673,12 +9565,12 @@ # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" + func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" + func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi @@ -8686,7 +9578,6 @@ esac func_show_eval "$RM $rmfiles" 'exit_status=1' done - objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do @@ -8698,16 +9589,16 @@ exit $exit_status } -{ test "$mode" = uninstall || test "$mode" = clean; } && +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} -test -z "$mode" && { +test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$mode'" + func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" diff -Nru pcre3-8.12/makevp_c.txt pcre3-8.31/makevp_c.txt --- pcre3-8.12/makevp_c.txt 2008-09-05 10:21:21.000000000 +0000 +++ pcre3-8.31/makevp_c.txt 2011-12-28 16:57:51.000000000 +0000 @@ -1,3 +1,4 @@ +pcre_byte_order.c pcre_chartables.c pcre_compile.c pcre_config.c @@ -13,7 +14,6 @@ pcre_refcount.c pcre_study.c pcre_tables.c -pcre_try_flipped.c pcre_ucd.c pcre_valid_utf8.c pcre_version.c diff -Nru pcre3-8.12/makevp_l.txt pcre3-8.31/makevp_l.txt --- pcre3-8.12/makevp_l.txt 2008-09-05 10:21:47.000000000 +0000 +++ pcre3-8.31/makevp_l.txt 2011-12-28 16:57:55.000000000 +0000 @@ -1,3 +1,4 @@ ++pcre_byte_order.obj & +pcre_chartables.obj & +pcre_compile.obj & +pcre_config.obj & @@ -13,7 +14,6 @@ +pcre_refcount.obj & +pcre_study.obj & +pcre_tables.obj & -+pcre_try_flipped.obj & +pcre_ucd.obj & +pcre_valid_utf8.obj & +pcre_version.obj & diff -Nru pcre3-8.12/pcre-config.in pcre3-8.31/pcre-config.in --- pcre3-8.12/pcre-config.in 2010-03-02 11:08:45.000000000 +0000 +++ pcre3-8.31/pcre-config.in 2012-01-21 16:00:28.000000000 +0000 @@ -4,12 +4,25 @@ exec_prefix=@exec_prefix@ exec_prefix_set=no +cflags="[--cflags]" + if test @enable_cpp@ = yes ; then - usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--libs-cpp] [--cflags] [--cflags-posix]" + libs="[--libs-cpp]" else - usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]" + libs= +fi + +if test @enable_pcre16@ = yes ; then + libs="[--libs16] $libs" fi +if test @enable_pcre8@ = yes ; then + libs="[--libs] [--libs-posix] $libs" + cflags="$cflags [--cflags-posix]" +fi + +usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] $libs $cflags" + if test $# -eq 0; then echo "${usage}" 1>&2 exit 1 @@ -25,6 +38,11 @@ ;; esac +libS= +if test @libdir@ != /usr/lib ; then + libS=-L@libdir@ +fi + while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; @@ -51,21 +69,46 @@ --version) echo @PACKAGE_VERSION@ ;; - --cflags | --cflags-posix) + --cflags) if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi echo $includes @PCRE_STATIC_CFLAG@ ;; + --cflags-posix) + if test @enable_pcre8@ = yes ; then + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes @PCRE_STATIC_CFLAG@ + else + echo "${usage}" 1>&2 + fi + ;; --libs-posix) - echo -L@libdir@$libR -lpcreposix -lpcre + if test @enable_pcre8@ = yes ; then + echo $libS$libR -lpcreposix -lpcre + else + echo "${usage}" 1>&2 + fi ;; --libs) - echo -L@libdir@$libR -lpcre + if test @enable_pcre8@ = yes ; then + echo $libS$libR -lpcre + else + echo "${usage}" 1>&2 + fi + ;; + --libs16) + if test @enable_pcre16@ = yes ; then + echo $libS$libR -lpcre16 + else + echo "${usage}" 1>&2 + fi ;; --libs-cpp) if test @enable_cpp@ = yes ; then - echo -L@libdir@$libR -lpcrecpp -lpcre + echo $libS$libR -lpcrecpp -lpcre else echo "${usage}" 1>&2 fi diff -Nru pcre3-8.12/pcre.h.generic pcre3-8.31/pcre.h.generic --- pcre3-8.12/pcre.h.generic 2011-01-15 17:27:55.000000000 +0000 +++ pcre3-8.31/pcre.h.generic 2012-07-06 09:55:37.000000000 +0000 @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 12 +#define PCRE_MINOR 31 #define PCRE_PRERELEASE -#define PCRE_DATE 2011-01-15 +#define PCRE_DATE 2012-07-06 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate @@ -98,28 +98,37 @@ /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. However, almost all the bits in the options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. */ +compile-time only bits for runtime options, or vice versa. In the comments +below, "compile", "exec", and "DFA exec" mean that the option is permitted to +be set for those functions; "used in" means that an option may be set only for +compile, but is subsequently referenced in exec and/or DFA exec. Any of the +compile-time options may be inspected during studying (and therefore JIT +compiling). */ #define PCRE_CASELESS 0x00000001 /* Compile */ #define PCRE_MULTILINE 0x00000002 /* Compile */ #define PCRE_DOTALL 0x00000004 /* Compile */ #define PCRE_EXTENDED 0x00000008 /* Compile */ #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ -#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ #define PCRE_EXTRA 0x00000040 /* Compile */ #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ #define PCRE_UNGREEDY 0x00000200 /* Compile */ #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ -#define PCRE_UTF8 0x00000800 /* Compile */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ +#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ -#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ -#define PCRE_FIRSTLINE 0x00040000 /* Compile */ +#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ #define PCRE_DUPNAMES 0x00080000 /* Compile */ #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ @@ -128,41 +137,82 @@ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ -#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ -#define PCRE_UCP 0x20000000 /* Compile */ +#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ -#define PCRE_ERROR_NOMATCH (-1) -#define PCRE_ERROR_NULL (-2) -#define PCRE_ERROR_BADOPTION (-3) -#define PCRE_ERROR_BADMAGIC (-4) -#define PCRE_ERROR_UNKNOWN_OPCODE (-5) -#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ -#define PCRE_ERROR_NOMEMORY (-6) -#define PCRE_ERROR_NOSUBSTRING (-7) -#define PCRE_ERROR_MATCHLIMIT (-8) -#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ -#define PCRE_ERROR_BADUTF8 (-10) -#define PCRE_ERROR_BADUTF8_OFFSET (-11) -#define PCRE_ERROR_PARTIAL (-12) -#define PCRE_ERROR_BADPARTIAL (-13) -#define PCRE_ERROR_INTERNAL (-14) -#define PCRE_ERROR_BADCOUNT (-15) -#define PCRE_ERROR_DFA_UITEM (-16) -#define PCRE_ERROR_DFA_UCOND (-17) -#define PCRE_ERROR_DFA_UMLIMIT (-18) -#define PCRE_ERROR_DFA_WSSIZE (-19) -#define PCRE_ERROR_DFA_RECURSE (-20) -#define PCRE_ERROR_RECURSIONLIMIT (-21) -#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ -#define PCRE_ERROR_BADNEWLINE (-23) -#define PCRE_ERROR_BADOFFSET (-24) -#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_OPCODE (-5) +#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) +#define PCRE_ERROR_DFA_UITEM (-16) +#define PCRE_ERROR_DFA_UCOND (-17) +#define PCRE_ERROR_DFA_UMLIMIT (-18) +#define PCRE_ERROR_DFA_WSSIZE (-19) +#define PCRE_ERROR_DFA_RECURSE (-20) +#define PCRE_ERROR_RECURSIONLIMIT (-21) +#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ +#define PCRE_ERROR_BADNEWLINE (-23) +#define PCRE_ERROR_BADOFFSET (-24) +#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ +#define PCRE_ERROR_RECURSELOOP (-26) +#define PCRE_ERROR_JIT_STACKLIMIT (-27) +#define PCRE_ERROR_BADMODE (-28) +#define PCRE_ERROR_BADENDIANNESS (-29) +#define PCRE_ERROR_DFA_BADRESTART (-30) + +/* Specific error codes for UTF-8 validity checks */ + +#define PCRE_UTF8_ERR0 0 +#define PCRE_UTF8_ERR1 1 +#define PCRE_UTF8_ERR2 2 +#define PCRE_UTF8_ERR3 3 +#define PCRE_UTF8_ERR4 4 +#define PCRE_UTF8_ERR5 5 +#define PCRE_UTF8_ERR6 6 +#define PCRE_UTF8_ERR7 7 +#define PCRE_UTF8_ERR8 8 +#define PCRE_UTF8_ERR9 9 +#define PCRE_UTF8_ERR10 10 +#define PCRE_UTF8_ERR11 11 +#define PCRE_UTF8_ERR12 12 +#define PCRE_UTF8_ERR13 13 +#define PCRE_UTF8_ERR14 14 +#define PCRE_UTF8_ERR15 15 +#define PCRE_UTF8_ERR16 16 +#define PCRE_UTF8_ERR17 17 +#define PCRE_UTF8_ERR18 18 +#define PCRE_UTF8_ERR19 19 +#define PCRE_UTF8_ERR20 20 +#define PCRE_UTF8_ERR21 21 + +/* Specific error codes for UTF-16 validity checks */ + +#define PCRE_UTF16_ERR0 0 +#define PCRE_UTF16_ERR1 1 +#define PCRE_UTF16_ERR2 2 +#define PCRE_UTF16_ERR3 3 +#define PCRE_UTF16_ERR4 4 /* Request types for pcre_fullinfo() */ @@ -183,6 +233,9 @@ #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 +#define PCRE_INFO_JIT 16 +#define PCRE_INFO_JITSIZE 17 +#define PCRE_INFO_MAXLOOKBEHIND 18 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -196,8 +249,18 @@ #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 +#define PCRE_CONFIG_JIT 9 +#define PCRE_CONFIG_UTF16 10 +#define PCRE_CONFIG_JITTARGET 11 -/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine +/* Request types for pcre_study(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_STUDY_JIT_COMPILE 0x0001 +#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 +#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 + +/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 @@ -206,12 +269,33 @@ #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 +#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; +struct real_pcre16; /* declaration; the definition is private */ +typedef struct real_pcre16 pcre16; + +struct real_pcre_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre_jit_stack pcre_jit_stack; + +struct real_pcre16_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre16_jit_stack pcre16_jit_stack; + +/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain +a 16 bit wide signed data type. Otherwise it can be a dummy data type since +pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR16 +#define PCRE_UCHAR16 unsigned short +#endif + +#ifndef PCRE_SPTR16 +#define PCRE_SPTR16 const PCRE_UCHAR16 * +#endif + /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ @@ -232,8 +316,22 @@ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre_extra; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ + unsigned long int match_limit_recursion; /* Max recursive calls to match() */ + PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ +} pcre16_extra; + /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work @@ -254,9 +352,33 @@ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const unsigned char *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre_callout_block; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR16 subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ +} pcre16_callout_block; + /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function @@ -269,47 +391,114 @@ PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); + +PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_free)(void *); +PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_stack_free)(void *); +PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); + +PCRE_EXP_DECL void *pcre16_malloc(size_t); +PCRE_EXP_DECL void pcre16_free(void *); +PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); +PCRE_EXP_DECL void pcre16_stack_free(void *); +PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); #endif /* VPCOMPAT */ +/* User defined callback which provides a stack just before the match starts. */ + +typedef pcre_jit_stack *(*pcre_jit_callback)(void *); +typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); + /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, + const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, + int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); +PCRE_EXP_DECL int pcre16_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); -PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, - int); +PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); +PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, + char *, int); +PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, + PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); +PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); +PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); +PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, + void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); +PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); +PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); +PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, + PCRE_UCHAR16 **, PCRE_UCHAR16 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); +PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, + PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); -PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); +PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); +PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); +PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); PCRE_EXP_DECL const char *pcre_version(void); +PCRE_EXP_DECL const char *pcre16_version(void); + +/* Utility functions for byte order swaps. */ +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); + +/* JIT compiler related functions. */ + +PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); +PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); +PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); +PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); +PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, + pcre_jit_callback, void *); +PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, + pcre16_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ diff -Nru pcre3-8.12/pcre.h.in pcre3-8.31/pcre.h.in --- pcre3-8.12/pcre.h.in 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre.h.in 2012-04-19 16:17:54.000000000 +0000 @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, to be #included by applications that call the PCRE functions. - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -98,28 +98,37 @@ /* Options. Some are compile-time only, some are run-time only, and some are both, so we keep them all distinct. However, almost all the bits in the options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. */ +compile-time only bits for runtime options, or vice versa. In the comments +below, "compile", "exec", and "DFA exec" mean that the option is permitted to +be set for those functions; "used in" means that an option may be set only for +compile, but is subsequently referenced in exec and/or DFA exec. Any of the +compile-time options may be inspected during studying (and therefore JIT +compiling). */ #define PCRE_CASELESS 0x00000001 /* Compile */ #define PCRE_MULTILINE 0x00000002 /* Compile */ #define PCRE_DOTALL 0x00000004 /* Compile */ #define PCRE_EXTENDED 0x00000008 /* Compile */ #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ -#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ #define PCRE_EXTRA 0x00000040 /* Compile */ #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ #define PCRE_UNGREEDY 0x00000200 /* Compile */ #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ -#define PCRE_UTF8 0x00000800 /* Compile */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ +#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ -#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ -#define PCRE_FIRSTLINE 0x00040000 /* Compile */ +#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ #define PCRE_DUPNAMES 0x00080000 /* Compile */ #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ @@ -128,41 +137,82 @@ #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ -#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ -#define PCRE_UCP 0x20000000 /* Compile */ +#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ -#define PCRE_ERROR_NOMATCH (-1) -#define PCRE_ERROR_NULL (-2) -#define PCRE_ERROR_BADOPTION (-3) -#define PCRE_ERROR_BADMAGIC (-4) -#define PCRE_ERROR_UNKNOWN_OPCODE (-5) -#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ -#define PCRE_ERROR_NOMEMORY (-6) -#define PCRE_ERROR_NOSUBSTRING (-7) -#define PCRE_ERROR_MATCHLIMIT (-8) -#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ -#define PCRE_ERROR_BADUTF8 (-10) -#define PCRE_ERROR_BADUTF8_OFFSET (-11) -#define PCRE_ERROR_PARTIAL (-12) -#define PCRE_ERROR_BADPARTIAL (-13) -#define PCRE_ERROR_INTERNAL (-14) -#define PCRE_ERROR_BADCOUNT (-15) -#define PCRE_ERROR_DFA_UITEM (-16) -#define PCRE_ERROR_DFA_UCOND (-17) -#define PCRE_ERROR_DFA_UMLIMIT (-18) -#define PCRE_ERROR_DFA_WSSIZE (-19) -#define PCRE_ERROR_DFA_RECURSE (-20) -#define PCRE_ERROR_RECURSIONLIMIT (-21) -#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ -#define PCRE_ERROR_BADNEWLINE (-23) -#define PCRE_ERROR_BADOFFSET (-24) -#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_OPCODE (-5) +#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) +#define PCRE_ERROR_DFA_UITEM (-16) +#define PCRE_ERROR_DFA_UCOND (-17) +#define PCRE_ERROR_DFA_UMLIMIT (-18) +#define PCRE_ERROR_DFA_WSSIZE (-19) +#define PCRE_ERROR_DFA_RECURSE (-20) +#define PCRE_ERROR_RECURSIONLIMIT (-21) +#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ +#define PCRE_ERROR_BADNEWLINE (-23) +#define PCRE_ERROR_BADOFFSET (-24) +#define PCRE_ERROR_SHORTUTF8 (-25) +#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ +#define PCRE_ERROR_RECURSELOOP (-26) +#define PCRE_ERROR_JIT_STACKLIMIT (-27) +#define PCRE_ERROR_BADMODE (-28) +#define PCRE_ERROR_BADENDIANNESS (-29) +#define PCRE_ERROR_DFA_BADRESTART (-30) + +/* Specific error codes for UTF-8 validity checks */ + +#define PCRE_UTF8_ERR0 0 +#define PCRE_UTF8_ERR1 1 +#define PCRE_UTF8_ERR2 2 +#define PCRE_UTF8_ERR3 3 +#define PCRE_UTF8_ERR4 4 +#define PCRE_UTF8_ERR5 5 +#define PCRE_UTF8_ERR6 6 +#define PCRE_UTF8_ERR7 7 +#define PCRE_UTF8_ERR8 8 +#define PCRE_UTF8_ERR9 9 +#define PCRE_UTF8_ERR10 10 +#define PCRE_UTF8_ERR11 11 +#define PCRE_UTF8_ERR12 12 +#define PCRE_UTF8_ERR13 13 +#define PCRE_UTF8_ERR14 14 +#define PCRE_UTF8_ERR15 15 +#define PCRE_UTF8_ERR16 16 +#define PCRE_UTF8_ERR17 17 +#define PCRE_UTF8_ERR18 18 +#define PCRE_UTF8_ERR19 19 +#define PCRE_UTF8_ERR20 20 +#define PCRE_UTF8_ERR21 21 + +/* Specific error codes for UTF-16 validity checks */ + +#define PCRE_UTF16_ERR0 0 +#define PCRE_UTF16_ERR1 1 +#define PCRE_UTF16_ERR2 2 +#define PCRE_UTF16_ERR3 3 +#define PCRE_UTF16_ERR4 4 /* Request types for pcre_fullinfo() */ @@ -183,6 +233,9 @@ #define PCRE_INFO_JCHANGED 13 #define PCRE_INFO_HASCRORLF 14 #define PCRE_INFO_MINLENGTH 15 +#define PCRE_INFO_JIT 16 +#define PCRE_INFO_JITSIZE 17 +#define PCRE_INFO_MAXLOOKBEHIND 18 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -196,8 +249,18 @@ #define PCRE_CONFIG_UNICODE_PROPERTIES 6 #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 #define PCRE_CONFIG_BSR 8 +#define PCRE_CONFIG_JIT 9 +#define PCRE_CONFIG_UTF16 10 +#define PCRE_CONFIG_JITTARGET 11 -/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine +/* Request types for pcre_study(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_STUDY_JIT_COMPILE 0x0001 +#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 +#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 + +/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 @@ -206,12 +269,33 @@ #define PCRE_EXTRA_TABLES 0x0008 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 #define PCRE_EXTRA_MARK 0x0020 +#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; +struct real_pcre16; /* declaration; the definition is private */ +typedef struct real_pcre16 pcre16; + +struct real_pcre_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre_jit_stack pcre_jit_stack; + +struct real_pcre16_jit_stack; /* declaration; the definition is private */ +typedef struct real_pcre16_jit_stack pcre16_jit_stack; + +/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain +a 16 bit wide signed data type. Otherwise it can be a dummy data type since +pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ +#ifndef PCRE_UCHAR16 +#define PCRE_UCHAR16 unsigned short +#endif + +#ifndef PCRE_SPTR16 +#define PCRE_SPTR16 const PCRE_UCHAR16 * +#endif + /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ @@ -232,8 +316,22 @@ const unsigned char *tables; /* Pointer to character tables */ unsigned long int match_limit_recursion; /* Max recursive calls to match() */ unsigned char **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre_extra; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ + unsigned long int match_limit_recursion; /* Max recursive calls to match() */ + PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ + void *executable_jit; /* Contains a pointer to a compiled jit code */ +} pcre16_extra; + /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work @@ -254,9 +352,33 @@ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const unsigned char *mark; /* Pointer to current mark or NULL */ /* ------------------------------------------------------------------ */ } pcre_callout_block; +/* Same structure as above, but with 16 bit char pointers. */ + +typedef struct pcre16_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR16 subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------- Added for Version 2 -------------------------- */ + const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ + /* ------------------------------------------------------------------ */ +} pcre16_callout_block; + /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function @@ -269,47 +391,114 @@ PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre_stack_free)(void *); PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); + +PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_free)(void *); +PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre16_stack_free)(void *); +PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); PCRE_EXP_DECL void *pcre_stack_malloc(size_t); PCRE_EXP_DECL void pcre_stack_free(void *); PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); + +PCRE_EXP_DECL void *pcre16_malloc(size_t); +PCRE_EXP_DECL void pcre16_free(void *); +PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); +PCRE_EXP_DECL void pcre16_stack_free(void *); +PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); #endif /* VPCOMPAT */ +/* User defined callback which provides a stack just before the match starts. */ + +typedef pcre_jit_stack *(*pcre_jit_callback)(void *); +typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); + /* Exported PCRE functions */ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, + const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); +PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, + int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); +PCRE_EXP_DECL int pcre16_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); -PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, - int); +PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); +PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, + char *, int); +PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, + PCRE_UCHAR16 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); +PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); +PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, + PCRE_SPTR16, int, int, int, int *, int); PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); +PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, + void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); +PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, + int *, int, PCRE_SPTR16, PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); +PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); +PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, + PCRE_UCHAR16 **, PCRE_UCHAR16 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); +PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, + PCRE_SPTR16 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); -PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); +PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, + PCRE_SPTR16 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); +PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); +PCRE_EXP_DECL void pcre_free_study(pcre_extra *); +PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); PCRE_EXP_DECL const char *pcre_version(void); +PCRE_EXP_DECL const char *pcre16_version(void); + +/* Utility functions for byte order swaps. */ +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, + const unsigned char *); +PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, + PCRE_SPTR16, int, int *, int); + +/* JIT compiler related functions. */ + +PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); +PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); +PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); +PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); +PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, + pcre_jit_callback, void *); +PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, + pcre16_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ diff -Nru pcre3-8.12/pcre16_byte_order.c pcre3-8.31/pcre16_byte_order.c --- pcre3-8.12/pcre16_byte_order.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_byte_order.c 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_byte_order.c" + +/* End of pcre16_byte_order.c */ diff -Nru pcre3-8.12/pcre16_chartables.c pcre3-8.31/pcre16_chartables.c --- pcre3-8.12/pcre16_chartables.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_chartables.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_chartables.c" + +/* End of pcre16_chartables.c */ diff -Nru pcre3-8.12/pcre16_compile.c pcre3-8.31/pcre16_compile.c --- pcre3-8.12/pcre16_compile.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_compile.c 2011-12-28 16:57:46.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_compile.c" + +/* End of pcre16_compile.c */ diff -Nru pcre3-8.12/pcre16_config.c pcre3-8.31/pcre16_config.c --- pcre3-8.12/pcre16_config.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_config.c 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_config.c" + +/* End of pcre16_config.c */ diff -Nru pcre3-8.12/pcre16_dfa_exec.c pcre3-8.31/pcre16_dfa_exec.c --- pcre3-8.12/pcre16_dfa_exec.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_dfa_exec.c 2011-12-28 16:57:46.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_dfa_exec.c" + +/* End of pcre16_dfa_exec.c */ diff -Nru pcre3-8.12/pcre16_exec.c pcre3-8.31/pcre16_exec.c --- pcre3-8.12/pcre16_exec.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_exec.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_exec.c" + +/* End of pcre16_exec.c */ diff -Nru pcre3-8.12/pcre16_fullinfo.c pcre3-8.31/pcre16_fullinfo.c --- pcre3-8.12/pcre16_fullinfo.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_fullinfo.c 2011-12-28 16:57:56.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_fullinfo.c" + +/* End of pcre16_fullinfo.c */ diff -Nru pcre3-8.12/pcre16_get.c pcre3-8.31/pcre16_get.c --- pcre3-8.12/pcre16_get.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_get.c 2011-12-28 16:57:50.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_get.c" + +/* End of pcre16_get.c */ diff -Nru pcre3-8.12/pcre16_globals.c pcre3-8.31/pcre16_globals.c --- pcre3-8.12/pcre16_globals.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_globals.c 2011-12-28 16:57:50.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_globals.c" + +/* End of pcre16_globals.c */ diff -Nru pcre3-8.12/pcre16_jit_compile.c pcre3-8.31/pcre16_jit_compile.c --- pcre3-8.12/pcre16_jit_compile.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_jit_compile.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_jit_compile.c" + +/* End of pcre16_jit_compile.c */ diff -Nru pcre3-8.12/pcre16_maketables.c pcre3-8.31/pcre16_maketables.c --- pcre3-8.12/pcre16_maketables.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_maketables.c 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_maketables.c" + +/* End of pcre16_maketables.c */ diff -Nru pcre3-8.12/pcre16_newline.c pcre3-8.31/pcre16_newline.c --- pcre3-8.12/pcre16_newline.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_newline.c 2011-12-28 16:57:46.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_newline.c" + +/* End of pcre16_newline.c */ diff -Nru pcre3-8.12/pcre16_ord2utf16.c pcre3-8.31/pcre16_ord2utf16.c --- pcre3-8.12/pcre16_ord2utf16.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_ord2utf16.c 2011-12-28 16:57:46.000000000 +0000 @@ -0,0 +1,95 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This file contains a private PCRE function that converts an ordinal +character value into a UTF16 string. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_internal.h" + +/************************************************* +* Convert character value to UTF-16 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x10ffff +and encodes it as a UTF-16 character in 1 to 2 pcre_uchars. + +Arguments: + cvalue the character value + buffer pointer to buffer for result - at least 2 pcre_uchars long + +Returns: number of characters placed in the buffer +*/ + +int +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) +{ +#ifdef SUPPORT_UTF + +/* Checking invalid cvalue character, encoded as invalid UTF-16 character. +Should never happen in practice. */ +if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) + cvalue = 0xfffe; + +if (cvalue <= 0xffff) + { + *buffer = (pcre_uchar)cvalue; + return 1; + } + +cvalue -= 0x10000; +*buffer++ = 0xd800 | (cvalue >> 10); +*buffer = 0xdc00 | (cvalue & 0x3ff); +return 2; + +#else /* SUPPORT_UTF */ +(void)(cvalue); /* Keep compiler happy; this function won't ever be */ +(void)(buffer); /* called when SUPPORT_UTF is not defined. */ +return 0; +#endif /* SUPPORT_UTF */ +} + +/* End of pcre16_ord2utf16.c */ diff -Nru pcre3-8.12/pcre16_printint.c pcre3-8.31/pcre16_printint.c --- pcre3-8.12/pcre16_printint.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_printint.c 2011-12-28 16:57:50.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_printint.c" + +/* End of pcre16_printint.c */ diff -Nru pcre3-8.12/pcre16_refcount.c pcre3-8.31/pcre16_refcount.c --- pcre3-8.12/pcre16_refcount.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_refcount.c 2011-12-28 16:57:58.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_refcount.c" + +/* End of pcre16_refcount.c */ diff -Nru pcre3-8.12/pcre16_string_utils.c pcre3-8.31/pcre16_string_utils.c --- pcre3-8.12/pcre16_string_utils.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_string_utils.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_string_utils.c" + +/* End of pcre16_string_utils.c */ diff -Nru pcre3-8.12/pcre16_study.c pcre3-8.31/pcre16_study.c --- pcre3-8.12/pcre16_study.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_study.c 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_study.c" + +/* End of pcre16_study.c */ diff -Nru pcre3-8.12/pcre16_tables.c pcre3-8.31/pcre16_tables.c --- pcre3-8.12/pcre16_tables.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_tables.c 2011-12-28 16:57:50.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_tables.c" + +/* End of pcre16_tables.c */ diff -Nru pcre3-8.12/pcre16_ucd.c pcre3-8.31/pcre16_ucd.c --- pcre3-8.12/pcre16_ucd.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_ucd.c 2011-12-28 16:57:58.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_ucd.c" + +/* End of pcre16_ucd.c */ diff -Nru pcre3-8.12/pcre16_utf16_utils.c pcre3-8.31/pcre16_utf16_utils.c --- pcre3-8.12/pcre16_utf16_utils.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_utf16_utils.c 2012-01-10 14:05:14.000000000 +0000 @@ -0,0 +1,129 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains a function for converting any UTF-16 character +strings to host byte order. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_internal.h" + +/************************************************* +* Convert any UTF-16 string to host byte order * +*************************************************/ + +/* This function takes an UTF-16 string and converts +it to host byte order. The length can be explicitly set, +or automatically detected for zero terminated strings. +BOMs can be kept or discarded during the conversion. +Conversion can be done in place (output == input). + +Arguments: + output the output buffer, its size must be greater + or equal than the input string + input any UTF-16 string + length the number of 16-bit units in the input string + can be less than zero for zero terminated strings + host_byte_order + A non-zero value means the input is in host byte + order, which can be dynamically changed by BOMs later. + Initially it contains the starting byte order and returns + with the last byte order so it can be used for stream + processing. It can be NULL, which set the host byte + order mode by default. + keep_boms for a non-zero value, the BOM (0xfeff) characters + are copied as well + +Returns: the number of 16-bit units placed into the output buffer, + including the zero-terminator +*/ + +int +pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input, + int length, int *host_byte_order, int keep_boms) +{ +#ifdef SUPPORT_UTF +/* This function converts any UTF-16 string to host byte order and optionally +removes any Byte Order Marks (BOMS). Returns with the remainig length. */ +int host_bo = host_byte_order != NULL ? *host_byte_order : 1; +pcre_uchar *optr = (pcre_uchar *)output; +const pcre_uchar *iptr = (const pcre_uchar *)input; +const pcre_uchar *end; +/* The c variable must be unsigned. */ +register pcre_uchar c; + +if (length < 0) + length = STRLEN_UC(iptr) + 1; +end = iptr + length; + +while (iptr < end) + { + c = *iptr++; + if (c == 0xfeff || c == 0xfffe) + { + /* Detecting the byte order of the machine is unnecessary, it is + enough to know that the UTF-16 string has the same byte order or not. */ + host_bo = c == 0xfeff; + if (keep_boms != 0) + *optr++ = 0xfeff; + else + length--; + } + else + *optr++ = host_bo ? c : ((c >> 8) | (c << 8)); /* Flip bytes if needed. */ + } +if (host_byte_order != NULL) + *host_byte_order = host_bo; + +#else /* SUPPORT_UTF */ +(void)(output); /* Keep picky compilers happy */ +(void)(input); +(void)(keep_boms); +#endif /* SUPPORT_UTF */ +return length; +} + +/* End of pcre16_utf16_utils.c */ diff -Nru pcre3-8.12/pcre16_valid_utf16.c pcre3-8.31/pcre16_valid_utf16.c --- pcre3-8.12/pcre16_valid_utf16.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_valid_utf16.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,146 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains an internal function for validating UTF-16 character +strings. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_internal.h" + + +/************************************************* +* Validate a UTF-16 string * +*************************************************/ + +/* This function is called (optionally) at the start of compile or match, to +check that a supposed UTF-16 string is actually valid. The early check means +that subsequent code can assume it is dealing with a valid string. The check +can be turned off for maximum performance, but the consequences of supplying an +invalid string are then undefined. + +From release 8.21 more information about the details of the error are passed +back in the returned value: + +PCRE_UTF16_ERR0 No error +PCRE_UTF16_ERR1 Missing low surrogate at the end of the string +PCRE_UTF16_ERR2 Invalid low surrogate +PCRE_UTF16_ERR3 Isolated low surrogate +PCRE_UTF16_ERR4 Not allowed character + +Arguments: + string points to the string + length length of string, or -1 if the string is zero-terminated + errp pointer to an error position offset variable + +Returns: = 0 if the string is a valid UTF-16 string + > 0 otherwise, setting the offset of the bad character +*/ + +int +PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset) +{ +#ifdef SUPPORT_UTF +register PCRE_PUCHAR p; +register pcre_uchar c; + +if (length < 0) + { + for (p = string; *p != 0; p++); + length = p - string; + } + +for (p = string; length-- > 0; p++) + { + c = *p; + + if ((c & 0xf800) != 0xd800) + { + /* Normal UTF-16 code point. Neither high nor low surrogate. */ + + /* This is probably a BOM from a different byte-order. + Regardless, the string is rejected. */ + if (c == 0xfffe) + { + *erroroffset = p - string; + return PCRE_UTF16_ERR4; + } + } + else if ((c & 0x0400) == 0) + { + /* High surrogate. */ + + /* Must be a followed by a low surrogate. */ + if (length == 0) + { + *erroroffset = p - string; + return PCRE_UTF16_ERR1; + } + p++; + length--; + if ((*p & 0xfc00) != 0xdc00) + { + *erroroffset = p - string; + return PCRE_UTF16_ERR2; + } + } + else + { + /* Isolated low surrogate. Always an error. */ + *erroroffset = p - string; + return PCRE_UTF16_ERR3; + } + } + +#else /* SUPPORT_UTF */ +(void)(string); /* Keep picky compilers happy */ +(void)(length); +#endif /* SUPPORT_UTF */ + +return PCRE_UTF16_ERR0; /* This indicates success */ +} + +/* End of pcre16_valid_utf16.c */ diff -Nru pcre3-8.12/pcre16_version.c pcre3-8.31/pcre16_version.c --- pcre3-8.12/pcre16_version.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_version.c 2011-12-28 16:57:59.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_version.c" + +/* End of pcre16_version.c */ diff -Nru pcre3-8.12/pcre16_xclass.c pcre3-8.31/pcre16_xclass.c --- pcre3-8.12/pcre16_xclass.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre16_xclass.c 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,45 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* Generate code with 16 bit character support. */ +#define COMPILE_PCRE16 + +#include "pcre_xclass.c" + +/* End of pcre16_xclass.c */ diff -Nru pcre3-8.12/pcre_byte_order.c pcre3-8.31/pcre_byte_order.c --- pcre3-8.12/pcre_byte_order.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre_byte_order.c 2012-01-06 12:50:34.000000000 +0000 @@ -0,0 +1,288 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains an internal function that tests a compiled pattern to +see if it was compiled with the opposite endianness. If so, it uses an +auxiliary local function to flip the appropriate bytes. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + + +/************************************************* +* Swap byte functions * +*************************************************/ + +/* The following functions swap the bytes of a pcre_uint16 +and pcre_uint32 value. + +Arguments: + value any number + +Returns: the byte swapped value +*/ + +static pcre_uint32 +swap_uint32(pcre_uint32 value) +{ +return ((value & 0x000000ff) << 24) | + ((value & 0x0000ff00) << 8) | + ((value & 0x00ff0000) >> 8) | + (value >> 24); +} + +static pcre_uint16 +swap_uint16(pcre_uint16 value) +{ +return (value >> 8) | (value << 8); +} + + +/************************************************* +* Test for a byte-flipped compiled regex * +*************************************************/ + +/* This function swaps the bytes of a compiled pattern usually +loaded form the disk. It also sets the tables pointer, which +is likely an invalid pointer after reload. + +Arguments: + argument_re points to the compiled expression + extra_data points to extra data or is NULL + tables points to the character tables or NULL + +Returns: 0 if the swap is successful, negative on error +*/ + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re, + pcre_extra *extra_data, const unsigned char *tables) +#else +PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re, + pcre16_extra *extra_data, const unsigned char *tables) +#endif +{ +REAL_PCRE *re = (REAL_PCRE *)argument_re; +pcre_study_data *study; +#ifndef COMPILE_PCRE8 +pcre_uchar *ptr; +int length; +#ifdef SUPPORT_UTF +BOOL utf; +BOOL utf16_char; +#endif /* SUPPORT_UTF */ +#endif /* !COMPILE_PCRE8 */ + +if (re == NULL) return PCRE_ERROR_NULL; +if (re->magic_number == MAGIC_NUMBER) + { + if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + re->tables = tables; + return 0; + } + +if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; +if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + +re->magic_number = MAGIC_NUMBER; +re->size = swap_uint32(re->size); +re->options = swap_uint32(re->options); +re->flags = swap_uint16(re->flags); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); +re->first_char = swap_uint16(re->first_char); +re->req_char = swap_uint16(re->req_char); +re->name_table_offset = swap_uint16(re->name_table_offset); +re->name_entry_size = swap_uint16(re->name_entry_size); +re->name_count = swap_uint16(re->name_count); +re->ref_count = swap_uint16(re->ref_count); +re->tables = tables; + +if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) + { + study = (pcre_study_data *)extra_data->study_data; + study->size = swap_uint32(study->size); + study->flags = swap_uint32(study->flags); + study->minlength = swap_uint32(study->minlength); + } + +#ifndef COMPILE_PCRE8 +ptr = (pcre_uchar *)re + re->name_table_offset; +length = re->name_count * re->name_entry_size; +#ifdef SUPPORT_UTF +utf = (re->options & PCRE_UTF16) != 0; +utf16_char = FALSE; +#endif + +while(TRUE) + { + /* Swap previous characters. */ + while (length-- > 0) + { + *ptr = swap_uint16(*ptr); + ptr++; + } +#ifdef SUPPORT_UTF + if (utf16_char) + { + if (HAS_EXTRALEN(ptr[-1])) + { + /* We know that there is only one extra character in UTF-16. */ + *ptr = swap_uint16(*ptr); + ptr++; + } + } + utf16_char = FALSE; +#endif /* SUPPORT_UTF */ + + /* Get next opcode. */ + length = 0; + *ptr = swap_uint16(*ptr); + switch (*ptr) + { + case OP_END: + return 0; + +#ifdef SUPPORT_UTF + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + if (utf) utf16_char = TRUE; +#endif + /* Fall through. */ + + default: + length = PRIV(OP_lengths)[*ptr] - 1; + break; + + case OP_CLASS: + case OP_NCLASS: + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uchar); + length = 0; + break; + + case OP_XCLASS: + /* Reverse the size of the XCLASS instance. */ + ptr++; + *ptr = swap_uint16(*ptr); + if (LINK_SIZE > 1) + { + /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ + ptr++; + *ptr = swap_uint16(*ptr); + } + ptr++; + length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1); + *ptr = swap_uint16(*ptr); + if ((*ptr & XCL_MAP) != 0) + { + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uchar); + length -= 32/sizeof(pcre_uchar); + } + break; + } + ptr++; + } +/* Control should never reach here in 16 bit mode. */ +#endif /* !COMPILE_PCRE8 */ + +return 0; +} + +/* End of pcre_byte_order.c */ diff -Nru pcre3-8.12/pcre_chartables.c.dist pcre3-8.31/pcre_chartables.c.dist --- pcre3-8.12/pcre_chartables.c.dist 2010-06-14 13:54:16.000000000 +0000 +++ pcre3-8.31/pcre_chartables.c.dist 2011-12-28 16:57:59.000000000 +0000 @@ -26,7 +26,7 @@ #include "pcre_internal.h" -const unsigned char _pcre_default_tables[] = { +const pcre_uint8 PRIV(default_tables)[] = { /* This table is a lower casing table. */ diff -Nru pcre3-8.12/pcre_compile.c pcre3-8.31/pcre_compile.c --- pcre3-8.12/pcre_compile.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_compile.c 2012-06-20 15:08:50.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -53,12 +53,16 @@ #include "pcre_internal.h" -/* When PCRE_DEBUG is defined, we need the pcre_printint() function, which is -also used by pcretest. PCRE_DEBUG is not defined when building a production -library. */ +/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which +is also used by pcretest. PCRE_DEBUG is not defined when building a production +library. We do not need to select pcre16_printint.c specially, because the +COMPILE_PCREx macro will already be appropriately set. */ #ifdef PCRE_DEBUG -#include "pcre_printint.src" +/* pcre_printint.c should not include any headers */ +#define PCRE_INCLUDED +#include "pcre_printint.c" +#undef PCRE_INCLUDED #endif @@ -88,15 +92,30 @@ The same workspace is used during the second, actual compile phase for remembering forward references to groups so that they can be filled in at the end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE -is 4 there is plenty of room. */ +is 4 there is plenty of room for most patterns. However, the memory can get +filled up by repetitions of forward references, for example patterns like +/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so +that the workspace is expanded using malloc() in this situation. The value +below is therefore a minimum, and we put a maximum on it for safety. The +minimum is now also defined in terms of LINK_SIZE so that the use of malloc() +kicks in at the same number of forward references in all cases. */ -#define COMPILE_WORK_SIZE (4096) +#define COMPILE_WORK_SIZE (2048*LINK_SIZE) +#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE) /* The overrun tests check for a slightly smaller size so that they detect the overrun before it actually does run off the end of the data block. */ -#define WORK_SIZE_CHECK (COMPILE_WORK_SIZE - 100) +#define WORK_SIZE_SAFETY_MARGIN (100) +/* Private flags added to firstchar and reqchar. */ + +#define REQ_CASELESS 0x10000000l /* Indicates caselessness */ +#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */ + +/* Repeated character flags. */ + +#define UTF_LENGTH 0x10000000l /* The char contains its length. */ /* Table for handling escaped characters in the range '0'-'z'. Positive returns are simple data values; negative values are for special things like \d and so @@ -231,7 +250,7 @@ STRING_graph0 STRING_print0 STRING_punct0 STRING_space0 STRING_word0 STRING_xdigit; -static const uschar posix_name_lengths[] = { +static const pcre_uint8 posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; /* Table of class bit maps for each POSIX class. Each class is formed from a @@ -266,47 +285,101 @@ both positive and negative cases. NULL means no substitute. */ #ifdef SUPPORT_UCP -static const uschar *substitutes[] = { - (uschar *)"\\P{Nd}", /* \D */ - (uschar *)"\\p{Nd}", /* \d */ - (uschar *)"\\P{Xsp}", /* \S */ /* NOTE: Xsp is Perl space */ - (uschar *)"\\p{Xsp}", /* \s */ - (uschar *)"\\P{Xwd}", /* \W */ - (uschar *)"\\p{Xwd}" /* \w */ +static const pcre_uchar string_PNd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pNd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXsp[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXsp[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXwd[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXwd[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static const pcre_uchar *substitutes[] = { + string_PNd, /* \D */ + string_pNd, /* \d */ + string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */ + string_pXsp, /* \s */ + string_PXwd, /* \W */ + string_pXwd /* \w */ }; -static const uschar *posix_substitutes[] = { - (uschar *)"\\p{L}", /* alpha */ - (uschar *)"\\p{Ll}", /* lower */ - (uschar *)"\\p{Lu}", /* upper */ - (uschar *)"\\p{Xan}", /* alnum */ - NULL, /* ascii */ - (uschar *)"\\h", /* blank */ - NULL, /* cntrl */ - (uschar *)"\\p{Nd}", /* digit */ - NULL, /* graph */ - NULL, /* print */ - NULL, /* punct */ - (uschar *)"\\p{Xps}", /* space */ /* NOTE: Xps is POSIX space */ - (uschar *)"\\p{Xwd}", /* word */ - NULL, /* xdigit */ +static const pcre_uchar string_pL[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pLl[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pLu[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_pXan[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_h[] = { + CHAR_BACKSLASH, CHAR_h, '\0' }; +static const pcre_uchar string_pXps[] = { + CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PL[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PLl[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PLu[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_PXan[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' }; +static const pcre_uchar string_H[] = { + CHAR_BACKSLASH, CHAR_H, '\0' }; +static const pcre_uchar string_PXps[] = { + CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET, + CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' }; + +static const pcre_uchar *posix_substitutes[] = { + string_pL, /* alpha */ + string_pLl, /* lower */ + string_pLu, /* upper */ + string_pXan, /* alnum */ + NULL, /* ascii */ + string_h, /* blank */ + NULL, /* cntrl */ + string_pNd, /* digit */ + NULL, /* graph */ + NULL, /* print */ + NULL, /* punct */ + string_pXps, /* space */ /* NOTE: Xps is POSIX space */ + string_pXwd, /* word */ + NULL, /* xdigit */ /* Negated cases */ - (uschar *)"\\P{L}", /* ^alpha */ - (uschar *)"\\P{Ll}", /* ^lower */ - (uschar *)"\\P{Lu}", /* ^upper */ - (uschar *)"\\P{Xan}", /* ^alnum */ - NULL, /* ^ascii */ - (uschar *)"\\H", /* ^blank */ - NULL, /* ^cntrl */ - (uschar *)"\\P{Nd}", /* ^digit */ - NULL, /* ^graph */ - NULL, /* ^print */ - NULL, /* ^punct */ - (uschar *)"\\P{Xps}", /* ^space */ /* NOTE: Xps is POSIX space */ - (uschar *)"\\P{Xwd}", /* ^word */ - NULL /* ^xdigit */ + string_PL, /* ^alpha */ + string_PLl, /* ^lower */ + string_PLu, /* ^upper */ + string_PXan, /* ^alnum */ + NULL, /* ^ascii */ + string_H, /* ^blank */ + NULL, /* ^cntrl */ + string_PNd, /* ^digit */ + NULL, /* ^graph */ + NULL, /* ^print */ + NULL, /* ^punct */ + string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */ + string_PXwd, /* ^word */ + NULL /* ^xdigit */ }; -#define POSIX_SUBSIZE (sizeof(posix_substitutes)/sizeof(uschar *)) +#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *)) #endif #define STRING(a) # a @@ -365,7 +438,7 @@ /* 30 */ "unknown POSIX class name\0" "POSIX collating elements are not supported\0" - "this version of PCRE is not compiled with PCRE_UTF8 support\0" + "this version of PCRE is compiled without UTF support\0" "spare error\0" /** DEAD **/ "character value in \\x{...} sequence is too large\0" /* 35 */ @@ -388,12 +461,12 @@ "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" /* 50 */ "repeated subpattern is too long\0" /** DEAD **/ - "octal value is greater than \\377 (not in UTF-8 mode)\0" + "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" "internal error: overran compiling workspace\0" "internal error: previously-checked referenced subpattern not found\0" "DEFINE group contains more than one branch\0" /* 55 */ - "repeating a DEFINE group is not allowed\0" + "repeating a DEFINE group is not allowed\0" /** DEAD **/ "inconsistent NEWLINE options\0" "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" "a numbered reference must not be zero\0" @@ -407,8 +480,18 @@ /* 65 */ "different names for subpatterns of the same number are not allowed\0" "(*MARK) must have an argument\0" - "this version of PCRE is not compiled with PCRE_UCP support\0" + "this version of PCRE is not compiled with Unicode property support\0" "\\c must be followed by an ASCII character\0" + "\\k is not followed by a braced, angle-bracketed, or quoted name\0" + /* 70 */ + "internal error: unknown opcode in find_fixedlength()\0" + "\\N is not supported in a class\0" + "too many forward references\0" + "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0" + "invalid UTF-16 string\0" + /* 75 */ + "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" + "character value in \\u.... sequence is too large\0" ; /* Table to identify digits and hex digits. This is used when compiling @@ -427,12 +510,18 @@ Then we can use ctype_digit and ctype_xdigit in the code. */ +/* Using a simple comparison for decimal numbers rather than a memory read +is much faster, and the resulting code is simpler (the compiler turns it +into a subtraction and unsigned comparison). */ + +#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9) + #ifndef EBCDIC /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in UTF-8 mode. */ -static const unsigned char digitab[] = +static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ @@ -471,7 +560,7 @@ /* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */ -static const unsigned char digitab[] = +static const pcre_uint8 digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ @@ -506,7 +595,7 @@ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ -static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ +static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ @@ -545,7 +634,7 @@ /* Definition to allow mutual recursion */ static BOOL - compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int, + compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, int *, int *, branch_chain *, compile_data *, int *); @@ -577,6 +666,78 @@ /************************************************* +* Expand the workspace * +*************************************************/ + +/* This function is called during the second compiling phase, if the number of +forward references fills the existing workspace, which is originally a block on +the stack. A larger block is obtained from malloc() unless the ultimate limit +has been reached or the increase will be rather small. + +Argument: pointer to the compile data block +Returns: 0 if all went well, else an error number +*/ + +static int +expand_workspace(compile_data *cd) +{ +pcre_uchar *newspace; +int newsize = cd->workspace_size * 2; + +if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX; +if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX || + newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN) + return ERR72; + +newspace = (PUBL(malloc))(IN_UCHARS(newsize)); +if (newspace == NULL) return ERR21; +memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar)); +cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace); +if (cd->workspace_size > COMPILE_WORK_SIZE) + (PUBL(free))((void *)cd->start_workspace); +cd->start_workspace = newspace; +cd->workspace_size = newsize; +return 0; +} + + + +/************************************************* +* Check for counted repeat * +*************************************************/ + +/* This function is called when a '{' is encountered in a place where it might +start a quantifier. It looks ahead to see if it really is a quantifier or not. +It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} +where the ddds are digits. + +Arguments: + p pointer to the first char after '{' + +Returns: TRUE or FALSE +*/ + +static BOOL +is_counted_repeat(const pcre_uchar *p) +{ +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (*p++ != CHAR_COMMA) return FALSE; +if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; + +if (!IS_DIGIT(*p)) return FALSE; +p++; +while (IS_DIGIT(*p)) p++; + +return (*p == CHAR_RIGHT_CURLY_BRACKET); +} + + + +/************************************************* * Handle escapes * *************************************************/ @@ -601,12 +762,14 @@ */ static int -check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount, +check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount, int options, BOOL isclass) { -BOOL utf8 = (options & PCRE_UTF8) != 0; -const uschar *ptr = *ptrptr + 1; -int c, i; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +const pcre_uchar *ptr = *ptrptr + 1; +pcre_int32 c; +int i; GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ ptr--; /* Set pointer back to the last byte */ @@ -620,11 +783,13 @@ Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ -else if (c < CHAR_0 || c > CHAR_z) {} /* Not alphanumeric */ +/* Not alphanumeric */ +else if (c < CHAR_0 || c > CHAR_z) {} else if ((i = escapes[c - CHAR_0]) != 0) c = i; #else /* EBCDIC coding */ -else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphanumeric */ +/* Not alphanumeric */ +else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} else if ((i = escapes[c - 0x48]) != 0) c = i; #endif @@ -632,7 +797,7 @@ else { - const uschar *oldptr; + const pcre_uchar *oldptr; BOOL braced, negated; switch (c) @@ -642,12 +807,56 @@ case CHAR_l: case CHAR_L: + *errorcodeptr = ERR37; + break; + case CHAR_u: + if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + /* In JavaScript, \u must be followed by four hexadecimal numbers. + Otherwise it is a lowercase u letter. */ + if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 + && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0 + && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0 + && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0) + { + c = 0; + for (i = 0; i < 4; ++i) + { + register int cc = *(++ptr); +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#else /* EBCDIC coding */ + if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); +#endif + } + +#ifdef COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) +#else +#ifdef COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) +#endif +#endif + { + *errorcodeptr = ERR76; + } + else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; + } + } + else + *errorcodeptr = ERR37; + break; + case CHAR_U: - *errorcodeptr = ERR37; + /* In JavaScript, \U is an uppercase U letter. */ + if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37; break; - /* \g must be followed by one of a number of specific things: + /* In a character class, \g is just a literal "g". Outside a character + class, \g must be followed by one of a number of specific things: (1) A number, either plain or braced. If positive, it is an absolute backreference. If negative, it is a relative backreference. This is a Perl @@ -664,6 +873,7 @@ the -ESC_g code (cf \k). */ case CHAR_g: + if (isclass) break; if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) { c = -ESC_g; @@ -674,9 +884,9 @@ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { - const uschar *p; + const pcre_uchar *p; for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++) - if (*p != CHAR_MINUS && (digitab[*p] & ctype_digit) == 0) break; + if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET) { c = -ESC_k; @@ -694,12 +904,21 @@ } else negated = FALSE; + /* The integer range is limited by the machine's int representation. */ c = 0; - while ((digitab[ptr[1]] & ctype_digit) != 0) + while (IS_DIGIT(ptr[1])) + { + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ + { + c = -1; + break; + } c = c * 10 + *(++ptr) - CHAR_0; - - if (c < 0) /* Integer overflow */ + } + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { + while (IS_DIGIT(ptr[1])) + ptr++; *errorcodeptr = ERR61; break; } @@ -747,11 +966,21 @@ if (!isclass) { oldptr = ptr; + /* The integer range is limited by the machine's int representation. */ c -= CHAR_0; - while ((digitab[ptr[1]] & ctype_digit) != 0) + while (IS_DIGIT(ptr[1])) + { + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ + { + c = -1; + break; + } c = c * 10 + *(++ptr) - CHAR_0; - if (c < 0) /* Integer overflow */ + } + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { + while (IS_DIGIT(ptr[1])) + ptr++; *errorcodeptr = ERR61; break; } @@ -777,32 +1006,55 @@ /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least significant 8 bits of octal numbers (I think this is what early Perls used - to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more - than 3 octal digits. */ + to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, + but no more than 3 octal digits. */ case CHAR_0: c -= CHAR_0; while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) c = c * 8 + *(++ptr) - CHAR_0; - if (!utf8 && c > 255) *errorcodeptr = ERR51; +#ifdef COMPILE_PCRE8 + if (!utf && c > 0xff) *errorcodeptr = ERR51; +#endif break; /* \x is complicated. \x{ddd} is a character number which can be greater - than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is - treated as a data character. */ + than 0xff in utf or non-8bit mode, but only if the ddd are hex digits. + If not, { is treated as a data character. */ case CHAR_x: + if ((options & PCRE_JAVASCRIPT_COMPAT) != 0) + { + /* In JavaScript, \x must be followed by two hexadecimal numbers. + Otherwise it is a lowercase x letter. */ + if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0 + && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0) + { + c = 0; + for (i = 0; i < 2; ++i) + { + register int cc = *(++ptr); +#ifndef EBCDIC /* ASCII/UTF-8 coding */ + if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ + c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); +#else /* EBCDIC coding */ + if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ + c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); +#endif + } + } + break; + } + if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { - const uschar *pt = ptr + 2; - int count = 0; + const pcre_uchar *pt = ptr + 2; c = 0; - while ((digitab[*pt] & ctype_xdigit) != 0) + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) { register int cc = *pt++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ - count++; #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ @@ -811,11 +1063,25 @@ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif + +#ifdef COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; } +#else +#ifdef COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; } +#endif +#endif + } + + if (c < 0) + { + while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; + *errorcodeptr = ERR34; } if (*pt == CHAR_RIGHT_CURLY_BRACKET) { - if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34; + if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73; ptr = pt; break; } @@ -827,7 +1093,7 @@ /* Read just a single-byte hex-defined char */ c = 0; - while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0) + while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) { int cc; /* Some compilers don't like */ cc = *(++ptr); /* ++ in initializers */ @@ -885,9 +1151,11 @@ } /* Perl supports \N{name} for character names, as well as plain \N for "not -newline". PCRE does not support \N{name}. */ +newline". PCRE does not support \N{name}. However, it does support +quantification such as \N{2,3}. */ -if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET) +if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && + !is_counted_repeat(ptr+2)) *errorcodeptr = ERR37; /* If PCRE_UCP is set, we change the values for \d etc. */ @@ -923,11 +1191,11 @@ */ static int -get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) +get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) { int c, i, bot, top; -const uschar *ptr = *ptrptr; -char name[32]; +const pcre_uchar *ptr = *ptrptr; +pcre_uchar name[32]; c = *(++ptr); if (c == 0) goto ERROR_RETURN; @@ -944,7 +1212,7 @@ *negptr = TRUE; ptr++; } - for (i = 0; i < (int)sizeof(name) - 1; i++) + for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++) { c = *(++ptr); if (c == 0) goto ERROR_RETURN; @@ -968,16 +1236,16 @@ /* Search for a recognized property name using binary chop */ bot = 0; -top = _pcre_utt_size; +top = PRIV(utt_size); while (bot < top) { i = (bot + top) >> 1; - c = strcmp(name, _pcre_utt_names + _pcre_utt[i].name_offset); + c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); if (c == 0) { - *dptr = _pcre_utt[i].value; - return _pcre_utt[i].type; + *dptr = PRIV(utt)[i].value; + return PRIV(utt)[i].type; } if (c > 0) bot = i + 1; else top = i; } @@ -997,39 +1265,6 @@ /************************************************* -* Check for counted repeat * -*************************************************/ - -/* This function is called when a '{' is encountered in a place where it might -start a quantifier. It looks ahead to see if it really is a quantifier or not. -It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} -where the ddds are digits. - -Arguments: - p pointer to the first char after '{' - -Returns: TRUE or FALSE -*/ - -static BOOL -is_counted_repeat(const uschar *p) -{ -if ((digitab[*p++] & ctype_digit) == 0) return FALSE; -while ((digitab[*p] & ctype_digit) != 0) p++; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if (*p++ != CHAR_COMMA) return FALSE; -if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE; - -if ((digitab[*p++] & ctype_digit) == 0) return FALSE; -while ((digitab[*p] & ctype_digit) != 0) p++; - -return (*p == CHAR_RIGHT_CURLY_BRACKET); -} - - - -/************************************************* * Read repeat counts * *************************************************/ @@ -1048,8 +1283,8 @@ current ptr on error, with errorcodeptr set non-zero */ -static const uschar * -read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr) +static const pcre_uchar * +read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr) { int min = 0; int max = -1; @@ -1057,7 +1292,7 @@ /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ -while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - CHAR_0; +while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0; if (min < 0 || min > 65535) { *errorcodeptr = ERR5; @@ -1072,7 +1307,7 @@ if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) { max = 0; - while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - CHAR_0; + while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0; if (max < 0 || max > 65535) { *errorcodeptr = ERR5; @@ -1127,17 +1362,17 @@ name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf8 TRUE if we are in UTF-8 mode + utf TRUE if we are in UTF-8 / UTF-16 mode count pointer to the current capturing subpattern number (updated) Returns: the number of the named subpattern, or -1 if not found */ static int -find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn, - BOOL xmode, BOOL utf8, int *count) +find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn, + BOOL xmode, BOOL utf, int *count) { -uschar *ptr = *ptrptr; +pcre_uchar *ptr = *ptrptr; int start_count = *count; int hwm_count = start_count; BOOL dup_parens = FALSE; @@ -1204,7 +1439,7 @@ ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) { int term; - const uschar *thisname; + const pcre_uchar *thisname; *count += 1; if (name == NULL && *count == lorn) return *count; term = *ptr++; @@ -1212,7 +1447,7 @@ thisname = ptr; while (*ptr != term) ptr++; if (name != NULL && lorn == ptr - thisname && - strncmp((const char *)name, (const char *)thisname, lorn) == 0) + STRNCMP_UC_UC(name, thisname, lorn) == 0) return *count; term++; } @@ -1255,7 +1490,7 @@ { if (ptr[2] == CHAR_E) ptr+= 2; - else if (strncmp((const char *)ptr+2, + else if (STRNCMP_UC_C8(ptr + 2, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 4; else @@ -1303,8 +1538,8 @@ { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } if (*ptr == 0) goto FAIL_EXIT; @@ -1315,7 +1550,7 @@ if (*ptr == CHAR_LEFT_PARENTHESIS) { - int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, count); + int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); if (rc > 0) return rc; if (*ptr == 0) goto FAIL_EXIT; } @@ -1361,16 +1596,16 @@ name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf8 TRUE if we are in UTF-8 mode + utf TRUE if we are in UTF-8 / UTF-16 mode Returns: the number of the found subpattern, or -1 if not found */ static int -find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode, - BOOL utf8) +find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode, + BOOL utf) { -uschar *ptr = (uschar *)cd->start_pattern; +pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern; int count = 0; int rc; @@ -1381,7 +1616,7 @@ for (;;) { - rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, &count); + rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); if (rc > 0 || *ptr++ == 0) break; } @@ -1397,40 +1632,30 @@ /* This is called by several functions that scan a compiled expression looking for a fixed first character, or an anchoring op code etc. It skips over things -that do not influence this. For some calls, a change of option is important. -For some calls, it makes sense to skip negative forward and all backward -assertions, and also the \b assertion; for others it does not. +that do not influence this. For some calls, it makes sense to skip negative +forward and all backward assertions, and also the \b assertion; for others it +does not. Arguments: code pointer to the start of the group - options pointer to external options - optbit the option bit whose changing is significant, or - zero if none are skipassert TRUE if certain assertions are to be skipped Returns: pointer to the first significant opcode */ -static const uschar* -first_significant_code(const uschar *code, int *options, int optbit, - BOOL skipassert) +static const pcre_uchar* +first_significant_code(const pcre_uchar *code, BOOL skipassert) { for (;;) { switch ((int)*code) { - case OP_OPT: - if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit)) - *options = (int)code[1]; - code += 2; - break; - case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); - code += _pcre_OP_lengths[*code]; + code += PRIV(OP_lengths)[*code]; break; case OP_WORD_BOUNDARY: @@ -1444,7 +1669,7 @@ case OP_RREF: case OP_NRREF: case OP_DEF: - code += _pcre_OP_lengths[*code]; + code += PRIV(OP_lengths)[*code]; break; default: @@ -1474,23 +1699,24 @@ Arguments: code points to the start of the pattern (the bracket) - options the compiling options + utf TRUE in UTF-8 / UTF-16 mode atend TRUE if called when the pattern is complete cd the "compile data" structure Returns: the fixed length, or -1 if there is no fixed length, - or -2 if \C was encountered + or -2 if \C was encountered (in UTF-8 mode only) or -3 if an OP_RECURSE item was encountered and atend is FALSE + or -4 if an unknown opcode was encountered (internal error) */ static int -find_fixedlength(uschar *code, int options, BOOL atend, compile_data *cd) +find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd) { int length = -1; register int branchlength = 0; -register uschar *cc = code + 1 + LINK_SIZE; +register pcre_uchar *cc = code + 1 + LINK_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ @@ -1498,30 +1724,39 @@ for (;;) { int d; - uschar *ce, *cs; + pcre_uchar *ce, *cs; register int op = *cc; + switch (op) { + /* We only need to continue for OP_CBRA (normal capturing bracket) and + OP_BRA (normal non-capturing bracket) because the other variants of these + opcodes are all concerned with unlimited repeated groups, which of course + are not of fixed length. */ + case OP_CBRA: case OP_BRA: case OP_ONCE: + case OP_ONCE_NC: case OP_COND: - d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options, atend, cd); + d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; - /* Reached end of a branch; if it's a ket it is the end of a nested - call. If it's ALT it is an alternation in a nested call. If it is - END it's the end of the outer call. All can be handled by the same code. */ + /* Reached end of a branch; if it's a ket it is the end of a nested call. + If it's ALT it is an alternation in a nested call. An ACCEPT is effectively + an ALT. If it is END it's the end of the outer call. All can be handled by + the same code. Note that we must not include the OP_KETRxxx opcodes here, + because they all imply an unlimited repeat. */ case OP_ALT: case OP_KET: - case OP_KETRMAX: - case OP_KETRMIN: case OP_END: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: if (length < 0) length = branchlength; else if (length != branchlength) return -1; if (*cc != OP_ALT) return length; @@ -1535,10 +1770,10 @@ case OP_RECURSE: if (!atend) return -3; - cs = ce = (uschar *)cd->start_code + GET(cc, 1); /* Start subpattern */ - do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ - if (cc > cs && cc < ce) return -1; /* Recursion */ - d = find_fixedlength(cs + 2, options, atend, cd); + cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */ + do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */ + if (cc > cs && cc < ce) return -1; /* Recursion */ + d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd); if (d < 0) return d; branchlength += d; cc += 1 + LINK_SIZE; @@ -1551,40 +1786,55 @@ case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); - /* Fall through */ + cc += PRIV(OP_lengths)[*cc]; + break; /* Skip over things that don't match chars */ - case OP_REVERSE: + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + cc += cc[1] + PRIV(OP_lengths)[*cc]; + break; + + case OP_CALLOUT: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: case OP_CREF: - case OP_NCREF: - case OP_RREF: - case OP_NRREF: case OP_DEF: - case OP_OPT: - case OP_CALLOUT: - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: + case OP_DOLL: + case OP_DOLLM: case OP_EOD: case OP_EODN: - case OP_CIRC: - case OP_DOLL: + case OP_FAIL: + case OP_NCREF: + case OP_NRREF: case OP_NOT_WORD_BOUNDARY: + case OP_PRUNE: + case OP_REVERSE: + case OP_RREF: + case OP_SET_SOM: + case OP_SKIP: + case OP_SOD: + case OP_SOM: + case OP_THEN: case OP_WORD_BOUNDARY: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; break; /* Handle literal characters */ case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: branchlength++; cc += 2; -#ifdef SUPPORT_UTF8 - if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0) - cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -1592,18 +1842,20 @@ need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: branchlength += GET2(cc,1); - cc += 4; -#ifdef SUPPORT_UTF8 - if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0) - cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); - if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2; - cc += 4; + if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; + cc += 1 + IMM2_SIZE + 1; break; /* Handle single-char matchers */ @@ -1613,6 +1865,10 @@ cc += 2; /* Fall through */ + case OP_HSPACE: + case OP_VSPACE: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: @@ -1625,25 +1881,28 @@ cc++; break; - /* The single-byte matcher isn't allowed */ + /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode; + otherwise \C is coded as OP_ALLANY. */ case OP_ANYBYTE: return -2; /* Check a class for variable quantification */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: - cc += GET(cc, 1) - 33; + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: - cc += 33; + cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { + case OP_CRPLUS: + case OP_CRMINPLUS: case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: @@ -1652,9 +1911,9 @@ case OP_CRRANGE: case OP_CRMINRANGE: - if (GET2(cc,1) != GET2(cc,3)) return -1; + if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; branchlength += GET2(cc,1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -1664,8 +1923,91 @@ /* Anything else is variable length */ - default: + case OP_ANYNL: + case OP_BRAMINZERO: + case OP_BRAPOS: + case OP_BRAPOSZERO: + case OP_BRAZERO: + case OP_CBRAPOS: + case OP_EXTUNI: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_MINQUERY: + case OP_MINQUERYI: + case OP_MINSTAR: + case OP_MINSTARI: + case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_PLUS: + case OP_PLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_POSQUERY: + case OP_POSQUERYI: + case OP_POSSTAR: + case OP_POSSTARI: + case OP_POSUPTO: + case OP_POSUPTOI: + case OP_QUERY: + case OP_QUERYI: + case OP_REF: + case OP_REFI: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + case OP_SCOND: + case OP_SKIPZERO: + case OP_STAR: + case OP_STARI: + case OP_TYPEMINPLUS: + case OP_TYPEMINQUERY: + case OP_TYPEMINSTAR: + case OP_TYPEMINUPTO: + case OP_TYPEPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSUPTO: + case OP_TYPEQUERY: + case OP_TYPESTAR: + case OP_TYPEUPTO: + case OP_UPTO: + case OP_UPTOI: return -1; + + /* Catch unrecognized opcodes so that when new ones are added they + are not forgotten, as has happened in the past. */ + + default: + return -4; } } /* Control never gets here */ @@ -1686,18 +2028,19 @@ Arguments: code points to start of expression - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode number the required bracket number or negative to find a lookbehind Returns: pointer to the opcode for the bracket, or NULL if not found */ -const uschar * -_pcre_find_bracket(const uschar *code, BOOL utf8, int number) +const pcre_uchar * +PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number) { for (;;) { register int c = *code; + if (c == OP_END) return NULL; /* XCLASS is used for classes that cannot be represented just by a bit @@ -1710,17 +2053,18 @@ else if (c == OP_REVERSE) { - if (number < 0) return (uschar *)code; - code += _pcre_OP_lengths[c]; + if (number < 0) return (pcre_uchar *)code; + code += PRIV(OP_lengths)[c]; } /* Handle capturing bracket */ - else if (c == OP_CBRA) + else if (c == OP_CBRA || c == OP_SCBRA || + c == OP_CBRAPOS || c == OP_SCBRAPOS) { int n = GET2(code, 1+LINK_SIZE); - if (n == number) return (uschar *)code; - code += _pcre_OP_lengths[c]; + if (n == number) return (pcre_uchar *)code; + code += PRIV(OP_lengths)[c]; } /* Otherwise, we can get the item's length from the table, except that for @@ -1748,7 +2092,8 @@ case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -1758,41 +2103,54 @@ break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } /* Add in the fixed length from the table */ - code += _pcre_OP_lengths[c]; + code += PRIV(OP_lengths)[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(c) +#ifdef SUPPORT_UTF + if (utf) switch(c) { case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_EXACT: + case OP_EXACTI: case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_POSQUERY: - if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; + case OP_POSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else - (void)(utf8); /* Keep compiler happy by referencing function argument */ + (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } @@ -1809,13 +2167,13 @@ Arguments: code points to start of expression - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ -static const uschar * -find_recurse(const uschar *code, BOOL utf8) +static const pcre_uchar * +find_recurse(const pcre_uchar *code, BOOL utf) { for (;;) { @@ -1854,7 +2212,8 @@ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -1864,41 +2223,82 @@ break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; } /* Add in the fixed length from the table */ - code += _pcre_OP_lengths[c]; + code += PRIV(OP_lengths)[c]; /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(c) +#ifdef SUPPORT_UTF + if (utf) switch(c) { case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: case OP_EXACT: + case OP_EXACTI: + case OP_NOTEXACT: + case OP_NOTEXACTI: case OP_UPTO: + case OP_UPTOI: + case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_MINUPTO: + case OP_MINUPTOI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: case OP_MINSTAR: + case OP_MINSTARI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_POSSTAR: + case OP_POSSTARI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: case OP_PLUS: + case OP_PLUSI: + case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_MINPLUS: + case OP_MINPLUSI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_MINQUERY: + case OP_MINQUERYI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: case OP_POSQUERY: - if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f]; + case OP_POSQUERYI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); break; } #else - (void)(utf8); /* Keep compiler happy by referencing function argument */ + (void)(utf); /* Keep compiler happy by referencing function argument */ #endif } } @@ -1921,22 +2321,22 @@ Arguments: code points to start of search endcode points to where to stop - utf8 TRUE if in UTF8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd contains pointers to tables etc. Returns: TRUE if what is matched could be empty */ static BOOL -could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8, - compile_data *cd) +could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, + BOOL utf, compile_data *cd) { register int c; -for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE); +for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); code < endcode; - code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE)) + code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) { - const uschar *ccode; + const pcre_uchar *ccode; c = *code; @@ -1950,27 +2350,34 @@ continue; } - /* Groups with zero repeats can of course be empty; skip them. */ - - if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO) - { - code += _pcre_OP_lengths[c]; - do code += GET(code, 1); while (*code == OP_ALT); - c = *code; - continue; - } - /* For a recursion/subroutine call, if its end has been reached, which - implies a subroutine call, we can scan it. */ + implies a backward reference subroutine call, we can scan it. If it's a + forward reference subroutine call, we can't. To detect forward reference + we have to scan up the list that is kept in the workspace. This function is + called only when doing the real compile, not during the pre-compile that + measures the size of the compiled pattern. */ if (c == OP_RECURSE) { - BOOL empty_branch = FALSE; - const uschar *scode = cd->start_code + GET(code, 1); + const pcre_uchar *scode; + BOOL empty_branch; + + /* Test for forward reference */ + + for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) + if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE; + + /* Not a forward reference, test for completed backward reference */ + + empty_branch = FALSE; + scode = cd->start_code + GET(code, 1); if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ + + /* Completed backwards reference */ + do { - if (could_be_empty_branch(scode, endcode, utf8, cd)) + if (could_be_empty_branch(scode, endcode, utf, cd)) { empty_branch = TRUE; break; @@ -1978,13 +2385,39 @@ scode += GET(scode, 1); } while (*scode == OP_ALT); + if (!empty_branch) return FALSE; /* All branches are non-empty */ continue; } + /* Groups with zero repeats can of course be empty; skip them. */ + + if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO || + c == OP_BRAPOSZERO) + { + code += PRIV(OP_lengths)[c]; + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + + /* A nested group that is already marked as "could be empty" can just be + skipped. */ + + if (c == OP_SBRA || c == OP_SBRAPOS || + c == OP_SCBRA || c == OP_SCBRAPOS) + { + do code += GET(code, 1); while (*code == OP_ALT); + c = *code; + continue; + } + /* For other groups, scan the branches. */ - if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND) + if (c == OP_BRA || c == OP_BRAPOS || + c == OP_CBRA || c == OP_CBRAPOS || + c == OP_ONCE || c == OP_ONCE_NC || + c == OP_COND) { BOOL empty_branch; if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ @@ -2000,7 +2433,7 @@ empty_branch = FALSE; do { - if (!empty_branch && could_be_empty_branch(code, endcode, utf8, cd)) + if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd)) empty_branch = TRUE; code += GET(code, 1); } @@ -2018,11 +2451,11 @@ { /* Check for quantifiers after a class. XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single - high-valued characters. The length in _pcre_OP_lengths[] is zero; the + high-valued characters. The length in PRIV(OP_lengths)[] is zero; the actual length is stored in the compiled code, so we must update "code" here. */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: ccode = code += GET(code, 1); goto CHECK_CLASS_REPEAT; @@ -2030,9 +2463,9 @@ case OP_CLASS: case OP_NCLASS: - ccode = code + 33; + ccode = code + PRIV(OP_lengths)[OP_CLASS]; -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 CHECK_CLASS_REPEAT: #endif @@ -2071,8 +2504,9 @@ case OP_ALLANY: case OP_ANYBYTE: case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2104,7 +2538,8 @@ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; /* End of branch */ @@ -2112,26 +2547,36 @@ case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: case OP_ALT: return TRUE; /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, MINUPTO, and POSUPTO may be followed by a multibyte character */ -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_POSQUERY: - if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f]; + case OP_POSQUERYI: + if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]); break; case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_POSUPTO: - if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f]; + case OP_POSUPTOI: + if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]); break; #endif @@ -2145,7 +2590,7 @@ break; case OP_THEN_ARG: - code += code[1+LINK_SIZE]; + code += code[1]; break; /* None of the remaining opcodes are required to match a character. */ @@ -2168,24 +2613,26 @@ the current branch of the current pattern to see if it could match the empty string. If it could, we must look outwards for branches at other levels, stopping when we pass beyond the bracket which is the subject of the recursion. +This function is called only during the real compile, not during the +pre-compile. Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts - utf8 TRUE if in UTF-8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd pointers to tables etc Returns: TRUE if what is matched could be empty */ static BOOL -could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr, - BOOL utf8, compile_data *cd) +could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode, + branch_chain *bcptr, BOOL utf, compile_data *cd) { while (bcptr != NULL && bcptr->current_branch >= code) { - if (!could_be_empty_branch(bcptr->current_branch, endcode, utf8, cd)) + if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd)) return FALSE; bcptr = bcptr->outer; } @@ -2218,6 +2665,17 @@ "l\ower". This is a lesser evil that not diagnosing bad classes when Perl does, I think. +A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. +It seems that the appearance of a nested POSIX class supersedes an apparent +external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or +a digit. + +In Perl, unescaped square brackets may also appear as part of class names. For +example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for +[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not +seem right at all. PCRE does not allow closing square brackets in POSIX class +names. + Arguments: ptr pointer to the initial [ endptr where to return the end pointer @@ -2226,20 +2684,27 @@ */ static BOOL -check_posix_syntax(const uschar *ptr, const uschar **endptr) +check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr) { int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ for (++ptr; *ptr != 0; ptr++) { - if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; else + if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + ptr++; + else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; + else { - if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE; if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { *endptr = ptr; return TRUE; } + if (*ptr == CHAR_LEFT_SQUARE_BRACKET && + (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT || + ptr[1] == CHAR_EQUALS_SIGN) && + check_posix_syntax(ptr, endptr)) + return FALSE; } } return FALSE; @@ -2263,14 +2728,14 @@ */ static int -check_posix_name(const uschar *ptr, int len) +check_posix_name(const pcre_uchar *ptr, int len) { const char *pn = posix_names; register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && - strncmp((const char *)ptr, pn, len) == 0) return yield; + STRNCMP_UC_C8(ptr, pn, len) == 0) return yield; pn += posix_name_lengths[yield] + 1; yield++; } @@ -2302,7 +2767,7 @@ Arguments: group points to the start of the group adjust the amount by which the group is to be moved - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode cd contains pointers to tables etc. save_hwm the hwm forward reference pointer at the start of the group @@ -2310,15 +2775,15 @@ */ static void -adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd, - uschar *save_hwm) +adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd, + pcre_uchar *save_hwm) { -uschar *ptr = group; +pcre_uchar *ptr = group; -while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL) +while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) { int offset; - uschar *hc; + pcre_uchar *hc; /* See if this recursion is on the forward reference list. If so, adjust the reference. */ @@ -2363,14 +2828,14 @@ Returns: new code pointer */ -static uschar * -auto_callout(uschar *code, const uschar *ptr, compile_data *cd) +static pcre_uchar * +auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd) { *code++ = OP_CALLOUT; *code++ = 255; PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ -return code + 2*LINK_SIZE; +return code + 2 * LINK_SIZE; } @@ -2392,7 +2857,7 @@ */ static void -complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd) +complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd) { int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2)); PUT(previous_callout, 2 + LINK_SIZE, length); @@ -2475,7 +2940,7 @@ prop->chartype == ucp_Lt) == negated; case PT_GC: - return (pdata == _pcre_ucp_gentype[prop->chartype]) == negated; + return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated; case PT_PC: return (pdata == prop->chartype) == negated; @@ -2486,23 +2951,23 @@ /* These are specials */ case PT_ALNUM: - return (_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == negated; + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated; case PT_SPACE: /* Perl space */ - return (_pcre_ucp_gentype[prop->chartype] == ucp_Z || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == negated; case PT_PXSPACE: /* POSIX space */ - return (_pcre_ucp_gentype[prop->chartype] == ucp_Z || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == negated; case PT_WORD: - return (_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == negated; } return FALSE; @@ -2521,7 +2986,7 @@ Arguments: previous pointer to the repeated opcode - utf8 TRUE in UTF-8 mode + utf TRUE in UTF-8 / UTF-16 mode ptr next character in pattern options options bits cd contains pointers to tables etc. @@ -2530,10 +2995,10 @@ */ static BOOL -check_auto_possessive(const uschar *previous, BOOL utf8, const uschar *ptr, - int options, compile_data *cd) +check_auto_possessive(const pcre_uchar *previous, BOOL utf, + const pcre_uchar *ptr, int options, compile_data *cd) { -int c, next; +pcre_int32 c, next; int op_code = *previous++; /* Skip whitespace and comments in extended mode */ @@ -2542,7 +3007,7 @@ { for (;;) { - while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; @@ -2550,8 +3015,8 @@ { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } } @@ -2569,15 +3034,13 @@ if (temperrorcode != 0) return FALSE; ptr++; /* Point after the escape sequence */ } - -else if ((cd->ctypes[*ptr] & ctype_meta) == 0) +else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) { -#ifdef SUPPORT_UTF8 - if (utf8) { GETCHARINC(next, ptr); } else +#ifdef SUPPORT_UTF + if (utf) { GETCHARINC(next, ptr); } else #endif next = *ptr++; } - else return FALSE; /* Skip whitespace and comments in extended mode */ @@ -2586,7 +3049,7 @@ { for (;;) { - while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++; if (*ptr == CHAR_NUMBER_SIGN) { ptr++; @@ -2594,8 +3057,8 @@ { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } } @@ -2606,7 +3069,7 @@ /* If the next thing is itself optional, we have to give up. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Now compare the next item with the previous opcode. First, handle cases when @@ -2615,26 +3078,26 @@ if (next >= 0) switch(op_code) { case OP_CHAR: -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif return c != next; - /* For CHARNC (caseless character) we must check the other case. If we have + /* For CHARI (caseless character) we must check the other case. If we have Unicode property support, we can use it to test the other case of high-valued characters. */ - case OP_CHARNC: -#ifdef SUPPORT_UTF8 + case OP_CHARI: +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif if (c == next) return FALSE; -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else @@ -2646,50 +3109,60 @@ return (unsigned int)c != othercase; } else -#endif /* SUPPORT_UTF8 */ - return (c != cd->fcc[next]); /* Non-UTF-8 mode */ - - /* For OP_NOT, its data is always a single-byte character. */ +#endif /* SUPPORT_UTF */ + return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ case OP_NOT: - if ((c = *previous) == next) return TRUE; - if ((options & PCRE_CASELESS) == 0) return FALSE; -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + return c == next; + + case OP_NOTI: +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + if (c == next) return TRUE; +#ifdef SUPPORT_UTF + if (utf) { unsigned int othercase; if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); + othercase = UCD_OTHERCASE((unsigned int)next); #else othercase = NOTACHAR; #endif return (unsigned int)c == othercase; } else -#endif /* SUPPORT_UTF8 */ - return (c == cd->fcc[next]); /* Non-UTF-8 mode */ +#endif /* SUPPORT_UTF */ + return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ case OP_DIGIT: - return next > 127 || (cd->ctypes[next] & ctype_digit) == 0; + return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; case OP_NOT_DIGIT: - return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; case OP_WHITESPACE: - return next > 127 || (cd->ctypes[next] & ctype_space) == 0; + return next > 255 || (cd->ctypes[next] & ctype_space) == 0; case OP_NOT_WHITESPACE: - return next <= 127 && (cd->ctypes[next] & ctype_space) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; case OP_WORDCHAR: - return next > 127 || (cd->ctypes[next] & ctype_word) == 0; + return next > 255 || (cd->ctypes[next] & ctype_word) == 0; case OP_NOT_WORDCHAR: - return next <= 127 && (cd->ctypes[next] & ctype_word) != 0; + return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; case OP_HSPACE: case OP_NOT_HSPACE: @@ -2758,8 +3231,8 @@ switch(op_code) { case OP_CHAR: - case OP_CHARNC: -#ifdef SUPPORT_UTF8 + case OP_CHARI: +#ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; @@ -2767,22 +3240,22 @@ switch(-next) { case ESC_d: - return c > 127 || (cd->ctypes[c] & ctype_digit) == 0; + return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; case ESC_D: - return c <= 127 && (cd->ctypes[c] & ctype_digit) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0; case ESC_s: - return c > 127 || (cd->ctypes[c] & ctype_space) == 0; + return c > 255 || (cd->ctypes[c] & ctype_space) == 0; case ESC_S: - return c <= 127 && (cd->ctypes[c] & ctype_space) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_space) != 0; case ESC_w: - return c > 127 || (cd->ctypes[c] & ctype_word) == 0; + return c > 255 || (cd->ctypes[c] & ctype_word) == 0; case ESC_W: - return c <= 127 && (cd->ctypes[c] & ctype_word) != 0; + return c <= 255 && (cd->ctypes[c] & ctype_word) != 0; case ESC_h: case ESC_H: @@ -2864,7 +3337,7 @@ to the original \d etc. At this point, ptr will point to a zero byte. */ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || - strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) + STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; /* Do the property check. */ @@ -2891,10 +3364,10 @@ return next == -ESC_d; case OP_WHITESPACE: - return next == -ESC_S || next == -ESC_d || next == -ESC_w || next == -ESC_R; + return next == -ESC_S || next == -ESC_d || next == -ESC_w; case OP_NOT_WHITESPACE: - return next == -ESC_s || next == -ESC_h || next == -ESC_v; + return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_HSPACE: return next == -ESC_S || next == -ESC_H || next == -ESC_d || @@ -2942,9 +3415,10 @@ codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorcodeptr points to error code variable - firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) - reqbyteptr set to the last literal character required, else < 0 + firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) + reqcharptr set to the last literal character required, else < 0 bcptr points to current branch chain + cond_depth conditional nesting depth cd contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase @@ -2954,44 +3428,54 @@ */ static BOOL -compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr, - int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, +compile_branch(int *optionsptr, pcre_uchar **codeptr, + const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr, + pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; -int firstbyte, reqbyte; -int zeroreqbyte, zerofirstbyte; -int req_caseopt, reqvary, tempreqvary; -int options = *optionsptr; +pcre_int32 firstchar, reqchar; +pcre_int32 zeroreqchar, zerofirstchar; +pcre_int32 req_caseopt, reqvary, tempreqvary; +int options = *optionsptr; /* May change dynamically */ int after_manual_callout = 0; int length_prevgroup = 0; register int c; -register uschar *code = *codeptr; -uschar *last_code = code; -uschar *orig_code = code; -uschar *tempcode; +register pcre_uchar *code = *codeptr; +pcre_uchar *last_code = code; +pcre_uchar *orig_code = code; +pcre_uchar *tempcode; BOOL inescq = FALSE; -BOOL groupsetfirstbyte = FALSE; -const uschar *ptr = *ptrptr; -const uschar *tempptr; -const uschar *nestptr = NULL; -uschar *previous = NULL; -uschar *previous_callout = NULL; -uschar *save_hwm = NULL; -uschar classbits[32]; - -#ifdef SUPPORT_UTF8 -BOOL class_utf8; -BOOL utf8 = (options & PCRE_UTF8) != 0; -uschar *class_utf8data; -uschar *class_utf8data_base; -uschar utf8_char[6]; +BOOL groupsetfirstchar = FALSE; +const pcre_uchar *ptr = *ptrptr; +const pcre_uchar *tempptr; +const pcre_uchar *nestptr = NULL; +pcre_uchar *previous = NULL; +pcre_uchar *previous_callout = NULL; +pcre_uchar *save_hwm = NULL; +pcre_uint8 classbits[32]; + +/* We can fish out the UTF-8 setting once and for all into a BOOL, but we +must not do this for other options (e.g. PCRE_EXTENDED) because they may change +dynamically as we process the pattern. */ + +#ifdef SUPPORT_UTF +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; +pcre_uchar utf_chars[6]; #else -BOOL utf8 = FALSE; -uschar *utf8_char = NULL; +BOOL utf = FALSE; +#endif + +/* Helper variables for OP_XCLASS opcode (for characters > 255). */ + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 +BOOL xclass; +pcre_uchar *class_uchardata; +pcre_uchar *class_uchardata_base; #endif #ifdef PCRE_DEBUG @@ -3005,22 +3489,23 @@ /* Initialize no first byte, no required byte. REQ_UNSET means "no char matching encountered yet". It gets changed to REQ_NONE if we hit something that -matches a non-fixed char first char; reqbyte just remains unset if we never +matches a non-fixed char first char; reqchar just remains unset if we never find one. When we hit a repeat whose minimum is zero, we may have to adjust these values to take the zero repeat into account. This is implemented by setting them to -zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual +zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ -firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET; +firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET; -/* The variable req_caseopt contains either the REQ_CASELESS value or zero, -according to the current setting of the caseless flag. REQ_CASELESS is a bit -value > 255. It is added into the firstbyte or reqbyte variables to record the -case status of the value. This is used only for ASCII characters. */ +/* The variable req_caseopt contains either the REQ_CASELESS value +or zero, according to the current setting of the caseless flag. The +REQ_CASELESS leaves the lower 28 bit empty. It is added into the +firstchar or reqchar variables to record the case status of the +value. This is used only for ASCII characters. */ -req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; +req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0; /* Switch on next character until the end of the branch */ @@ -3032,19 +3517,20 @@ BOOL is_quantifier; BOOL is_recurse; BOOL reset_bracount; - int class_charcount; - int class_lastchar; + int class_has_8bitchar; + int class_single_char; int newoptions; int recno; int refsign; int skipbytes; - int subreqbyte; - int subfirstbyte; + int subreqchar; + int subfirstchar; int terminator; int mclength; - uschar mcbuffer[8]; + int tempbracount; + pcre_uchar mcbuffer[8]; - /* Get next byte in the pattern */ + /* Get next character in the pattern */ c = *ptr; @@ -3066,7 +3552,8 @@ #ifdef PCRE_DEBUG if (code > cd->hwm) cd->hwm = code; /* High water info */ #endif - if (code > cd->start_workspace + WORK_SIZE_CHECK) /* Check for overrun */ + if (code > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { *errorcodeptr = ERR52; goto FAILED; @@ -3089,7 +3576,8 @@ } *lengthptr += (int)(code - last_code); - DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c)); + DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr, + (int)(code - last_code), c, c)); /* If "previous" is set and it is not at the start of the work space, move it back to there, in order to avoid filling up the work space. Otherwise, @@ -3099,7 +3587,7 @@ { if (previous > orig_code) { - memmove(orig_code, previous, code - previous); + memmove(orig_code, previous, IN_UCHARS(code - previous)); code -= previous - orig_code; previous = orig_code; } @@ -3115,7 +3603,8 @@ /* In the real compile phase, just check the workspace used by the forward reference list. */ - else if (cd->hwm > cd->start_workspace + WORK_SIZE_CHECK) + else if (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) { *errorcodeptr = ERR52; goto FAILED; @@ -3163,11 +3652,11 @@ previous_callout = NULL; } - /* In extended mode, skip white space and comments */ + /* In extended mode, skip white space and comments. */ if ((options & PCRE_EXTENDED) != 0) { - if ((cd->ctypes[c] & ctype_space) != 0) continue; + if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue; if (c == CHAR_NUMBER_SIGN) { ptr++; @@ -3175,8 +3664,8 @@ { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; -#ifdef SUPPORT_UTF8 - if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++; +#ifdef SUPPORT_UTF + if (utf) FORWARDCHAR(ptr); #endif } if (*ptr != 0) continue; @@ -3200,8 +3689,8 @@ case 0: /* The branch terminates at string end */ case CHAR_VERTICAL_LINE: /* or | or ) */ case CHAR_RIGHT_PARENTHESIS: - *firstbyteptr = firstbyte; - *reqbyteptr = reqbyte; + *firstcharptr = firstchar; + *reqcharptr = reqchar; *codeptr = code; *ptrptr = ptr; if (lengthptr != NULL) @@ -3222,26 +3711,27 @@ the setting of any following char as a first character. */ case CHAR_CIRCUMFLEX_ACCENT: + previous = NULL; if ((options & PCRE_MULTILINE) != 0) { - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + *code++ = OP_CIRCM; } - previous = NULL; - *code++ = OP_CIRC; + else *code++ = OP_CIRC; break; case CHAR_DOLLAR_SIGN: previous = NULL; - *code++ = OP_DOLL; + *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL; break; /* There can never be a first char if '.' is first, whatever happens about - repeats. The value of reqbyte doesn't change either. */ + repeats. The value of reqchar doesn't change either. */ case CHAR_DOT: - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + zeroreqchar = reqchar; previous = code; *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; break; @@ -3296,8 +3786,7 @@ { if (ptr[1] == CHAR_E) ptr++; - else if (strncmp((const char *)ptr+1, - STR_Q STR_BACKSLASH STR_E, 3) == 0) + else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0) ptr += 3; else break; @@ -3316,8 +3805,8 @@ (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) { *code++ = negate_class? OP_ALLANY : OP_FAIL; - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; break; } @@ -3327,24 +3816,25 @@ should_flip_negation = FALSE; - /* Keep a count of chars with values < 256 so that we can optimize the case - of just a single character (as long as it's < 256). However, For higher - valued UTF-8 characters, we don't yet do any optimization. */ + /* For optimization purposes, we track some properties of the class. + class_has_8bitchar will be non-zero, if the class contains at least one + < 256 character. class_single_char will be 1 if the class contains only + a single character. */ - class_charcount = 0; - class_lastchar = -1; + class_has_8bitchar = 0; + class_single_char = 0; /* Initialize the 32-char bit map to all zeros. We build the map in a temporary bit of memory, in case the class contains only 1 character (less than 256), because in that case the compiled code doesn't use the bit map. */ - memset(classbits, 0, 32 * sizeof(uschar)); + memset(classbits, 0, 32 * sizeof(pcre_uint8)); -#ifdef SUPPORT_UTF8 - class_utf8 = FALSE; /* No chars >= 256 */ - class_utf8data = code + LINK_SIZE + 2; /* For UTF-8 items */ - class_utf8data_base = class_utf8data; /* For resetting in pass 1 */ +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + xclass = FALSE; /* No chars >= 256 */ + class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */ + class_uchardata_base = class_uchardata; /* For resetting in pass 1 */ #endif /* Process characters until ] is reached. By writing this as a "do" it @@ -3353,25 +3843,26 @@ if (c != 0) do { - const uschar *oldptr; + const pcre_uchar *oldptr; -#ifdef SUPPORT_UTF8 - if (utf8 && c > 127) +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(c)) { /* Braces are required because the */ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ } +#endif - /* In the pre-compile phase, accumulate the length of any UTF-8 extra +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + /* In the pre-compile phase, accumulate the length of any extra data and reset the pointer. This is so that very large classes that - contain a zillion UTF-8 characters no longer overwrite the work space + contain a zillion > 255 characters no longer overwrite the work space (which is on the stack). */ if (lengthptr != NULL) { - *lengthptr += class_utf8data - class_utf8data_base; - class_utf8data = class_utf8data_base; + *lengthptr += class_uchardata - class_uchardata_base; + class_uchardata = class_uchardata_base; } - #endif /* Inside \Q...\E everything is literal except \E */ @@ -3399,8 +3890,8 @@ { BOOL local_negate = FALSE; int posix_class, taboffset, tabopt; - register const uschar *cbits = cd->cbits; - uschar pbits[32]; + register const pcre_uint8 *cbits = cd->cbits; + pcre_uint8 pbits[32]; if (ptr[1] != CHAR_COLON) { @@ -3455,7 +3946,7 @@ /* Copy in the first table (always present) */ memcpy(pbits, cbits + posix_class_maps[posix_class], - 32 * sizeof(uschar)); + 32 * sizeof(pcre_uint8)); /* If there is a second table, add or remove it as required. */ @@ -3486,16 +3977,20 @@ for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; ptr = tempptr + 1; - class_charcount = 10; /* Set > 1; assumes more than 1 per class */ + /* Every class contains at least one < 256 characters. */ + class_has_8bitchar = 1; + /* Every class contains at least two characters. */ + class_single_char = 2; continue; /* End of POSIX syntax handling */ } /* Backslash may introduce a single character, or it may introduce one of the specials, which just set a flag. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. We - assume that other escapes have more than one character in them, so set - class_charcount bigger than one. Unrecognized escapes fall through and - are either treated as literal characters (by default), or are faulted if + assume that other escapes have more than one character in them, so + speculatively set both class_has_8bitchar and class_single_char bigger + than one. Unrecognized escapes fall through and are either treated + as literal characters (by default), or are faulted if PCRE_EXTRA is set. */ if (c == CHAR_BACKSLASH) @@ -3504,6 +3999,11 @@ if (*errorcodeptr != 0) goto FAILED; if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ + else if (-c == ESC_N) /* \N is not supported in a class */ + { + *errorcodeptr = ERR71; + goto FAILED; + } else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) @@ -3517,8 +4017,11 @@ if (c < 0) { - register const uschar *cbits = cd->cbits; - class_charcount += 2; /* Greater than 1 is what matters */ + register const pcre_uint8 *cbits = cd->cbits; + /* Every class contains at least two < 256 characters. */ + class_has_8bitchar++; + /* Every class contains at least two characters. */ + class_single_char += 2; switch (-c) { @@ -3531,7 +4034,7 @@ case ESC_SU: nestptr = ptr; ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ - class_charcount -= 2; /* Undo! */ + class_has_8bitchar--; /* Undo! */ continue; #endif case ESC_d: @@ -3572,23 +4075,38 @@ SETBIT(classbits, 0x09); /* VT */ SETBIT(classbits, 0x20); /* SPACE */ SETBIT(classbits, 0xa0); /* NSBP */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x1680; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x180e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2000; + *class_uchardata++ = 0x200a; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x202f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x205f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x3000; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data); - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata); } #endif continue; @@ -3606,32 +4124,59 @@ } classbits[c] |= x; } - -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x167f; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x1681; + *class_uchardata++ = 0x180d; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x180f; + *class_uchardata++ = 0x1fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x200b; + *class_uchardata++ = 0x202e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2030; + *class_uchardata++ = 0x205e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2060; + *class_uchardata++ = 0x2fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x3001; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; @@ -3642,13 +4187,18 @@ SETBIT(classbits, 0x0c); /* FF */ SETBIT(classbits, 0x0d); /* CR */ SETBIT(classbits, 0x85); /* NEL */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2028; + *class_uchardata++ = 0x2029; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata); } #endif continue; @@ -3670,16 +4220,29 @@ classbits[c] |= x; } -#ifdef SUPPORT_UTF8 - if (utf8) +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x2027; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x202a; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data); - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data); - class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data); + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); } #endif continue; @@ -3692,12 +4255,12 @@ int pdata; int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); if (ptype < 0) goto FAILED; - class_utf8 = TRUE; - *class_utf8data++ = ((-c == ESC_p) != negated)? + xclass = TRUE; + *class_uchardata++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; - *class_utf8data++ = ptype; - *class_utf8data++ = pdata; - class_charcount -= 2; /* Not a < 256 character */ + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + class_has_8bitchar--; /* Undo! */ continue; } #endif @@ -3711,14 +4274,15 @@ *errorcodeptr = ERR7; goto FAILED; } - class_charcount -= 2; /* Undo the default count from above */ - c = *ptr; /* Get the final character and fall through */ + class_has_8bitchar--; /* Undo the speculative increase. */ + class_single_char -= 2; /* Undo the speculative increase. */ + c = *ptr; /* Get the final character and fall through */ break; } } /* Fall through if we have a single character (c >= 0). This may be - greater than 256 in UTF-8 mode. */ + greater than 256. */ } /* End of backslash handling */ @@ -3766,8 +4330,8 @@ goto LONE_SINGLE_CHARACTER; } -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { /* Braces are required because the */ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ } @@ -3811,22 +4375,36 @@ if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; + /* Since we found a character range, single character optimizations + cannot be done anymore. */ + class_single_char = 2; + /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless matching, we have to use an XCLASS with extra data items. Caseless matching for characters > 127 is available only if UCP support is available. */ -#ifdef SUPPORT_UTF8 - if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif defined SUPPORT_UTF + if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif !(defined COMPILE_PCRE8) + if (d > 255) +#endif +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) { - class_utf8 = TRUE; + xclass = TRUE; /* With UCP support, we can find the other case equivalents of the relevant characters. There may be several ranges. Optimize how they fit with the basic range. */ #ifdef SUPPORT_UCP +#ifndef COMPILE_PCRE8 + if (utf && (options & PCRE_CASELESS) != 0) +#else if ((options & PCRE_CASELESS) != 0) +#endif { unsigned int occ, ocd; unsigned int cc = c; @@ -3852,14 +4430,14 @@ if (occ == ocd) { - *class_utf8data++ = XCL_SINGLE; + *class_uchardata++ = XCL_SINGLE; } else { - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(occ, class_utf8data); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(occ, class_uchardata); } - class_utf8data += _pcre_ord2utf8(ocd, class_utf8data); + class_uchardata += PRIV(ord2utf)(ocd, class_uchardata); } } #endif /* SUPPORT_UCP */ @@ -3867,33 +4445,69 @@ /* Now record the original range, possibly modified for UCP caseless overlapping ranges. */ - *class_utf8data++ = XCL_RANGE; - class_utf8data += _pcre_ord2utf8(c, class_utf8data); - class_utf8data += _pcre_ord2utf8(d, class_utf8data); + *class_uchardata++ = XCL_RANGE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + if (utf) + { + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); + } + else + { + *class_uchardata++ = c; + *class_uchardata++ = d; + } +#else + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); +#endif +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; + *class_uchardata++ = d; +#endif /* SUPPORT_UTF */ /* With UCP support, we are done. Without UCP support, there is no - caseless matching for UTF-8 characters > 127; we can use the bit map - for the smaller ones. */ + caseless matching for UTF characters > 127; we can use the bit map + for the smaller ones. As for 16 bit characters without UTF, we + can still use */ #ifdef SUPPORT_UCP - continue; /* With next character in the class */ -#else - if ((options & PCRE_CASELESS) == 0 || c > 127) continue; +#ifndef COMPILE_PCRE8 + if (utf) +#endif + continue; /* With next character in the class */ +#endif /* SUPPORT_UCP */ +#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8) + if (utf) + { + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 127; + } + else + { + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; + } +#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP) + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; /* Adjust upper limit and fall through to set up the map */ - d = 127; - -#endif /* SUPPORT_UCP */ +#else + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; +#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */ } -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ - /* We use the bit map for all cases when not in UTF-8 mode; else - ranges that lie entirely within 0-127 when there is UCP support; else - for partial ranges without UCP support. */ + /* We use the bit map for 8 bit mode, or when the characters fall + partially or entirely to [0-255] ([0-127] for UCP) ranges. */ - class_charcount += d - c + 1; - class_lastchar = d; + class_has_8bitchar = 1; /* We can save a bit of time by skipping this in the pre-compile. */ @@ -3902,7 +4516,7 @@ classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { - int uc = cd->fcc[c]; /* flip case */ + int uc = cd->fcc[c]; /* flip case */ classbits[uc/8] |= (1 << (uc&7)); } } @@ -3916,41 +4530,110 @@ LONE_SINGLE_CHARACTER: - /* Handle a character that cannot go in the bit map */ + /* Only the value of 1 matters for class_single_char. */ + + if (class_single_char < 2) class_single_char++; + + /* If class_charcount is 1, we saw precisely one character. As long as + there was no use of \p or \P, in other words, no use of any XCLASS + features, we can optimize. + + The optimization throws away the bit map. We turn the item into a + 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative. + In the positive case, it can cause firstchar to be set. Otherwise, there + can be no first char if this item is first, whatever repeat count may + follow. In the case of reqchar, save the previous value for reinstating. */ -#ifdef SUPPORT_UTF8 - if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) + if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { - class_utf8 = TRUE; - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(c, class_utf8data); + ptr++; + zeroreqchar = reqchar; + + if (negate_class) + { + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + code += PRIV(ord2utf)(c, code); + else +#endif + *code++ = c; + goto NOT_CHAR; + } + + /* For a single, positive character, get the value into mcbuffer, and + then we can handle this with the normal one-character code. */ + +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + mclength = PRIV(ord2utf)(c, mcbuffer); + else +#endif + { + mcbuffer[0] = c; + mclength = 1; + } + goto ONE_CHAR; + } /* End of 1-char optimization */ + + /* Handle a character that cannot go in the bit map. */ + +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif defined SUPPORT_UTF + if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif !(defined COMPILE_PCRE8) + if (c > 255) +#endif + +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + { + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (!utf) + *class_uchardata++ = c; + else +#endif + class_uchardata += PRIV(ord2utf)(c, class_uchardata); +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; +#endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP +#ifdef COMPILE_PCRE8 if ((options & PCRE_CASELESS) != 0) +#else + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (utf && (options & PCRE_CASELESS) != 0) +#endif { unsigned int othercase; - if ((othercase = UCD_OTHERCASE(c)) != c) + if ((int)(othercase = UCD_OTHERCASE(c)) != c) { - *class_utf8data++ = XCL_SINGLE; - class_utf8data += _pcre_ord2utf8(othercase, class_utf8data); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(othercase, class_uchardata); } } #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ /* Handle a single-byte character */ { + class_has_8bitchar = 1; classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { - c = cd->fcc[c]; /* flip case */ + c = cd->fcc[c]; /* flip case */ classbits[c/8] |= (1 << (c&7)); } - class_charcount++; - class_lastchar = c; } } @@ -3971,66 +4654,13 @@ goto FAILED; } - /* If class_charcount is 1, we saw precisely one character whose value is - less than 256. As long as there were no characters >= 128 and there was no - use of \p or \P, in other words, no use of any XCLASS features, we can - optimize. - - In UTF-8 mode, we can optimize the negative case only if there were no - characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR - operate on single-bytes only. This is an historical hangover. Maybe one day - we can tidy these opcodes to handle multi-byte characters. - - The optimization throws away the bit map. We turn the item into a - 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note - that OP_NOT does not support multibyte characters. In the positive case, it - can cause firstbyte to be set. Otherwise, there can be no first char if - this item is first, whatever repeat count may follow. In the case of - reqbyte, save the previous value for reinstating. */ - -#ifdef SUPPORT_UTF8 - if (class_charcount == 1 && !class_utf8 && - (!utf8 || !negate_class || class_lastchar < 128)) -#else - if (class_charcount == 1) -#endif - { - zeroreqbyte = reqbyte; - - /* The OP_NOT opcode works on one-byte characters only. */ - - if (negate_class) - { - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - *code++ = OP_NOT; - *code++ = class_lastchar; - break; - } - - /* For a single, positive character, get the value into mcbuffer, and - then we can handle this with the normal one-character code. */ - -#ifdef SUPPORT_UTF8 - if (utf8 && class_lastchar > 127) - mclength = _pcre_ord2utf8(class_lastchar, mcbuffer); - else -#endif - { - mcbuffer[0] = class_lastchar; - mclength = 1; - } - goto ONE_CHAR; - } /* End of 1-char optimization */ - - /* The general case - not the one-char optimization. If this is the first - thing in the branch, there can be no first char setting, whatever the - repeat count. Any reqbyte setting must remain unchanged after any kind of - repeat. */ - - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + /* If this is the first thing in the branch, there can be no first char + setting, whatever the repeat count. Any reqchar setting must remain + unchanged after any kind of repeat. */ + + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; + zerofirstchar = firstchar; + zeroreqchar = reqchar; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode, unless there was a negated special @@ -4040,29 +4670,34 @@ be listed) there are no characters < 256, we can omit the bitmap in the actual compiled code. */ -#ifdef SUPPORT_UTF8 - if (class_utf8 && (!should_flip_negation || (options & PCRE_UCP) != 0)) +#ifdef SUPPORT_UTF + if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0)) +#elif !defined COMPILE_PCRE8 + if (xclass && !should_flip_negation) +#endif +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 { - *class_utf8data++ = XCL_END; /* Marks the end of extra data */ + *class_uchardata++ = XCL_END; /* Marks the end of extra data */ *code++ = OP_XCLASS; code += LINK_SIZE; - *code = negate_class? XCL_NOT : 0; + *code = negate_class? XCL_NOT:0; /* If the map is required, move up the extra data to make room for it; otherwise just move the code pointer to the end of the extra data. */ - if (class_charcount > 0) + if (class_has_8bitchar > 0) { *code++ |= XCL_MAP; - memmove(code + 32, code, class_utf8data - code); + memmove(code + (32 / sizeof(pcre_uchar)), code, + IN_UCHARS(class_uchardata - code)); memcpy(code, classbits, 32); - code = class_utf8data + 32; + code = class_uchardata + (32 / sizeof(pcre_uchar)); } - else code = class_utf8data; + else code = class_uchardata; /* Now fill in the complete length of the item */ - PUT(previous, 1, code - previous); + PUT(previous, 1, (int)(code - previous)); break; /* End of class handling */ } #endif @@ -4074,16 +4709,14 @@ negating it if necessary. */ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; - if (negate_class) - { - if (lengthptr == NULL) /* Save time in the pre-compile phase */ - for (c = 0; c < 32; c++) code[c] = ~classbits[c]; - } - else + if (lengthptr == NULL) /* Save time in the pre-compile phase */ { + if (negate_class) + for (c = 0; c < 32; c++) classbits[c] = ~classbits[c]; memcpy(code, classbits, 32); } - code += 32; + code += 32 / sizeof(pcre_uchar); + NOT_CHAR: break; @@ -4120,8 +4753,8 @@ if (repeat_min == 0) { - firstbyte = zerofirstbyte; /* Adjust for zero repeat */ - reqbyte = zeroreqbyte; /* Ditto */ + firstchar = zerofirstchar; /* Adjust for zero repeat */ + reqchar = zeroreqchar; /* Ditto */ } /* Remember whether this is a variable length repeat */ @@ -4131,8 +4764,8 @@ op_type = 0; /* Default single-char op codes */ possessive_quantifier = FALSE; /* Default not possessive quantifier */ - /* Save start of previous item, in case we have to move it up to make space - for an inserted OP_ONCE for the additional '+' extension. */ + /* Save start of previous item, in case we have to move it up in order to + insert something before it. */ tempcode = previous; @@ -4155,37 +4788,76 @@ } else repeat_type = greedy_default; - /* If previous was a character match, abolish the item and generate a - repeat item instead. If a char item has a minumum of more than one, ensure - that it is set in reqbyte - it might not be if a sequence such as x{3} is - the first thing in a branch because the x will have gone into firstbyte - instead. */ + /* If previous was a recursion call, wrap it in atomic brackets so that + previous becomes the atomic group. All recursions were so wrapped in the + past, but it no longer happens for non-repeated recursions. In fact, the + repeated ones could be re-implemented independently so as not to need this, + but for the moment we rely on the code for repeating groups. */ - if (*previous == OP_CHAR || *previous == OP_CHARNC) + if (*previous == OP_RECURSE) { - /* Deal with UTF-8 characters that take up more than one byte. It's + memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE)); + *previous = OP_ONCE; + PUT(previous, 1, 2 + 2*LINK_SIZE); + previous[2 + 2*LINK_SIZE] = OP_KET; + PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE); + code += 2 + 2 * LINK_SIZE; + length_prevgroup = 3 + 3*LINK_SIZE; + + /* When actually compiling, we need to check whether this was a forward + reference, and if so, adjust the offset. */ + + if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE) + { + int offset = GET(cd->hwm, -LINK_SIZE); + if (offset == previous + 1 - cd->start_code) + PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE); + } + } + + /* Now handle repetition for the different types of item. */ + + /* If previous was a character or negated character match, abolish the item + and generate a repeat item instead. If a char item has a minimum of more + than one, ensure that it is set in reqchar - it might not be if a sequence + such as x{3} is the first thing in a branch because the x will have gone + into firstchar instead. */ + + if (*previous == OP_CHAR || *previous == OP_CHARI + || *previous == OP_NOT || *previous == OP_NOTI) + { + switch (*previous) + { + default: /* Make compiler happy. */ + case OP_CHAR: op_type = OP_STAR - OP_STAR; break; + case OP_CHARI: op_type = OP_STARI - OP_STAR; break; + case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break; + case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break; + } + + /* Deal with UTF characters that take up more than one character. It's easier to write this out separately than try to macrify it. Use c to - hold the length of the character in bytes, plus 0x80 to flag that it's a - length rather than a small character. */ + hold the length of the character in bytes, plus UTF_LENGTH to flag that + it's a length rather than a small character. */ -#ifdef SUPPORT_UTF8 - if (utf8 && (code[-1] & 0x80) != 0) +#ifdef SUPPORT_UTF + if (utf && NOT_FIRSTCHAR(code[-1])) { - uschar *lastchar = code - 1; - while((*lastchar & 0xc0) == 0x80) lastchar--; - c = code - lastchar; /* Length of UTF-8 character */ - memcpy(utf8_char, lastchar, c); /* Save the char */ - c |= 0x80; /* Flag c as a length */ + pcre_uchar *lastchar = code - 1; + BACKCHAR(lastchar); + c = (int)(code - lastchar); /* Length of UTF-8 character */ + memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */ + c |= UTF_LENGTH; /* Flag c as a length */ } else -#endif - - /* Handle the case of a single byte - either with no UTF8 support, or - with UTF-8 disabled, or for a UTF-8 character < 128. */ +#endif /* SUPPORT_UTF */ + /* Handle the case of a single charater - either with no UTF support, or + with UTF disabled, or for a single character UTF character. */ { c = code[-1]; - if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt; + if (*previous <= OP_CHARI && repeat_min > 1) + reqchar = c | req_caseopt | cd->req_varyopt; } /* If the repetition is unlimited, it pays to see if the next thing on @@ -4195,7 +4867,7 @@ if (!possessive_quantifier && repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) + check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; @@ -4204,26 +4876,6 @@ goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } - /* If previous was a single negated character ([^a] or similar), we use - one of the special opcodes, replacing it. The code is shared with single- - character repeats by setting opt_type to add a suitable offset into - repeat_type. We can also test for auto-possessification. OP_NOT is - currently used only for single-byte chars. */ - - else if (*previous == OP_NOT) - { - op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ - c = previous[1]; - if (!possessive_quantifier && - repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) - { - repeat_type = 0; /* Force greedy */ - possessive_quantifier = TRUE; - } - goto OUTPUT_SINGLE_REPEAT; - } - /* If previous was a character type match (\d or similar), abolish it and create a suitable repeat item. The code is shared with single-character repeats by setting op_type to add a suitable offset into repeat_type. Note @@ -4233,14 +4885,14 @@ else if (*previous < OP_EODN) { - uschar *oldcode; + pcre_uchar *oldcode; int prop_type, prop_value; op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; if (!possessive_quantifier && repeat_max < 0 && - check_auto_possessive(previous, utf8, ptr + 1, options, cd)) + check_auto_possessive(previous, utf, ptr + 1, options, cd)) { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; @@ -4320,14 +4972,14 @@ we have to insert the character for the previous code. For a repeated Unicode property match, there are two extra bytes that define the required property. In UTF-8 mode, long characters have their length in - c, with the 0x80 bit as a flag. */ + c, with the UTF_LENGTH bit as a flag. */ if (repeat_max < 0) { -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4349,10 +5001,10 @@ else if (repeat_max != repeat_min) { -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4379,10 +5031,10 @@ /* The character or character type itself comes last in all cases. */ -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 128) +#ifdef SUPPORT_UTF + if (utf && (c & UTF_LENGTH) != 0) { - memcpy(code, utf8_char, c & 7); + memcpy(code, utf_chars, IN_UCHARS(c & 7)); code += c & 7; } else @@ -4406,10 +5058,11 @@ else if (*previous == OP_CLASS || *previous == OP_NCLASS || -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 *previous == OP_XCLASS || #endif - *previous == OP_REF) + *previous == OP_REF || + *previous == OP_REFI) { if (repeat_max == 0) { @@ -4443,35 +5096,35 @@ } /* If previous was a bracket group, we may have to replicate it in certain - cases. */ + cases. Note that at this point we can encounter only the "basic" bracket + opcodes such as BRA and CBRA, as this is the place where they get converted + into the more special varieties such as BRAPOS and SBRA. A test for >= + OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK, + ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow + repetition of assertions, but now it does, for Perl compatibility. */ - else if (*previous == OP_BRA || *previous == OP_CBRA || - *previous == OP_ONCE || *previous == OP_COND) + else if (*previous >= OP_ASSERT && *previous <= OP_COND) { register int i; - int ketoffset = 0; int len = (int)(code - previous); - uschar *bralink = NULL; + pcre_uchar *bralink = NULL; + pcre_uchar *brazeroptr = NULL; - /* Repeating a DEFINE group is pointless */ + /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so + we just ignore the repeat. */ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF) - { - *errorcodeptr = ERR55; - goto FAILED; - } + goto END_REPEAT; + + /* There is no sense in actually repeating assertions. The only potential + use of repetition is in cases when the assertion is optional. Therefore, + if the minimum is greater than zero, just ignore the repeat. If the + maximum is not not zero or one, set it to 1. */ - /* If the maximum repeat count is unlimited, find the end of the bracket - by scanning through from the start, and compute the offset back to it - from the current code pointer. There may be an OP_OPT setting following - the final KET, so we can't find the end just by going back from the code - pointer. */ - - if (repeat_max == -1) - { - register uschar *ket = previous; - do ket += GET(ket, 1); while (*ket != OP_KET); - ketoffset = (int)(code - ket); + if (*previous < OP_ONCE) /* Assertion */ + { + if (repeat_min > 0) goto END_REPEAT; + if (repeat_max < 0 || repeat_max > 1) repeat_max = 1; } /* The case of a zero minimum is special because of the need to stick @@ -4492,10 +5145,11 @@ ** goto END_REPEAT; ** } - However, that fails when a group is referenced as a subroutine from - elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it - so that it is skipped on execution. As we don't have a list of which - groups are referenced, we cannot do this selectively. + However, that fails when a group or a subgroup within it is referenced + as a subroutine from elsewhere in the pattern, so now we stick in + OP_SKIPZERO in front of it so that it is skipped on execution. As we + don't have a list of which groups are referenced, we cannot do this + selectively. If the maximum is 1 or unlimited, we just have to stick in the BRAZERO and do no more at this point. However, we do need to adjust any @@ -4507,14 +5161,15 @@ if (repeat_max <= 1) /* Covers 0, 1, and unlimited */ { *code = OP_END; - adjust_recurse(previous, 1, utf8, cd, save_hwm); - memmove(previous+1, previous, len); + adjust_recurse(previous, 1, utf, cd, save_hwm); + memmove(previous + 1, previous, IN_UCHARS(len)); code++; if (repeat_max == 0) { *previous++ = OP_SKIPZERO; goto END_REPEAT; } + brazeroptr = previous; /* Save for possessive optimizing */ *previous++ = OP_BRAZERO + repeat_type; } @@ -4530,8 +5185,8 @@ { int offset; *code = OP_END; - adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm); - memmove(previous + 2 + LINK_SIZE, previous, len); + adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm); + memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len)); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; @@ -4577,16 +5232,32 @@ *lengthptr += delta; } - /* This is compiling for real */ + /* This is compiling for real. If there is a set first byte for + the group, and we have not yet set a "required byte", set it. Make + sure there is enough workspace for copying forward references before + doing the copy. */ else { - if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte; + if (groupsetfirstchar && reqchar < 0) reqchar = firstchar; + for (i = 1; i < repeat_min; i++) { - uschar *hc; - uschar *this_hwm = cd->hwm; - memcpy(code, previous, len); + pcre_uchar *hc; + pcre_uchar *this_hwm = cd->hwm; + memcpy(code, previous, IN_UCHARS(len)); + + while (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) + { + int save_offset = save_hwm - cd->start_workspace; + int this_offset = this_hwm - cd->start_workspace; + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; + this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; + } + for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len); @@ -4636,8 +5307,8 @@ else for (i = repeat_max - 1; i >= 0; i--) { - uschar *hc; - uschar *this_hwm = cd->hwm; + pcre_uchar *hc; + pcre_uchar *this_hwm = cd->hwm; *code++ = OP_BRAZERO + repeat_type; @@ -4653,7 +5324,22 @@ PUTINC(code, 0, offset); } - memcpy(code, previous, len); + memcpy(code, previous, IN_UCHARS(len)); + + /* Ensure there is enough workspace for forward references before + copying them. */ + + while (cd->hwm > cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm)) + { + int save_offset = save_hwm - cd->start_workspace; + int this_offset = this_hwm - cd->start_workspace; + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + save_hwm = (pcre_uchar *)cd->start_workspace + save_offset; + this_hwm = (pcre_uchar *)cd->start_workspace + this_offset; + } + for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE) { PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1)); @@ -4670,7 +5356,7 @@ { int oldlinkoffset; int offset = (int)(code - bralink + 1); - uschar *bra = code - offset; + pcre_uchar *bra = code - offset; oldlinkoffset = GET(bra, 1); bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; *code++ = OP_KET; @@ -4679,35 +5365,110 @@ } } - /* If the maximum is unlimited, set a repeater in the final copy. We - can't just offset backwards from the current code point, because we - don't know if there's been an options resetting after the ket. The - correct offset was computed above. + /* If the maximum is unlimited, set a repeater in the final copy. For + ONCE brackets, that's all we need to do. However, possessively repeated + ONCE brackets can be converted into non-capturing brackets, as the + behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to + deal with possessive ONCEs specially. - Then, when we are doing the actual compile phase, check to see whether - this group is a non-atomic one that could match an empty string. If so, + Otherwise, when we are doing the actual compile phase, check to see + whether this group is one that could match an empty string. If so, convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so - that runtime checking can be done. [This check is also applied to - atomic groups at runtime, but in a different way.] */ + that runtime checking can be done. [This check is also applied to ONCE + groups at runtime, but in a different way.] + + Then, if the quantifier was possessive and the bracket is not a + conditional, we convert the BRA code to the POS form, and the KET code to + KETRPOS. (It turns out to be convenient at runtime to detect this kind of + subpattern at both the start and at the end.) The use of special opcodes + makes it possible to reduce greatly the stack usage in pcre_exec(). If + the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. + + Then, if the minimum number of matches is 1 or 0, cancel the possessive + flag so that the default action below, of wrapping everything inside + atomic brackets, does not happen. When the minimum is greater than 1, + there will be earlier copies of the group, and so we still have to wrap + the whole thing. */ else { - uschar *ketcode = code - ketoffset; - uschar *bracode = ketcode - GET(ketcode, 1); - *ketcode = OP_KETRMAX + repeat_type; - if (lengthptr == NULL && *bracode != OP_ONCE) + pcre_uchar *ketcode = code - 1 - LINK_SIZE; + pcre_uchar *bracode = ketcode - GET(ketcode, 1); + + /* Convert possessive ONCE brackets to non-capturing */ + + if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) && + possessive_quantifier) *bracode = OP_BRA; + + /* For non-possessive ONCE brackets, all we need to do is to + set the KET. */ + + if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC) + *ketcode = OP_KETRMAX + repeat_type; + + /* Handle non-ONCE brackets and possessive ONCEs (which have been + converted to non-capturing above). */ + + else { - uschar *scode = bracode; - do + /* In the compile phase, check for empty string matching. */ + + if (lengthptr == NULL) { - if (could_be_empty_branch(scode, ketcode, utf8, cd)) + pcre_uchar *scode = bracode; + do { - *bracode += OP_SBRA - OP_BRA; - break; + if (could_be_empty_branch(scode, ketcode, utf, cd)) + { + *bracode += OP_SBRA - OP_BRA; + break; + } + scode += GET(scode, 1); + } + while (*scode == OP_ALT); + } + + /* Handle possessive quantifiers. */ + + if (possessive_quantifier) + { + /* For COND brackets, we wrap the whole thing in a possessively + repeated non-capturing bracket, because we have not invented POS + versions of the COND opcodes. Because we are moving code along, we + must ensure that any pending recursive references are updated. */ + + if (*bracode == OP_COND || *bracode == OP_SCOND) + { + int nlen = (int)(code - bracode); + *code = OP_END; + adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm); + memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen)); + code += 1 + LINK_SIZE; + nlen += 1 + LINK_SIZE; + *bracode = OP_BRAPOS; + *code++ = OP_KETRPOS; + PUTINC(code, 0, nlen); + PUT(bracode, 1, nlen); } - scode += GET(scode, 1); + + /* For non-COND brackets, we modify the BRA code and use KETRPOS. */ + + else + { + *bracode += 1; /* Switch to xxxPOS opcodes */ + *ketcode = OP_KETRPOS; + } + + /* If the minimum is zero, mark it as possessive, then unset the + possessive flag when the minimum is 0 or 1. */ + + if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO; + if (repeat_min < 2) possessive_quantifier = FALSE; } - while (*scode == OP_ALT); + + /* Non-possessive quantifier */ + + else *ketcode = OP_KETRMAX + repeat_type; } } } @@ -4728,13 +5489,18 @@ } /* If the character following a repeat is '+', or if certain optimization - tests above succeeded, possessive_quantifier is TRUE. For some of the - simpler opcodes, there is an special alternative opcode for this. For - anything else, we wrap the entire repeated item inside OP_ONCE brackets. - The '+' notation is just syntactic sugar, taken from Sun's Java package, - but the special opcodes can optimize it a bit. The repeated item starts at - tempcode, not at previous, which might be the first part of a string whose - (former) last char we repeated. + tests above succeeded, possessive_quantifier is TRUE. For some opcodes, + there are special alternative opcodes for this case. For anything else, we + wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+' + notation is just syntactic sugar, taken from Sun's Java package, but the + special opcodes can optimize it. + + Some (but not all) possessively repeated subpatterns have already been + completely handled in the code just above. For them, possessive_quantifier + is always FALSE at this stage. + + Note that the repeated item starts at tempcode, not at previous, which + might be the first part of a string whose (former) last char we repeated. Possessifying an 'exact' quantifier has no effect, so we can ignore it. But an 'upto' may follow. We skip over an 'exact' item, and then test the @@ -4745,15 +5511,16 @@ int len; if (*tempcode == OP_TYPEEXACT) - tempcode += _pcre_OP_lengths[*tempcode] + - ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0); + tempcode += PRIV(OP_lengths)[*tempcode] + + ((tempcode[1 + IMM2_SIZE] == OP_PROP + || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT) { - tempcode += _pcre_OP_lengths[*tempcode]; -#ifdef SUPPORT_UTF8 - if (utf8 && tempcode[-1] >= 0xc0) - tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f]; + tempcode += PRIV(OP_lengths)[*tempcode]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(tempcode[-1])) + tempcode += GET_EXTRALEN(tempcode[-1]); #endif } @@ -4765,23 +5532,33 @@ case OP_QUERY: *tempcode = OP_POSQUERY; break; case OP_UPTO: *tempcode = OP_POSUPTO; break; - case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; - case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; - case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; - case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; + case OP_STARI: *tempcode = OP_POSSTARI; break; + case OP_PLUSI: *tempcode = OP_POSPLUSI; break; + case OP_QUERYI: *tempcode = OP_POSQUERYI; break; + case OP_UPTOI: *tempcode = OP_POSUPTOI; break; case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break; case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break; case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break; case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break; + case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break; + case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break; + case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break; + case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break; + + case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break; + case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break; + case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break; + case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break; + /* Because we are moving code along, we must ensure that any pending recursive references are updated. */ default: *code = OP_END; - adjust_recurse(tempcode, 1 + LINK_SIZE, utf8, cd, save_hwm); - memmove(tempcode + 1+LINK_SIZE, tempcode, len); + adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm); + memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len)); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; @@ -4793,7 +5570,7 @@ } /* In all case we no longer have a previous item. We also set the - "follows varying string" flag for subsequently encountered reqbytes if + "follows varying string" flag for subsequently encountered reqchars if it isn't already set and we have just passed a varying length item. */ END_REPEAT: @@ -4816,24 +5593,34 @@ /* First deal with various "verbs" that can be introduced by '*'. */ - if (*(++ptr) == CHAR_ASTERISK && - ((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':')) + ptr++; + if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' + || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0)))) { int i, namelen; int arglen = 0; const char *vn = verbnames; - const uschar *name = ptr + 1; - const uschar *arg = NULL; + const pcre_uchar *name = ptr + 1; + const pcre_uchar *arg = NULL; previous = NULL; - while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {}; + ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; namelen = (int)(ptr - name); + /* It appears that Perl allows any characters whatsoever, other than + a closing parenthesis, to appear in arguments, so we no longer insist on + letters, digits, and underscores. */ + if (*ptr == CHAR_COLON) { arg = ++ptr; - while ((cd->ctypes[*ptr] & (ctype_letter|ctype_digit)) != 0 - || *ptr == '_') ptr++; + while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; arglen = (int)(ptr - arg); + if (arglen > (int)MAX_MARK) + { + *errorcodeptr = ERR75; + goto FAILED; + } } if (*ptr != CHAR_RIGHT_PARENTHESIS) @@ -4847,24 +5634,34 @@ for (i = 0; i < verbcount; i++) { if (namelen == verbs[i].len && - strncmp((char *)name, vn, namelen) == 0) + STRNCMP_UC_C8(name, vn, namelen) == 0) { - /* Check for open captures before ACCEPT */ + /* Check for open captures before ACCEPT and convert it to + ASSERT_ACCEPT if in an assertion. */ if (verbs[i].op == OP_ACCEPT) { open_capitem *oc; + if (arglen != 0) + { + *errorcodeptr = ERR59; + goto FAILED; + } cd->had_accept = TRUE; for (oc = cd->open_caps; oc != NULL; oc = oc->next) { *code++ = OP_CLOSE; PUT2INC(code, 0, oc->number); } + *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; + + /* Do not set firstchar after *ACCEPT */ + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; } - /* Handle the cases with/without an argument */ + /* Handle other cases with/without an argument */ - if (arglen == 0) + else if (arglen == 0) { if (verbs[i].op < 0) /* Argument is mandatory */ { @@ -4872,11 +5669,7 @@ goto FAILED; } *code = verbs[i].op; - if (*code++ == OP_THEN) - { - PUT(code, 0, code - bcptr->current_branch - 1); - code += LINK_SIZE; - } + if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN; } else @@ -4887,13 +5680,9 @@ goto FAILED; } *code = verbs[i].op_arg; - if (*code++ == OP_THEN_ARG) - { - PUT(code, 0, code - bcptr->current_branch - 1); - code += LINK_SIZE; - } + if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN; *code++ = arglen; - memcpy(code, arg, arglen); + memcpy(code, arg, IN_UCHARS(arglen)); code += arglen; *code++ = 0; } @@ -4916,8 +5705,8 @@ { int i, set, unset, namelen; int *optset; - const uschar *name; - uschar *slot; + const pcre_uchar *name; + pcre_uchar *slot; switch (*(++ptr)) { @@ -4970,10 +5759,10 @@ break; /* Most other conditions use OP_CREF (a couple change to OP_RREF - below), and all need to skip 3 bytes at the start of the group. */ + below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */ code[1+LINK_SIZE] = OP_CREF; - skipbytes = 3; + skipbytes = 1+IMM2_SIZE; refsign = -1; /* Check for a test for recursion in a named group. */ @@ -5006,7 +5795,7 @@ /* We now expect to read a name; any thing else is an error */ - if ((cd->ctypes[ptr[1]] & ctype_word) == 0) + if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0) { ptr += 1; /* To get the right offset */ *errorcodeptr = ERR28; @@ -5017,11 +5806,10 @@ recno = 0; name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) { if (recno >= 0) - recno = ((digitab[*ptr] & ctype_digit) != 0)? - recno * 10 + *ptr - CHAR_0 : -1; + recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1; ptr++; } namelen = (int)(ptr - name); @@ -5069,7 +5857,7 @@ slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { - if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break; slot += cd->name_entry_size; } @@ -5085,7 +5873,7 @@ /* Search the pattern for a forward reference */ else if ((i = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8)) > 0) + (options & PCRE_EXTENDED) != 0, utf)) > 0) { PUT2(code, 2+LINK_SIZE, i); code[1+LINK_SIZE]++; @@ -5111,7 +5899,7 @@ recno = 0; for (i = 1; i < namelen; i++) { - if ((digitab[name[i]] & ctype_digit) == 0) + if (!IS_DIGIT(name[i])) { *errorcodeptr = ERR15; goto FAILED; @@ -5126,7 +5914,7 @@ /* Similarly, check for the (?(DEFINE) "condition", which is always false. */ - else if (namelen == 6 && strncmp((char *)name, STRING_DEFINE, 6) == 0) + else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0) { code[1+LINK_SIZE] = OP_DEF; skipbytes = 1; @@ -5153,6 +5941,7 @@ /* ------------------------------------------------------------ */ case CHAR_EQUALS_SIGN: /* Positive lookahead */ bravalue = OP_ASSERT; + cd->assert_depth += 1; ptr++; break; @@ -5167,6 +5956,7 @@ continue; } bravalue = OP_ASSERT_NOT; + cd->assert_depth += 1; break; @@ -5176,16 +5966,19 @@ { case CHAR_EQUALS_SIGN: /* Positive lookbehind */ bravalue = OP_ASSERTBACK; + cd->assert_depth += 1; ptr += 2; break; case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */ bravalue = OP_ASSERTBACK_NOT; + cd->assert_depth += 1; ptr += 2; break; default: /* Could be name define, else bad */ - if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME; + if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0) + goto DEFINE_NAME; ptr++; /* Correct offset for error */ *errorcodeptr = ERR24; goto FAILED; @@ -5202,13 +5995,14 @@ /* ------------------------------------------------------------ */ case CHAR_C: /* Callout - may be followed by digits; */ - previous_callout = code; /* Save for later completion */ - after_manual_callout = 1; /* Skip one item before completing */ + previous_callout = code; /* Save for later completion */ + after_manual_callout = 1; /* Skip one item before completing */ *code++ = OP_CALLOUT; { int n = 0; - while ((digitab[*(++ptr)] & ctype_digit) != 0) - n = n * 10 + *ptr - CHAR_0; + ptr++; + while(IS_DIGIT(*ptr)) + n = n * 10 + *ptr++ - CHAR_0; if (*ptr != CHAR_RIGHT_PARENTHESIS) { *errorcodeptr = ERR39; @@ -5253,7 +6047,7 @@ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, just do a syntax check. */ @@ -5270,9 +6064,9 @@ *errorcodeptr = ERR49; goto FAILED; } - if (namelen + 3 > cd->name_entry_size) + if (namelen + IMM2_SIZE + 1 > cd->name_entry_size) { - cd->name_entry_size = namelen + 3; + cd->name_entry_size = namelen + IMM2_SIZE + 1; if (namelen > MAX_NAME_SIZE) { *errorcodeptr = ERR48; @@ -5301,10 +6095,10 @@ for (i = 0; i < cd->names_found; i++) { - int crc = memcmp(name, slot+2, namelen); + int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen)); if (crc == 0) { - if (slot[2+namelen] == 0) + if (slot[IMM2_SIZE+namelen] == 0) { if (GET2(slot, 0) != cd->bracount + 1 && (options & PCRE_DUPNAMES) == 0) @@ -5325,7 +6119,7 @@ if (crc < 0) { memmove(slot + cd->name_entry_size, slot, - (cd->names_found - i) * cd->name_entry_size); + IN_UCHARS((cd->names_found - i) * cd->name_entry_size)); break; } @@ -5339,7 +6133,7 @@ if (!dupname) { - uschar *cslot = cd->name_table; + pcre_uchar *cslot = cd->name_table; for (i = 0; i < cd->names_found; i++) { if (cslot != slot) @@ -5356,8 +6150,8 @@ } PUT2(slot, 0, cd->bracount + 1); - memcpy(slot + 2, name, namelen); - slot[2+namelen] = 0; + memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen)); + slot[IMM2_SIZE + namelen] = 0; } } @@ -5383,7 +6177,7 @@ NAMED_REF_OR_RECURSE: name = ++ptr; - while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++; + while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++; namelen = (int)(ptr - name); /* In the pre-compile phase, do a syntax check. We used to just set @@ -5395,7 +6189,7 @@ if (lengthptr != NULL) { - const uschar *temp; + const pcre_uchar *temp; if (namelen == 0) { @@ -5425,7 +6219,7 @@ temp = cd->end_pattern; cd->end_pattern = ptr; recno = find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8); + (options & PCRE_EXTENDED) != 0, utf); cd->end_pattern = temp; if (recno < 0) recno = 0; /* Forward ref; set dummy number */ } @@ -5440,8 +6234,8 @@ slot = cd->name_table; for (i = 0; i < cd->names_found; i++) { - if (strncmp((char *)name, (char *)slot+2, namelen) == 0 && - slot[2+namelen] == 0) + if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 && + slot[IMM2_SIZE+namelen] == 0) break; slot += cd->name_entry_size; } @@ -5452,7 +6246,7 @@ } else if ((recno = /* Forward back reference */ find_parens(cd, name, namelen, - (options & PCRE_EXTENDED) != 0, utf8)) <= 0) + (options & PCRE_EXTENDED) != 0, utf)) <= 0) { *errorcodeptr = ERR15; goto FAILED; @@ -5477,7 +6271,7 @@ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: { - const uschar *called; + const pcre_uchar *called; terminator = CHAR_RIGHT_PARENTHESIS; /* Come here from the \g<...> and \g'...' code (Oniguruma @@ -5491,7 +6285,7 @@ if ((refsign = *ptr) == CHAR_PLUS) { ptr++; - if ((digitab[*ptr] & ctype_digit) == 0) + if (!IS_DIGIT(*ptr)) { *errorcodeptr = ERR63; goto FAILED; @@ -5499,13 +6293,13 @@ } else if (refsign == CHAR_MINUS) { - if ((digitab[ptr[1]] & ctype_digit) == 0) + if (!IS_DIGIT(ptr[1])) goto OTHER_CHAR_AFTER_QUERY; ptr++; } recno = 0; - while((digitab[*ptr] & ctype_digit) != 0) + while(IS_DIGIT(*ptr)) recno = recno * 10 + *ptr++ - CHAR_0; if (*ptr != terminator) @@ -5556,14 +6350,14 @@ { *code = OP_END; if (recno != 0) - called = _pcre_find_bracket(cd->start_code, utf8, recno); + called = PRIV(find_bracket)(cd->start_code, utf, recno); /* Forward reference */ if (called == NULL) { if (find_parens(cd, NULL, recno, - (options & PCRE_EXTENDED) != 0, utf8) < 0) + (options & PCRE_EXTENDED) != 0, utf) < 0) { *errorcodeptr = ERR15; goto FAILED; @@ -5571,46 +6365,48 @@ /* Fudge the value of "called" so that when it is inserted as an offset below, what it actually inserted is the reference number - of the group. */ + of the group. Then remember the forward reference. */ called = cd->start_code + recno; - PUTINC(cd->hwm, 0, (int)(code + 2 + LINK_SIZE - cd->start_code)); + if (cd->hwm >= cd->start_workspace + cd->workspace_size - + WORK_SIZE_SAFETY_MARGIN) + { + *errorcodeptr = expand_workspace(cd); + if (*errorcodeptr != 0) goto FAILED; + } + PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code)); } /* If not a forward reference, and the subpattern is still open, this is a recursive call. We check to see if this is a left - recursion that could loop for ever, and diagnose that case. */ + recursion that could loop for ever, and diagnose that case. We + must not, however, do this check if we are in a conditional + subpattern because the condition might be testing for recursion in + a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid. + Forever loops are also detected at runtime, so those that occur in + conditional subpatterns will be picked up then. */ - else if (GET(called, 1) == 0 && - could_be_empty(called, code, bcptr, utf8, cd)) + else if (GET(called, 1) == 0 && cond_depth <= 0 && + could_be_empty(called, code, bcptr, utf, cd)) { *errorcodeptr = ERR40; goto FAILED; } } - /* Insert the recursion/subroutine item, automatically wrapped inside - "once" brackets. Set up a "previous group" length so that a - subsequent quantifier will work. */ - - *code = OP_ONCE; - PUT(code, 1, 2 + 2*LINK_SIZE); - code += 1 + LINK_SIZE; + /* Insert the recursion/subroutine item. It does not have a set first + character (relevant if it is repeated, because it will then be + wrapped with ONCE brackets). */ *code = OP_RECURSE; PUT(code, 1, (int)(called - cd->start_code)); code += 1 + LINK_SIZE; - - *code = OP_KET; - PUT(code, 1, 2 + 2*LINK_SIZE); - code += 1 + LINK_SIZE; - - length_prevgroup = 3 + 3*LINK_SIZE; + groupsetfirstchar = FALSE; } /* Can't determine a first byte now */ - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; continue; @@ -5666,9 +6462,8 @@ is necessary to ensure we correctly detect the start of the pattern in both phases. - If we are not at the pattern start, compile code to change the ims - options if this setting actually changes any of them, and reset the - greedy defaults and the case value for firstbyte and reqbyte. */ + If we are not at the pattern start, reset the greedy defaults and the + case value for firstchar and reqchar. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { @@ -5679,20 +6474,13 @@ } else { - if ((options & PCRE_IMS) != (newoptions & PCRE_IMS)) - { - *code++ = OP_OPT; - *code++ = newoptions & PCRE_IMS; - } greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; - req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; + req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; } /* Change options at this level, and pass them back for use - in subsequent branches. When not at the start of the pattern, this - information is also necessary so that a resetting item can be - compiled at the end of a group (if we are in a group). */ + in subsequent branches. */ *optionsptr = options = newoptions; previous = NULL; /* This item can't be repeated */ @@ -5725,53 +6513,62 @@ NUMBERED_GROUP: cd->bracount += 1; PUT2(code, 1+LINK_SIZE, cd->bracount); - skipbytes = 2; + skipbytes = IMM2_SIZE; } - /* Process nested bracketed regex. Assertions may not be repeated, but - other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a - non-register variable in order to be able to pass its address because some - compilers complain otherwise. Pass in a new setting for the ims options if - they have changed. */ + /* Process nested bracketed regex. Assertions used not to be repeatable, + but this was changed for Perl compatibility, so all kinds can now be + repeated. We copy code into a non-register variable (tempcode) in order to + be able to pass its address because some compilers complain otherwise. */ - previous = (bravalue >= OP_ONCE)? code : NULL; + previous = code; /* For handling repetition */ *code = bravalue; tempcode = code; - tempreqvary = cd->req_varyopt; /* Save value before bracket */ - length_prevgroup = 0; /* Initialize for pre-compile phase */ + tempreqvary = cd->req_varyopt; /* Save value before bracket */ + tempbracount = cd->bracount; /* Save value before bracket */ + length_prevgroup = 0; /* Initialize for pre-compile phase */ if (!compile_regex( - newoptions, /* The complete new option state */ - options & PCRE_IMS, /* The previous ims option state */ - &tempcode, /* Where to put code (updated) */ - &ptr, /* Input pointer (updated) */ - errorcodeptr, /* Where to put an error message */ + newoptions, /* The complete new option state */ + &tempcode, /* Where to put code (updated) */ + &ptr, /* Input pointer (updated) */ + errorcodeptr, /* Where to put an error message */ (bravalue == OP_ASSERTBACK || bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ - reset_bracount, /* True if (?| group */ - skipbytes, /* Skip over bracket number */ - &subfirstbyte, /* For possible first char */ - &subreqbyte, /* For possible last char */ - bcptr, /* Current branch chain */ - cd, /* Tables block */ - (lengthptr == NULL)? NULL : /* Actual compile phase */ - &length_prevgroup /* Pre-compile phase */ + reset_bracount, /* True if (?| group */ + skipbytes, /* Skip over bracket number */ + cond_depth + + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ + &subfirstchar, /* For possible first char */ + &subreqchar, /* For possible last char */ + bcptr, /* Current branch chain */ + cd, /* Tables block */ + (lengthptr == NULL)? NULL : /* Actual compile phase */ + &length_prevgroup /* Pre-compile phase */ )) goto FAILED; + /* If this was an atomic group and there are no capturing groups within it, + generate OP_ONCE_NC instead of OP_ONCE. */ + + if (bravalue == OP_ONCE && cd->bracount <= tempbracount) + *code = OP_ONCE_NC; + + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) + cd->assert_depth -= 1; + /* At the end of compiling, code is still pointing to the start of the - group, while tempcode has been updated to point past the end of the group - and any option resetting that may follow it. The pattern pointer (ptr) - is on the bracket. */ + group, while tempcode has been updated to point past the end of the group. + The pattern pointer (ptr) is on the bracket. - /* If this is a conditional bracket, check that there are no more than + If this is a conditional bracket, check that there are no more than two branches in the group, or just one if it's a DEFINE group. We do this in the real compile phase, not in the pre-pass, where the whole group may not be available. */ if (bravalue == OP_COND && lengthptr == NULL) { - uschar *tc = code; + pcre_uchar *tc = code; int condcount = 0; do { @@ -5794,7 +6591,7 @@ } /* A "normal" conditional group. If there is just one branch, we must not - make use of its firstbyte or reqbyte, because this is equivalent to an + make use of its firstchar or reqchar, because this is equivalent to an empty second branch. */ else @@ -5804,7 +6601,7 @@ *errorcodeptr = ERR27; goto FAILED; } - if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE; + if (condcount == 1) subfirstchar = subreqchar = REQ_NONE; } } @@ -5829,7 +6626,7 @@ goto FAILED; } *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE; - *code++ = OP_BRA; + code++; /* This already contains bravalue */ PUTINC(code, 0, 1 + LINK_SIZE); *code++ = OP_KET; PUTINC(code, 0, 1 + LINK_SIZE); @@ -5848,55 +6645,55 @@ /* Handle updating of the required and first characters for other types of group. Update for normal brackets of all kinds, and conditions with two branches (see code above). If the bracket is followed by a quantifier with - zero repeat, we have to back off. Hence the definition of zeroreqbyte and - zerofirstbyte outside the main loop so that they can be accessed for the + zero repeat, we have to back off. Hence the definition of zeroreqchar and + zerofirstchar outside the main loop so that they can be accessed for the back off. */ - zeroreqbyte = reqbyte; - zerofirstbyte = firstbyte; - groupsetfirstbyte = FALSE; + zeroreqchar = reqchar; + zerofirstchar = firstchar; + groupsetfirstchar = FALSE; if (bravalue >= OP_ONCE) { - /* If we have not yet set a firstbyte in this branch, take it from the + /* If we have not yet set a firstchar in this branch, take it from the subpattern, remembering that it was set here so that a repeat of more - than one can replicate it as reqbyte if necessary. If the subpattern has - no firstbyte, set "none" for the whole branch. In both cases, a zero - repeat forces firstbyte to "none". */ + than one can replicate it as reqchar if necessary. If the subpattern has + no firstchar, set "none" for the whole branch. In both cases, a zero + repeat forces firstchar to "none". */ - if (firstbyte == REQ_UNSET) + if (firstchar == REQ_UNSET) { - if (subfirstbyte >= 0) + if (subfirstchar >= 0) { - firstbyte = subfirstbyte; - groupsetfirstbyte = TRUE; + firstchar = subfirstchar; + groupsetfirstchar = TRUE; } - else firstbyte = REQ_NONE; - zerofirstbyte = REQ_NONE; + else firstchar = REQ_NONE; + zerofirstchar = REQ_NONE; } - /* If firstbyte was previously set, convert the subpattern's firstbyte - into reqbyte if there wasn't one, using the vary flag that was in + /* If firstchar was previously set, convert the subpattern's firstchar + into reqchar if there wasn't one, using the vary flag that was in existence beforehand. */ - else if (subfirstbyte >= 0 && subreqbyte < 0) - subreqbyte = subfirstbyte | tempreqvary; + else if (subfirstchar >= 0 && subreqchar < 0) + subreqchar = subfirstchar | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ - if (subreqbyte >= 0) reqbyte = subreqbyte; + if (subreqchar >= 0) reqchar = subreqchar; } - /* For a forward assertion, we take the reqbyte, if set. This can be + /* For a forward assertion, we take the reqchar, if set. This can be helpful if the pattern that follows the assertion doesn't set a different - char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte + char. For example, it's useful for /(?=abcde).+/. We can't set firstchar for an assertion, however because it leads to incorrect effect for patterns - such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead - of a firstbyte. This is overcome by a scan at the end if there's no - firstbyte, looking for an asserted first char. */ + such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead + of a firstchar. This is overcome by a scan at the end if there's no + firstchar, looking for an asserted first char. */ - else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte; + else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar; break; /* End of processing '(' */ @@ -5929,13 +6726,13 @@ /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ - if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z) - firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z) + firstchar = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + zerofirstchar = firstchar; + zeroreqchar = reqchar; /* \g or \g'name' is a subroutine call by name and \g or \g'n' is a subroutine call by number (Oniguruma syntax). In fact, the value @@ -5946,7 +6743,7 @@ if (-c == ESC_g) { - const uschar *p; + const pcre_uchar *p; save_hwm = cd->hwm; /* Normally this is set when '(' is read */ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE; @@ -5963,10 +6760,11 @@ if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) { - BOOL isnumber = TRUE; + BOOL is_a_number = TRUE; for (p = ptr + 1; *p != 0 && *p != terminator; p++) { - if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE; + if (!MAX_255(*p)) { is_a_number = FALSE; break; } + if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; if ((cd->ctypes[*p] & ctype_word) == 0) break; } if (*p != terminator) @@ -5974,7 +6772,7 @@ *errorcodeptr = ERR57; break; } - if (isnumber) + if (is_a_number) { ptr++; goto HANDLE_NUMERICAL_RECURSION; @@ -5986,7 +6784,7 @@ /* Test a signed number in angle brackets or quotes. */ p = ptr + 2; - while ((digitab[*p] & ctype_digit) != 0) p++; + while (IS_DIGIT(*p)) p++; if (*p != terminator) { *errorcodeptr = ERR57; @@ -5997,11 +6795,16 @@ } /* \k or \k'name' is a back reference by name (Perl syntax). - We also support \k{name} (.NET syntax) */ + We also support \k{name} (.NET syntax). */ - if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN || - ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET)) + if (-c == ESC_k) { + if ((ptr[1] != CHAR_LESS_THAN_SIGN && + ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) + { + *errorcodeptr = ERR69; + break; + } is_recurse = FALSE; terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)? CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)? @@ -6009,7 +6812,7 @@ goto NAMED_REF_OR_RECURSE; } - /* Back references are handled specially; must disable firstbyte if + /* Back references are handled specially; must disable firstchar if not set to cope with cases like (?=(\w+))\1: which would otherwise set ':' later. */ @@ -6019,9 +6822,9 @@ recno = -c - ESC_REF; HANDLE_REFERENCE: /* Come here from named backref handling */ - if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; previous = code; - *code++ = OP_REF; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, recno); cd->backref_map |= (recno < 32)? (1 << recno) : 1; if (recno > cd->top_backref) cd->top_backref = recno; @@ -6069,10 +6872,13 @@ /* For the rest (including \X when Unicode properties are supported), we can obtain the OP value by negating the escape value in the default situation when PCRE_UCP is not set. When it *is* set, we substitute - Unicode property tests. */ + Unicode property tests. Note that \b and \B do a one-character + lookbehind. */ else { + if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0) + cd->max_lookbehind = 1; #ifdef SUPPORT_UCP if (-c >= ESC_DU && -c <= ESC_wu) { @@ -6081,9 +6887,12 @@ } else #endif + /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE + so that it works in DFA mode and in lookbehinds. */ + { previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; - *code++ = -c; + *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c; } } continue; @@ -6093,9 +6902,9 @@ a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ -#ifdef SUPPORT_UTF8 - if (utf8 && c > 127) - mclength = _pcre_ord2utf8(c, mcbuffer); +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + mclength = PRIV(ord2utf)(c, mcbuffer); else #endif @@ -6116,12 +6925,9 @@ mclength = 1; mcbuffer[0] = c; -#ifdef SUPPORT_UTF8 - if (utf8 && c >= 0xc0) - { - while ((ptr[1] & 0xc0) == 0x80) - mcbuffer[mclength++] = *(++ptr); - } +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(c)) + ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr)); #endif /* At this point we have the character's bytes in mcbuffer, and the length @@ -6129,7 +6935,7 @@ ONE_CHAR: previous = code; - *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR; + *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; /* Remember if \r or \n were seen */ @@ -6139,34 +6945,34 @@ /* Set the first and required bytes appropriately. If no previous first byte, set it from this character, but revert to none on a zero repeat. - Otherwise, leave the firstbyte value alone, and don't change it on a zero + Otherwise, leave the firstchar value alone, and don't change it on a zero repeat. */ - if (firstbyte == REQ_UNSET) + if (firstchar == REQ_UNSET) { - zerofirstbyte = REQ_NONE; - zeroreqbyte = reqbyte; + zerofirstchar = REQ_NONE; + zeroreqchar = reqchar; - /* If the character is more than one byte long, we can set firstbyte + /* If the character is more than one byte long, we can set firstchar only if it is not to be matched caselessly. */ if (mclength == 1 || req_caseopt == 0) { - firstbyte = mcbuffer[0] | req_caseopt; - if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt; + firstchar = mcbuffer[0] | req_caseopt; + if (mclength != 1) reqchar = code[-1] | cd->req_varyopt; } - else firstbyte = reqbyte = REQ_NONE; + else firstchar = reqchar = REQ_NONE; } - /* firstbyte was previously set; we can set reqbyte only the length is + /* firstchar was previously set; we can set reqchar only if the length is 1 or the matching is caseful. */ else { - zerofirstbyte = firstbyte; - zeroreqbyte = reqbyte; + zerofirstchar = firstchar; + zeroreqchar = reqchar; if (mclength == 1 || req_caseopt == 0) - reqbyte = code[-1] | req_caseopt | cd->req_varyopt; + reqchar = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ @@ -6193,26 +6999,21 @@ /* On entry, ptr is pointing past the bracket character, but on return it points to the closing bracket, or vertical bar, or end of string. The code variable is pointing at the byte into which the BRA operator has been stored. -If the ims options are changed at the start (for a (?ims: group) or during any -branch, we need to insert an OP_OPT item at the start of every following branch -to ensure they get set correctly at run time, and also pass the new options -into every subsequent branch compile. - This function is used during the pre-compile phase when we are trying to find out the amount of memory needed, as well as during the real compile phase. The value of lengthptr distinguishes the two phases. Arguments: options option bits, including any changes for this subpattern - oldims previous settings of ims option bits codeptr -> the address of the current code pointer ptrptr -> the address of the current pattern pointer errorcodeptr -> pointer to error code variable lookbehind TRUE if this is a lookbehind assertion reset_bracount TRUE to reset the count for each branch skipbytes skip this many bytes at start (for brackets and OP_COND) - firstbyteptr place to put the first required character, or a negative number - reqbyteptr place to put the last required character, or a negative number + cond_depth depth of nesting for conditional subpatterns + firstcharptr place to put the first required character, or a negative number + reqcharptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. lengthptr NULL during the real compile phase @@ -6222,30 +7023,29 @@ */ static BOOL -compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr, +compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr, int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, - int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd, - int *lengthptr) + int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr, + branch_chain *bcptr, compile_data *cd, int *lengthptr) { -const uschar *ptr = *ptrptr; -uschar *code = *codeptr; -uschar *last_branch = code; -uschar *start_bracket = code; -uschar *reverse_count = NULL; +const pcre_uchar *ptr = *ptrptr; +pcre_uchar *code = *codeptr; +pcre_uchar *last_branch = code; +pcre_uchar *start_bracket = code; +pcre_uchar *reverse_count = NULL; open_capitem capitem; int capnumber = 0; -int firstbyte, reqbyte; -int branchfirstbyte, branchreqbyte; +pcre_int32 firstchar, reqchar; +pcre_int32 branchfirstchar, branchreqchar; int length; int orig_bracount; int max_bracount; -int old_external_options = cd->external_options; branch_chain bc; bc.outer = bcptr; bc.current_branch = code; -firstbyte = reqbyte = REQ_UNSET; +firstchar = reqchar = REQ_UNSET; /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra bytes that are required at the @@ -6263,7 +7063,9 @@ /* If this is a capturing subpattern, add to the chain of open capturing items so that we can detect them if (*ACCEPT) is encountered. This is also used to -detect groups that contain recursive back references to themselves. */ +detect groups that contain recursive back references to themselves. Note that +only OP_CBRA need be tested here; changing this opcode to one of its variants, +e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */ if (*code == OP_CBRA) { @@ -6289,15 +7091,6 @@ if (reset_bracount) cd->bracount = orig_bracount; - /* Handle a change of ims options at the start of the branch */ - - if ((options & PCRE_IMS) != oldims) - { - *code++ = OP_OPT; - *code++ = options & PCRE_IMS; - length += 2; - } - /* Set up dummy OP_REVERSE if lookbehind assertion */ if (lookbehind) @@ -6311,22 +7104,14 @@ /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ - if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte, - &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length)) + if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar, + &branchreqchar, &bc, cond_depth, cd, + (lengthptr == NULL)? NULL : &length)) { *ptrptr = ptr; return FALSE; } - /* If the external options have changed during this branch, it means that we - are at the top level, and a leading option setting has been encountered. We - need to re-set the original option values to take account of this so that, - during the pre-compile phase, we know to allow for a re-set at the start of - subsequent branches. */ - - if (old_external_options != cd->external_options) - oldims = cd->external_options & PCRE_IMS; - /* Keep the highest bracket count in case (?| was used and some branch has fewer than the rest. */ @@ -6336,43 +7121,43 @@ if (lengthptr == NULL) { - /* If this is the first branch, the firstbyte and reqbyte values for the + /* If this is the first branch, the firstchar and reqchar values for the branch become the values for the regex. */ if (*last_branch != OP_ALT) { - firstbyte = branchfirstbyte; - reqbyte = branchreqbyte; + firstchar = branchfirstchar; + reqchar = branchreqchar; } - /* If this is not the first branch, the first char and reqbyte have to + /* If this is not the first branch, the first char and reqchar have to match the values from all the previous branches, except that if the - previous value for reqbyte didn't have REQ_VARY set, it can still match, + previous value for reqchar didn't have REQ_VARY set, it can still match, and we set REQ_VARY for the regex. */ else { - /* If we previously had a firstbyte, but it doesn't match the new branch, - we have to abandon the firstbyte for the regex, but if there was - previously no reqbyte, it takes on the value of the old firstbyte. */ + /* If we previously had a firstchar, but it doesn't match the new branch, + we have to abandon the firstchar for the regex, but if there was + previously no reqchar, it takes on the value of the old firstchar. */ - if (firstbyte >= 0 && firstbyte != branchfirstbyte) + if (firstchar >= 0 && firstchar != branchfirstchar) { - if (reqbyte < 0) reqbyte = firstbyte; - firstbyte = REQ_NONE; + if (reqchar < 0) reqchar = firstchar; + firstchar = REQ_NONE; } - /* If we (now or from before) have no firstbyte, a firstbyte from the - branch becomes a reqbyte if there isn't a branch reqbyte. */ + /* If we (now or from before) have no firstchar, a firstchar from the + branch becomes a reqchar if there isn't a branch reqchar. */ - if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0) - branchreqbyte = branchfirstbyte; + if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0) + branchreqchar = branchfirstchar; - /* Now ensure that the reqbytes match */ + /* Now ensure that the reqchars match */ - if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY)) - reqbyte = REQ_NONE; - else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */ + if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY)) + reqchar = REQ_NONE; + else reqchar |= branchreqchar; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and @@ -6387,7 +7172,8 @@ { int fixed_length; *code = OP_END; - fixed_length = find_fixedlength(last_branch, options, FALSE, cd); + fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0, + FALSE, cd); DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length == -3) { @@ -6395,11 +7181,17 @@ } else if (fixed_length < 0) { - *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25; + *errorcodeptr = (fixed_length == -2)? ERR36 : + (fixed_length == -4)? ERR70: ERR25; *ptrptr = ptr; return FALSE; } - else { PUT(reverse_count, 0, fixed_length); } + else + { + if (fixed_length > cd->max_lookbehind) + cd->max_lookbehind = fixed_length; + PUT(reverse_count, 0, fixed_length); + } } } @@ -6408,9 +7200,7 @@ of offsets, with the field in the BRA item now becoming an offset to the first alternative. If there are no alternatives, it points to the end of the group. The length in the terminating ket is always the length of the whole - bracketed item. If any of the ims options were changed inside the group, - compile a resetting op-code following, except at the very end of the pattern. - Return leaving the pointer at the terminating char. */ + bracketed item. Return leaving the pointer at the terminating char. */ if (*ptr != CHAR_VERTICAL_LINE) { @@ -6442,7 +7232,7 @@ if (cd->open_caps->flag) { memmove(start_bracket + 1 + LINK_SIZE, start_bracket, - code - start_bracket); + IN_UCHARS(code - start_bracket)); *start_bracket = OP_ONCE; code += 1 + LINK_SIZE; PUT(start_bracket, 1, (int)(code - start_bracket)); @@ -6454,15 +7244,6 @@ cd->open_caps = cd->open_caps->next; } - /* Reset options if needed. */ - - if ((options & PCRE_IMS) != oldims && *ptr == CHAR_RIGHT_PARENTHESIS) - { - *code++ = OP_OPT; - *code++ = oldims; - length += 2; - } - /* Retain the highest bracket number, in case resetting was used. */ cd->bracount = max_bracount; @@ -6471,8 +7252,8 @@ *codeptr = code; *ptrptr = ptr; - *firstbyteptr = firstbyte; - *reqbyteptr = reqbyte; + *firstcharptr = firstchar; + *reqcharptr = reqchar; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length) @@ -6522,8 +7303,8 @@ /* Try to find out if this is an anchored regular expression. Consider each alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then -it's anchored. However, if this is a multiline pattern, then only OP_SOD -counts, since OP_CIRC can match in the middle. +it's anchored. However, if this is a multiline pattern, then only OP_SOD will +be found, because ^ generates OP_CIRCM in that mode. We can also consider a regex to be anchored if OP_SOM starts all its branches. This is the code for \G, which means "match at start of match position, taking @@ -6544,7 +7325,6 @@ Arguments: code points to start of expression (the bracket) - options points to the options setting bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach @@ -6554,35 +7334,38 @@ */ static BOOL -is_anchored(register const uschar *code, int *options, unsigned int bracket_map, +is_anchored(register const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { - const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], - options, PCRE_MULTILINE, FALSE); + const pcre_uchar *scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* Non-capturing brackets */ - if (op == OP_BRA) + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ - else if (op == OP_CBRA) + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); - if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; + if (!is_anchored(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ - else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC || + op == OP_COND) { - if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and @@ -6597,9 +7380,7 @@ /* Check for explicit anchoring */ - else if (op != OP_SOD && op != OP_SOM && - ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC)) - return FALSE; + else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ @@ -6630,12 +7411,12 @@ */ static BOOL -is_startline(const uschar *code, unsigned int bracket_map, +is_startline(const pcre_uchar *code, unsigned int bracket_map, unsigned int backref_map) { do { - const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code], - NULL, 0, FALSE); + const pcre_uchar *scode = first_significant_code( + code + PRIV(OP_lengths)[*code], FALSE); register int op = *scode; /* If we are at the start of a conditional assertion group, *both* the @@ -6646,7 +7427,7 @@ if (op == OP_COND) { scode += 1 + LINK_SIZE; - if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT]; + if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT]; switch (*scode) { case OP_CREF: @@ -6662,20 +7443,22 @@ scode += 1 + LINK_SIZE; break; } - scode = first_significant_code(scode, NULL, 0, FALSE); + scode = first_significant_code(scode, FALSE); op = *scode; } /* Non-capturing brackets */ - if (op == OP_BRA) + if (op == OP_BRA || op == OP_BRAPOS || + op == OP_SBRA || op == OP_SBRAPOS) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ - else if (op == OP_CBRA) + else if (op == OP_CBRA || op == OP_CBRAPOS || + op == OP_SCBRA || op == OP_SCBRAPOS) { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); @@ -6684,7 +7467,7 @@ /* Other brackets */ - else if (op == OP_ASSERT || op == OP_ONCE) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } @@ -6699,7 +7482,7 @@ /* Check for explicit circumflex */ - else if (op != OP_CIRC) return FALSE; + else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; /* Move on to the next alternative */ @@ -6725,20 +7508,21 @@ Arguments: code points to start of expression (the bracket) - options pointer to the options (used to check casing changes) inassert TRUE if in an assertion Returns: -1 or the fixed first char */ static int -find_firstassertedchar(const uschar *code, int *options, BOOL inassert) +find_firstassertedchar(const pcre_uchar *code, BOOL inassert) { register int c = -1; do { int d; - const uschar *scode = - first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE); + int xl = (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; + const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl, + TRUE); register int op = *scode; switch(op) @@ -6747,30 +7531,44 @@ return -1; case OP_BRA: + case OP_BRAPOS: case OP_CBRA: + case OP_SCBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: case OP_ASSERT: case OP_ONCE: + case OP_ONCE_NC: case OP_COND: - if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0) + if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0) return -1; if (c < 0) c = d; else if (c != d) return -1; break; - case OP_EXACT: /* Fall through */ - scode += 2; + case OP_EXACT: + scode += IMM2_SIZE; + /* Fall through */ case OP_CHAR: - case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: if (!inassert) return -1; - if (c < 0) - { - c = scode[1]; - if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS; - } - else if (c != scode[1]) return -1; + if (c < 0) c = scode[1]; + else if (c != scode[1]) return -1; + break; + + case OP_EXACTI: + scode += IMM2_SIZE; + /* Fall through */ + + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + if (!inassert) return -1; + if (c < 0) c = scode[1] | REQ_CASELESS; + else if (c != scode[1]) return -1; break; } @@ -6804,28 +7602,45 @@ with errorptr and erroroffset set */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) +#else +PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION +pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr, + int *erroroffset, const unsigned char *tables) +#endif { +#ifdef COMPILE_PCRE8 return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#else +return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables); +#endif } +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) +#else +PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION +pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, + const char **errorptr, int *erroroffset, const unsigned char *tables) +#endif { -real_pcre *re; +REAL_PCRE *re; int length = 1; /* For final END opcode */ -int firstbyte, reqbyte, newline; +pcre_int32 firstchar, reqchar; +int newline; int errorcode = 0; int skipatstart = 0; -BOOL utf8; +BOOL utf; size_t size; -uschar *code; -const uschar *codestart; -const uschar *ptr; +pcre_uchar *code; +const pcre_uchar *codestart; +const pcre_uchar *ptr; compile_data compile_block; compile_data *cd = &compile_block; @@ -6833,13 +7648,14 @@ computing the amount of memory that is needed. Compiled items are thrown away as soon as possible, so that a fairly large buffer should be sufficient for this purpose. The same space is used in the second phase for remembering where -to fill in forward references to subpatterns. */ +to fill in forward references to subpatterns. That may overflow, in which case +new memory is obtained from malloc(). */ -uschar cworkspace[COMPILE_WORK_SIZE]; +pcre_uchar cworkspace[COMPILE_WORK_SIZE]; /* Set this early so that early errors get offset 0. */ -ptr = (const uschar *)pattern; +ptr = (const pcre_uchar *)pattern; /* We can't pass back an error message if errorptr is NULL; I guess the best we can do is just return NULL, but we can set a code value if there is a code @@ -6866,7 +7682,7 @@ /* Set up pointers to the individual character tables */ -if (tables == NULL) tables = _pcre_default_tables; +if (tables == NULL) tables = PRIV(default_tables); cd->lcc = tables + lcc_offset; cd->fcc = tables + fcc_offset; cd->cbits = tables + cbits_offset; @@ -6889,27 +7705,33 @@ int newnl = 0; int newbsr = 0; - if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0) +#ifdef COMPILE_PCRE8 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0) { skipatstart += 7; options |= PCRE_UTF8; continue; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0) +#endif +#ifdef COMPILE_PCRE16 + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0) + { skipatstart += 8; options |= PCRE_UTF16; continue; } +#endif + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) { skipatstart += 6; options |= PCRE_UCP; continue; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_NO_START_OPT_RIGHTPAR, 13) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; } - if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0) + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_CR; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0) { skipatstart += 5; newnl = PCRE_NEWLINE_LF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_CRLF_RIGHTPAR, 5) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0) { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANY_RIGHTPAR, 4) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0) { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANYCRLF_RIGHTPAR, 8) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0) { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; } - else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) + else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0) { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; } if (newnl != 0) @@ -6919,19 +7741,27 @@ else break; } -utf8 = (options & PCRE_UTF8) != 0; - -/* Can't support UTF8 unless PCRE has been compiled to include the code. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = (options & PCRE_UTF8) != 0; -#ifdef SUPPORT_UTF8 -if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 && - (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0) +/* Can't support UTF unless PCRE has been compiled to include the code. The +return of an error code from PRIV(valid_utf)() is a new feature, introduced in +release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is +not used here. */ + +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 && + (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0) { +#ifdef COMPILE_PCRE8 errorcode = ERR44; +#else + errorcode = ERR74; +#endif goto PCRE_EARLY_ERROR_RETURN2; } #else -if (utf8) +if (utf) { errorcode = ERR32; goto PCRE_EARLY_ERROR_RETURN; @@ -6950,13 +7780,11 @@ /* Check validity of \R options. */ -switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) +if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == + (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) { - case 0: - case PCRE_BSR_ANYCRLF: - case PCRE_BSR_UNICODE: - break; - default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN; + errorcode = ERR56; + goto PCRE_EARLY_ERROR_RETURN; } /* Handle different types of newline. The three bits give seven cases. The @@ -7009,7 +7837,10 @@ /* Reflect pattern for debugging output */ DPRINTF(("------------------------------------------------------------------\n")); -DPRINTF(("%s\n", pattern)); +#ifdef PCRE_DEBUG +print_puchar(stdout, (PCRE_PUCHAR)pattern); +#endif +DPRINTF(("\n")); /* Pretend to compile the pattern while actually just accumulating the length of memory required. This behaviour is triggered by passing a non-NULL final @@ -7022,12 +7853,15 @@ cd->names_found = 0; cd->name_entry_size = 0; cd->name_table = NULL; -cd->start_workspace = cworkspace; cd->start_code = cworkspace; cd->hwm = cworkspace; -cd->start_pattern = (const uschar *)pattern; -cd->end_pattern = (const uschar *)(pattern + strlen(pattern)); +cd->start_workspace = cworkspace; +cd->workspace_size = COMPILE_WORK_SIZE; +cd->start_pattern = (const pcre_uchar *)pattern; +cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern)); cd->req_varyopt = 0; +cd->assert_depth = 0; +cd->max_lookbehind = 0; cd->external_options = options; cd->external_flags = 0; cd->open_caps = NULL; @@ -7041,13 +7875,12 @@ ptr += skipatstart; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS, - &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, - &length); +(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, + FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, - cd->hwm - cworkspace)); + (int)(cd->hwm - cworkspace))); if (length > MAX_PATTERN_SIZE) { @@ -7060,8 +7893,8 @@ because nowadays we limit the maximum value of cd->names_found and cd->name_entry_size. */ -size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3); -re = (real_pcre *)(pcre_malloc)(size); +size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar); +re = (REAL_PCRE *)(PUBL(malloc))(size); if (re == NULL) { @@ -7079,14 +7912,13 @@ re->size = (int)size; re->options = cd->external_options; re->flags = cd->external_flags; -re->dummy1 = 0; -re->first_byte = 0; -re->req_byte = 0; -re->name_table_offset = sizeof(real_pcre); +re->first_char = 0; +re->req_char = 0; +re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar); re->name_entry_size = cd->name_entry_size; re->name_count = cd->names_found; re->ref_count = 0; -re->tables = (tables == _pcre_default_tables)? NULL : tables; +re->tables = (tables == PRIV(default_tables))? NULL : tables; re->nullpad = NULL; /* The starting points of the name/number translation table and of the code are @@ -7097,12 +7929,14 @@ */ cd->final_bracount = cd->bracount; /* Save for checking forward references */ +cd->assert_depth = 0; cd->bracount = 0; +cd->max_lookbehind = 0; cd->names_found = 0; -cd->name_table = (uschar *)re + re->name_table_offset; +cd->name_table = (pcre_uchar *)re + re->name_table_offset; codestart = cd->name_table + re->name_entry_size * re->name_count; cd->start_code = codestart; -cd->hwm = cworkspace; +cd->hwm = (pcre_uchar *)(cd->start_workspace); cd->req_varyopt = 0; cd->had_accept = FALSE; cd->check_lookbehind = FALSE; @@ -7112,16 +7946,17 @@ error, errorcode will be set non-zero, so we don't need to look at the result of the function here. */ -ptr = (const uschar *)pattern + skipatstart; -code = (uschar *)codestart; +ptr = (const pcre_uchar *)pattern + skipatstart; +code = (pcre_uchar *)codestart; *code = OP_BRA; -(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr, - &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL); +(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, + &firstchar, &reqchar, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; -re->flags = cd->external_flags; +re->max_lookbehind = cd->max_lookbehind; +re->flags = cd->external_flags | PCRE_MODE; -if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */ +if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ @@ -7136,20 +7971,34 @@ if (code - codestart > length) errorcode = ERR23; #endif -/* Fill in any forward references that are required. */ +/* Fill in any forward references that are required. There may be repeated +references; optimize for them, as searching a large regex takes time. */ -while (errorcode == 0 && cd->hwm > cworkspace) +if (cd->hwm > cd->start_workspace) { - int offset, recno; - const uschar *groupptr; - cd->hwm -= LINK_SIZE; - offset = GET(cd->hwm, 0); - recno = GET(codestart, offset); - groupptr = _pcre_find_bracket(codestart, utf8, recno); - if (groupptr == NULL) errorcode = ERR53; - else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart)); + int prev_recno = -1; + const pcre_uchar *groupptr = NULL; + while (errorcode == 0 && cd->hwm > cd->start_workspace) + { + int offset, recno; + cd->hwm -= LINK_SIZE; + offset = GET(cd->hwm, 0); + recno = GET(codestart, offset); + if (recno != prev_recno) + { + groupptr = PRIV(find_bracket)(codestart, utf, recno); + prev_recno = recno; + } + if (groupptr == NULL) errorcode = ERR53; + else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart)); + } } +/* If the workspace had to be expanded, free the new memory. */ + +if (cd->workspace_size > COMPILE_WORK_SIZE) + (PUBL(free))((void *)cd->start_workspace); + /* Give an error if there's back reference to a non-existent capturing subpattern. */ @@ -7165,31 +8014,34 @@ if (cd->check_lookbehind) { - uschar *cc = (uschar *)codestart; + pcre_uchar *cc = (pcre_uchar *)codestart; /* Loop, searching for OP_REVERSE items, and process those that do not have their length set. (Actually, it will also re-process any that have a length of zero, but that is a pathological case, and it does no harm.) When we find one, we temporarily terminate the branch it is in while we scan it. */ - for (cc = (uschar *)_pcre_find_bracket(codestart, utf8, -1); + for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1); cc != NULL; - cc = (uschar *)_pcre_find_bracket(cc, utf8, -1)) + cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1)) { if (GET(cc, 1) == 0) { int fixed_length; - uschar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); + pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE); int end_op = *be; *be = OP_END; - fixed_length = find_fixedlength(cc, re->options, TRUE, cd); + fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE, + cd); *be = end_op; DPRINTF(("fixed length = %d\n", fixed_length)); if (fixed_length < 0) { - errorcode = (fixed_length == -2)? ERR36 : ERR25; + errorcode = (fixed_length == -2)? ERR36 : + (fixed_length == -4)? ERR70 : ERR25; break; } + if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length; PUT(cc, 1, fixed_length); } cc += 1 + LINK_SIZE; @@ -7200,9 +8052,9 @@ if (errorcode != 0) { - (pcre_free)(re); + (PUBL(free))(re); PCRE_EARLY_ERROR_RETURN: - *erroroffset = (int)(ptr - (const uschar *)pattern); + *erroroffset = (int)(ptr - (const pcre_uchar *)pattern); PCRE_EARLY_ERROR_RETURN2: *errorptr = find_error_text(errorcode); if (errorcodeptr != NULL) *errorcodeptr = errorcode; @@ -7221,18 +8073,42 @@ if ((re->options & PCRE_ANCHORED) == 0) { - int temp_options = re->options; /* May get changed during these scans */ - if (is_anchored(codestart, &temp_options, 0, cd->backref_map)) + if (is_anchored(codestart, 0, cd->backref_map)) re->options |= PCRE_ANCHORED; else { - if (firstbyte < 0) - firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE); - if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ - { - int ch = firstbyte & 255; - re->first_byte = ((firstbyte & REQ_CASELESS) != 0 && - cd->fcc[ch] == ch)? ch : firstbyte; + if (firstchar < 0) + firstchar = find_firstassertedchar(codestart, FALSE); + if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */ + { +#ifdef COMPILE_PCRE8 + re->first_char = firstchar & 0xff; +#else +#ifdef COMPILE_PCRE16 + re->first_char = firstchar & 0xffff; +#endif +#endif + if ((firstchar & REQ_CASELESS) != 0) + { +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + /* We ignore non-ASCII first chars in 8 bit mode. */ + if (utf) + { + if (re->first_char < 128) + { + if (cd->fcc[re->first_char] != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + else if (UCD_OTHERCASE(re->first_char) != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + else +#endif + if (MAX_255(re->first_char) + && cd->fcc[re->first_char] != re->first_char) + re->flags |= PCRE_FCH_CASELESS; + } + re->flags |= PCRE_FIRSTSET; } else if (is_startline(codestart, 0, cd->backref_map)) @@ -7244,12 +8120,36 @@ variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ -if (reqbyte >= 0 && - ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0)) +if (reqchar >= 0 && + ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0)) { - int ch = reqbyte & 255; - re->req_byte = ((reqbyte & REQ_CASELESS) != 0 && - cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte; +#ifdef COMPILE_PCRE8 + re->req_char = reqchar & 0xff; +#else +#ifdef COMPILE_PCRE16 + re->req_char = reqchar & 0xffff; +#endif +#endif + if ((reqchar & REQ_CASELESS) != 0) + { +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + /* We ignore non-ASCII first chars in 8 bit mode. */ + if (utf) + { + if (re->req_char < 128) + { + if (cd->fcc[re->req_char] != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + else if (UCD_OTHERCASE(re->req_char) != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + else +#endif + if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char) + re->flags |= PCRE_RCH_CASELESS; + } + re->flags |= PCRE_REQCHSET; } @@ -7264,38 +8164,46 @@ if ((re->flags & PCRE_FIRSTSET) != 0) { - int ch = re->first_byte & 255; - const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)? - "" : " (caseless)"; - if (isprint(ch)) printf("First char = %c%s\n", ch, caseless); + pcre_uchar ch = re->first_char; + const char *caseless = + ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)"; + if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless); else printf("First char = \\x%02x%s\n", ch, caseless); } if ((re->flags & PCRE_REQCHSET) != 0) { - int ch = re->req_byte & 255; - const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)? - "" : " (caseless)"; - if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless); + pcre_uchar ch = re->req_char; + const char *caseless = + ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)"; + if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless); else printf("Req char = \\x%02x%s\n", ch, caseless); } -pcre_printint(re, stdout, TRUE); +#ifdef COMPILE_PCRE8 +pcre_printint((pcre *)re, stdout, TRUE); +#else +pcre16_printint((pcre *)re, stdout, TRUE); +#endif /* This check is done here in the debugging case so that the code that was compiled can be seen. */ if (code - codestart > length) { - (pcre_free)(re); + (PUBL(free))(re); *errorptr = find_error_text(ERR23); - *erroroffset = ptr - (uschar *)pattern; + *erroroffset = ptr - (pcre_uchar *)pattern; if (errorcodeptr != NULL) *errorcodeptr = ERR23; return NULL; } #endif /* PCRE_DEBUG */ +#ifdef COMPILE_PCRE8 return (pcre *)re; +#else +return (pcre16 *)re; +#endif } /* End of pcre_compile.c */ diff -Nru pcre3-8.12/pcre_config.c pcre3-8.31/pcre_config.c --- pcre3-8.12/pcre_config.c 2009-02-28 15:49:03.000000000 +0000 +++ pcre3-8.31/pcre_config.c 2012-01-17 14:10:47.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -45,6 +45,9 @@ #include "config.h" #endif +/* Keep the original link size. */ +static int real_link_size = LINK_SIZE; + #include "pcre_internal.h" @@ -62,18 +65,41 @@ Returns: 0 if data returned, negative on error */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_config(int what, void *where) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_config(int what, void *where) +#endif { switch (what) { case PCRE_CONFIG_UTF8: -#ifdef SUPPORT_UTF8 +#if defined COMPILE_PCRE16 + *((int *)where) = 0; + return PCRE_ERROR_BADOPTION; +#else +#if defined SUPPORT_UTF + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; +#endif + + case PCRE_CONFIG_UTF16: +#if defined COMPILE_PCRE8 + *((int *)where) = 0; + return PCRE_ERROR_BADOPTION; +#else +#if defined SUPPORT_UTF *((int *)where) = 1; #else *((int *)where) = 0; #endif break; +#endif case PCRE_CONFIG_UNICODE_PROPERTIES: #ifdef SUPPORT_UCP @@ -83,6 +109,22 @@ #endif break; + case PCRE_CONFIG_JIT: +#ifdef SUPPORT_JIT + *((int *)where) = 1; +#else + *((int *)where) = 0; +#endif + break; + + case PCRE_CONFIG_JITTARGET: +#ifdef SUPPORT_JIT + *((const char **)where) = PRIV(jit_get_target)(); +#else + *((const char **)where) = NULL; +#endif + break; + case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; @@ -96,7 +138,7 @@ break; case PCRE_CONFIG_LINK_SIZE: - *((int *)where) = LINK_SIZE; + *((int *)where) = real_link_size; break; case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: diff -Nru pcre3-8.12/pcre_dfa_exec.c pcre3-8.31/pcre_dfa_exec.c --- pcre3-8.12/pcre_dfa_exec.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_dfa_exec.c 2012-06-20 15:08:50.000000000 +0000 @@ -7,7 +7,7 @@ below for why this module is different). Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -38,10 +38,9 @@ ----------------------------------------------------------------------------- */ - /* This module contains the external function pcre_dfa_exec(), which is an alternative matching function that uses a sort of DFA algorithm (not a true -FSM). This is NOT Perl- compatible, but it has advantages in certain +FSM). This is NOT Perl-compatible, but it has advantages in certain applications. */ @@ -113,7 +112,7 @@ the character is to be found. ***NOTE*** If the start of this table is modified, the three tables that follow must also be modified. */ -static const uschar coptable[] = { +static const pcre_uint8 coptable[] = { 0, /* End */ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */ @@ -121,22 +120,34 @@ 0, 0, /* \P, \p */ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */ 0, /* \X */ - 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ - 1, /* Charnc */ + 1, /* Chari */ 1, /* not */ + 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ - 3, 3, 3, /* upto, minupto, exact */ - 1, 1, 1, 3, /* *+, ++, ?+, upto+ */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */ + 1+IMM2_SIZE, /* exact */ + 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */ + 1+IMM2_SIZE, /* exact I */ + 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ - 3, 3, 3, /* NOT upto, minupto, exact */ - 1, 1, 1, 3, /* NOT *+, ++, ?+, updo+ */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */ + 1+IMM2_SIZE, /* NOT exact */ + 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */ + 1+IMM2_SIZE, /* NOT exact I */ + 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ - 3, 3, 3, /* Type upto, minupto, exact */ - 1, 1, 1, 3, /* Type *+, ++, ?+, upto+ */ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */ + 1+IMM2_SIZE, /* Type exact */ + 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */ /* Character class & ref repeats */ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */ 0, 0, /* CRRANGE, CRMINRANGE */ @@ -144,26 +155,30 @@ 0, /* NCLASS */ 0, /* XCLASS - variable length */ 0, /* REF */ + 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ - 0, /* Reverse */ - 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */ - 0, 0, 0, /* SBRA, SCBRA, SCOND */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ - 0, 0, /* BRAZERO, BRAMINZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */ - 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0 /* CLOSE, SKIPZERO */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -171,7 +186,7 @@ the subject is reached. ***NOTE*** If the start of this table is modified, the two tables that follow must also be modified. */ -static const uschar poptable[] = { +static const pcre_uint8 poptable[] = { 0, /* End */ 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ @@ -179,18 +194,25 @@ 1, 1, /* \P, \p */ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ 1, /* \X */ - 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */ + 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */ 1, /* Char */ - 1, /* Charnc */ + 1, /* Chari */ 1, /* not */ + 1, /* noti */ /* Positive single-char repeats */ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ 1, 1, 1, /* upto, minupto, exact */ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* upto I, minupto I, exact I */ + 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */ /* Negative single-char repeats - only for chars < 256 */ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */ 1, 1, 1, /* NOT upto, minupto, exact */ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */ + 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */ + 1, 1, 1, /* NOT upto I, minupto I, exact I */ + 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */ /* Positive type repeats */ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */ 1, 1, 1, /* Type upto, minupto, exact */ @@ -202,32 +224,36 @@ 1, /* NCLASS */ 1, /* XCLASS - variable length */ 0, /* REF */ + 0, /* REFI */ 0, /* RECURSE */ 0, /* CALLOUT */ 0, /* Alt */ 0, /* Ket */ 0, /* KetRmax */ 0, /* KetRmin */ + 0, /* KetRpos */ + 0, /* Reverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ - 0, /* Reverse */ - 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */ - 0, 0, 0, /* SBRA, SCBRA, SCOND */ + 0, 0, /* ONCE, ONCE_NC */ + 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ + 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, NCREF */ 0, 0, /* RREF, NRREF */ 0, /* DEF */ - 0, 0, /* BRAZERO, BRAMINZERO */ - 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */ - 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */ - 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ + 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ + 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ + 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ + 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0 /* CLOSE, SKIPZERO */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, and \w */ -static const uschar toptable1[] = { +static const pcre_uint8 toptable1[] = { 0, 0, 0, 0, 0, 0, ctype_digit, ctype_digit, ctype_space, ctype_space, @@ -235,7 +261,7 @@ 0, 0 /* OP_ANY, OP_ALLANY */ }; -static const uschar toptable2[] = { +static const pcre_uint8 toptable2[] = { 0, 0, 0, 0, 0, 0, ctype_digit, 0, ctype_space, 0, @@ -252,11 +278,10 @@ typedef struct stateblock { int offset; /* Offset to opcode */ int count; /* Count for repeats */ - int ims; /* ims flag bits */ int data; /* Some use extra data */ } stateblock; -#define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int)) +#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) #ifdef PCRE_DEBUG @@ -275,7 +300,7 @@ */ static void -pchars(unsigned char *p, int length, FILE *f) +pchars(const pcre_uchar *p, int length, FILE *f) { int c; while (length-- > 0) @@ -308,9 +333,7 @@ offsetcount size of same workspace vector of workspace wscount size of same - ims the current ims flags rlevel function call recursion level - recursing regex recursive call level Returns: > 0 => number of match offset pairs placed in offsets = 0 => offsets overflowed; longest matches are present @@ -325,7 +348,6 @@ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ - next_active_state->ims = ims; \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ @@ -336,7 +358,6 @@ { \ next_active_state->offset = (x); \ next_active_state->count = (y); \ - next_active_state->ims = ims; \ next_active_state->data = (z); \ next_active_state++; \ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ @@ -348,7 +369,6 @@ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ - next_new_state->ims = ims; \ next_new_state++; \ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \ } \ @@ -359,10 +379,10 @@ { \ next_new_state->offset = (x); \ next_new_state->count = (y); \ - next_new_state->ims = ims; \ next_new_state->data = (z); \ next_new_state++; \ - DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \ + DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \ + (x), (y), (z), __LINE__)); \ } \ else return PCRE_ERROR_DFA_WSSIZE @@ -371,39 +391,41 @@ static int internal_dfa_exec( dfa_match_data *md, - const uschar *this_start_code, - const uschar *current_subject, + const pcre_uchar *this_start_code, + const pcre_uchar *current_subject, int start_offset, int *offsets, int offsetcount, int *workspace, int wscount, - int ims, - int rlevel, - int recursing) + int rlevel) { stateblock *active_states, *new_states, *temp_states; stateblock *next_active_state, *next_new_state; -const uschar *ctypes, *lcc, *fcc; -const uschar *ptr; -const uschar *end_code, *first_op; +const pcre_uint8 *ctypes, *lcc, *fcc; +const pcre_uchar *ptr; +const pcre_uchar *end_code, *first_op; + +dfa_recursion_info new_recursive; int active_count, new_count, match_count; /* Some fields in the md block are frequently referenced, so we load them into independent variables in the hope that this will perform better. */ -const uschar *start_subject = md->start_subject; -const uschar *end_subject = md->end_subject; -const uschar *start_code = md->start_code; +const pcre_uchar *start_subject = md->start_subject; +const pcre_uchar *end_subject = md->end_subject; +const pcre_uchar *start_code = md->start_code; -#ifdef SUPPORT_UTF8 -BOOL utf8 = (md->poptions & PCRE_UTF8) != 0; +#ifdef SUPPORT_UTF +BOOL utf = (md->poptions & PCRE_UTF8) != 0; #else -BOOL utf8 = FALSE; +BOOL utf = FALSE; #endif +BOOL reset_could_continue = FALSE; + rlevel++; offsetcount &= (-2); @@ -412,8 +434,8 @@ (2 * INTS_PER_STATEBLOCK); DPRINTF(("\n%.*s---------------------\n" - "%.*sCall to internal_dfa_exec f=%d r=%d\n", - rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing)); + "%.*sCall to internal_dfa_exec f=%d\n", + rlevel*2-2, SP, rlevel*2-2, SP, rlevel)); ctypes = md->tables + ctypes_offset; lcc = md->tables + lcc_offset; @@ -426,7 +448,9 @@ new_count = 0; first_op = this_start_code + 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) + ? IMM2_SIZE:0); /* The first thing in any (sub) pattern is a bracket of some sort. Push all the alternative states onto the list, and find out where the end is. This @@ -454,18 +478,16 @@ /* If we can't go back the amount required for the longest lookbehind pattern, go back as far as we can; some alternatives may still be viable. */ -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF /* In character mode we have to step back character by character */ - if (utf8) + if (utf) { for (gone_back = 0; gone_back < max_back; gone_back++) { if (current_subject <= start_subject) break; current_subject--; - while (current_subject > start_subject && - (*current_subject & 0xc0) == 0x80) - current_subject--; + ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--); } } else @@ -525,7 +547,9 @@ else { int length = 1 + LINK_SIZE + - ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0); + ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA || + *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS) + ? IMM2_SIZE:0); do { ADD_NEW((int)(end_code - start_code + length), 0); @@ -538,7 +562,7 @@ workspace[0] = 0; /* Bit indicating which vector is current */ -DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, end_code - start_code)); +DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code))); /* Loop for scanning the subject */ @@ -549,7 +573,9 @@ int clen, dlen; unsigned int c, d; int forced_fail = 0; - BOOL could_continue = FALSE; + BOOL partial_newline = FALSE; + BOOL could_continue = reset_could_continue; + reset_could_continue = FALSE; /* Make the new state list into the active state list and empty the new state list. */ @@ -565,7 +591,7 @@ #ifdef PCRE_DEBUG printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP); - pchars((uschar *)ptr, strlen((char *)ptr), stdout); + pchars(ptr, STRLEN_UC(ptr), stdout); printf("\"\n"); printf("%.*sActive states: ", rlevel*2-2, SP); @@ -585,10 +611,10 @@ if (ptr < end_subject) { - clen = 1; /* Number of bytes in the character */ -#ifdef SUPPORT_UTF8 - if (utf8) { GETCHARLEN(c, ptr, clen); } else -#endif /* SUPPORT_UTF8 */ + clen = 1; /* Number of data items in the character */ +#ifdef SUPPORT_UTF + if (utf) { GETCHARLEN(c, ptr, clen); } else +#endif /* SUPPORT_UTF */ c = *ptr; } else @@ -605,7 +631,8 @@ for (i = 0; i < active_count; i++) { stateblock *current_state = active_states + i; - const uschar *code; + BOOL caseless = FALSE; + const pcre_uchar *code; int state_offset = current_state->offset; int count, codevalue, rrc; @@ -616,13 +643,10 @@ else printf("0x%02x\n", c); #endif - /* This variable is referred to implicity in the ADD_xxx macros. */ - - ims = current_state->ims; - /* A negative offset is a special case meaning "hold off going to this (negated) state until the number of characters in the data field have - been skipped". */ + been skipped". If the could_continue flag was passed over from a previous + state, arrange for it to passed on. */ if (state_offset < 0) { @@ -631,6 +655,7 @@ DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP)); ADD_NEW_DATA(state_offset, current_state->count, current_state->data - 1); + if (could_continue) reset_could_continue = TRUE; continue; } else @@ -670,17 +695,17 @@ permitted. We also use this mechanism for opcodes such as OP_TYPEPLUS that take an - argument that is not a data character - but is always one byte long. We - have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in - this case. To keep the other cases fast, convert these ones to new opcodes. - */ + argument that is not a data character - but is always one byte long because + the values are small. We have to take special action to deal with \P, \p, + \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert + these ones to new opcodes. */ if (coptable[codevalue] > 0) { dlen = 1; -#ifdef SUPPORT_UTF8 - if (utf8) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else -#endif /* SUPPORT_UTF8 */ +#ifdef SUPPORT_UTF + if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else +#endif /* SUPPORT_UTF */ d = code[coptable[codevalue]]; if (codevalue >= OP_TYPESTAR) { @@ -725,7 +750,12 @@ /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry - on with the next opcode. Otherwise, unless we have an empty string and + on with the next opcode. For repeating opcodes, also add the repeat + state. Note that KETRPOS will always be encountered at the end of the + subpattern, because the possessive subpattern repeats are always handled + using recursive calls. Thus, it never adds any new states. + + At the end of the (sub)pattern, unless we have an empty string and PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the start of the subject, save the match data, shifting up all previous matches so we always have the longest first. */ @@ -733,6 +763,7 @@ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: + case OP_KETRPOS: if (code != end_code) { ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0); @@ -749,7 +780,7 @@ current_subject > start_subject + md->start_offset))) { if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0; - else if (match_count > 0 && ++match_count * 2 >= offsetcount) + else if (match_count > 0 && ++match_count * 2 > offsetcount) match_count = 0; count = ((match_count == 0)? offsetcount : match_count * 2) - 2; if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int)); @@ -758,7 +789,7 @@ offsets[0] = (int)(current_subject - start_subject); offsets[1] = (int)(ptr - start_subject); DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP, - offsets[1] - offsets[0], current_subject)); + offsets[1] - offsets[0], (char *)current_subject)); } if ((md->moptions & PCRE_DFA_SHORTEST) != 0) { @@ -795,7 +826,7 @@ /*-----------------------------------------------------------------*/ case OP_CBRA: case OP_SCBRA: - ADD_ACTIVE((int)(code - start_code + 3 + LINK_SIZE), 0); + ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0); code += GET(code, 1); while (*code == OP_ALT) { @@ -822,10 +853,14 @@ /*-----------------------------------------------------------------*/ case OP_CIRC: + if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) + { ADD_ACTIVE(state_offset + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + case OP_CIRCM: if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) || - ((ims & PCRE_MULTILINE) != 0 && - ptr != end_subject && - WAS_NEWLINE(ptr))) + (ptr != end_subject && WAS_NEWLINE(ptr))) { ADD_ACTIVE(state_offset + 1, 0); } break; @@ -840,12 +875,6 @@ break; /*-----------------------------------------------------------------*/ - case OP_OPT: - ims = code[1]; - ADD_ACTIVE(state_offset + 2, 0); - break; - - /*-----------------------------------------------------------------*/ case OP_SOD: if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); } break; @@ -865,7 +894,20 @@ /*-----------------------------------------------------------------*/ case OP_ANY: if (clen > 0 && !IS_NEWLINE(ptr)) - { ADD_NEW(state_offset + 1, 0); } + { + if (ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else + { + ADD_NEW(state_offset + 1, 0); + } + } break; /*-----------------------------------------------------------------*/ @@ -890,11 +932,49 @@ could_continue = TRUE; else if (clen == 0 || ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) && - ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen) + (ptr == end_subject - md->nllen) )) { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } + } + break; + + /*-----------------------------------------------------------------*/ + case OP_DOLLM: + if ((md->moptions & PCRE_NOTEOL) == 0) + { + if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0) + could_continue = TRUE; + else if (clen == 0 || + ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr))) + { ADD_ACTIVE(state_offset + 1, 0); } + else if (ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + { + reset_could_continue = TRUE; + ADD_NEW_DATA(-(state_offset + 1), 0, 1); + } + else could_continue = partial_newline = TRUE; + } } - else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr)) + else if (IS_NEWLINE(ptr)) { ADD_ACTIVE(state_offset + 1, 0); } break; @@ -925,10 +1005,10 @@ if (ptr > start_subject) { - const uschar *temp = ptr - 1; + const pcre_uchar *temp = ptr - 1; if (temp < md->start_used_ptr) md->start_used_ptr = temp; -#ifdef SUPPORT_UTF8 - if (utf8) BACKCHAR(temp); +#ifdef SUPPORT_UTF + if (utf) { BACKCHAR(temp); } #endif GETCHARTEST(d, temp); #ifdef SUPPORT_UCP @@ -993,7 +1073,7 @@ break; case PT_GC: - OK = _pcre_ucp_gentype[prop->chartype] == code[2]; + OK = PRIV(ucp_gentype)[prop->chartype] == code[2]; break; case PT_PC: @@ -1007,24 +1087,24 @@ /* These are specials for combination cases. */ case PT_ALNUM: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N; + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; @@ -1055,7 +1135,15 @@ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0) { - if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + if (d == OP_ANY && ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) @@ -1078,7 +1166,15 @@ ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { - if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + if (d == OP_ANY && ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) @@ -1100,7 +1196,15 @@ ADD_ACTIVE(state_offset + 2, 0); if (clen > 0) { - if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + if (d == OP_ANY && ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) @@ -1120,13 +1224,21 @@ count = current_state->count; /* Number already matched */ if (clen > 0) { - if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + if (d == OP_ANY && ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) { if (++count >= GET2(code, 1)) - { ADD_NEW(state_offset + 4, 0); } + { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); } else { ADD_NEW(state_offset, count); } } @@ -1137,11 +1249,19 @@ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - ADD_ACTIVE(state_offset + 4, 0); + ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { - if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || + if (d == OP_ANY && ptr + 1 >= md->end_subject && + (md->moptions & (PCRE_PARTIAL_HARD)) != 0 && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + could_continue = partial_newline = TRUE; + } + else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) || (c < 256 && (d != OP_ANY || !IS_NEWLINE(ptr)) && ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0)) @@ -1152,7 +1272,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW(state_offset + 4, 0); } + { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } @@ -1187,7 +1307,7 @@ break; case PT_GC: - OK = _pcre_ucp_gentype[prop->chartype] == code[3]; + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; break; case PT_PC: @@ -1201,24 +1321,24 @@ /* These are specials for combination cases. */ case PT_ALNUM: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N; + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; @@ -1250,7 +1370,7 @@ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - const uschar *nptr = ptr + clen; + const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) { @@ -1434,7 +1554,7 @@ break; case PT_GC: - OK = _pcre_ucp_gentype[prop->chartype] == code[3]; + OK = PRIV(ucp_gentype)[prop->chartype] == code[3]; break; case PT_PC: @@ -1448,24 +1568,24 @@ /* These are specials for combination cases. */ case PT_ALNUM: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N; + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; @@ -1506,7 +1626,7 @@ ADD_ACTIVE(state_offset + 2, 0); if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - const uschar *nptr = ptr + clen; + const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY) @@ -1688,13 +1808,13 @@ case OP_PROP_EXTRA + OP_TYPEMINUPTO: case OP_PROP_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 6, 0); } + { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { BOOL OK; const ucd_record * prop = GET_UCD(c); - switch(code[4]) + switch(code[1 + IMM2_SIZE + 1]) { case PT_ANY: OK = TRUE; @@ -1706,38 +1826,38 @@ break; case PT_GC: - OK = _pcre_ucp_gentype[prop->chartype] == code[5]; + OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2]; break; case PT_PC: - OK = prop->chartype == code[5]; + OK = prop->chartype == code[1 + IMM2_SIZE + 2]; break; case PT_SC: - OK = prop->script == code[5]; + OK = prop->script == code[1 + IMM2_SIZE + 2]; break; /* These are specials for combination cases. */ case PT_ALNUM: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N; + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N; break; case PT_SPACE: /* Perl space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR; break; case PT_PXSPACE: /* POSIX space */ - OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR; break; case PT_WORD: - OK = _pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE; break; @@ -1756,7 +1876,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW(state_offset + 6, 0); } + { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); } else { ADD_NEW(state_offset, count); } } @@ -1769,11 +1889,11 @@ case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO: case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 4, 0); } + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - const uschar *nptr = ptr + clen; + const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) { @@ -1789,8 +1909,10 @@ ncount++; nptr += ndlen; } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; if (++count >= GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); } + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } } @@ -1803,7 +1925,7 @@ case OP_ANYNL_EXTRA + OP_TYPEMINUPTO: case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 4, 0); } + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { @@ -1830,7 +1952,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); } + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); } else { ADD_NEW_DATA(-state_offset, count, ncount); } break; @@ -1847,7 +1969,7 @@ case OP_VSPACE_EXTRA + OP_TYPEMINUPTO: case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 4, 0); } + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { @@ -1876,7 +1998,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 4), 0, 0); } + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } @@ -1889,7 +2011,7 @@ case OP_HSPACE_EXTRA + OP_TYPEMINUPTO: case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO: if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT) - { ADD_ACTIVE(state_offset + 4, 0); } + { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ if (clen > 0) { @@ -1931,7 +2053,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW_DATA(-(state_offset + 4), 0, 0); } + { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); } else { ADD_NEW_DATA(-state_offset, count, 0); } } @@ -1950,35 +2072,35 @@ break; /*-----------------------------------------------------------------*/ - case OP_CHARNC: + case OP_CHARI: if (clen == 0) break; -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else { unsigned int othercase; - if (c < 128) othercase = fcc[c]; else - - /* If we have Unicode property support, we can use it to test the - other case of the character. */ - + if (c < 128) + othercase = fcc[c]; + else + /* If we have Unicode property support, we can use it to test the + other case of the character. */ #ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(c); + othercase = UCD_OTHERCASE(c); #else - othercase = NOTACHAR; + othercase = NOTACHAR; #endif if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); } } } else -#endif /* SUPPORT_UTF8 */ - - /* Non-UTF-8 mode */ +#endif /* SUPPORT_UTF */ + /* Not UTF mode */ { - if (lcc[c] == lcc[d]) { ADD_NEW(state_offset + 2, 0); } + if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d)) + { ADD_NEW(state_offset + 2, 0); } } break; @@ -1992,7 +2114,7 @@ case OP_EXTUNI: if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - const uschar *nptr = ptr + clen; + const pcre_uchar *nptr = ptr + clen; int ncount = 0; while (nptr < end_subject) { @@ -2002,6 +2124,8 @@ ncount++; nptr += nclen; } + if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; ADD_NEW_DATA(-(state_offset + 1), 0, ncount); } break; @@ -2027,7 +2151,13 @@ break; case 0x000d: - if (ptr + 1 < end_subject && ptr[1] == 0x0a) + if (ptr + 1 >= end_subject) + { + ADD_NEW(state_offset + 1, 0); + if ((md->moptions & PCRE_PARTIAL_HARD) != 0) + reset_could_continue = TRUE; + } + else if (ptr[1] == 0x0a) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } @@ -2136,19 +2266,45 @@ break; /*-----------------------------------------------------------------*/ - /* Match a negated single character. This is only used for one-byte - characters, that is, we know that d < 256. The character we are - checking (c) can be multibyte. */ + /* Match a negated single character casefully. */ case OP_NOT: + if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); } + break; + + /*-----------------------------------------------------------------*/ + /* Match a negated single character caselessly. */ + + case OP_NOTI: if (clen > 0) { - unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d; - if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); } + unsigned int otherd; +#ifdef SUPPORT_UTF + if (utf && d >= 128) + { +#ifdef SUPPORT_UCP + otherd = UCD_OTHERCASE(d); +#endif /* SUPPORT_UCP */ + } + else +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); + if (c != d && c != otherd) + { ADD_NEW(state_offset + dlen + 1, 0); } } break; /*-----------------------------------------------------------------*/ + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + + /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2160,18 +2316,18 @@ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { -#ifdef SUPPORT_UTF8 - if (utf8 && d >= 128) +#ifdef SUPPORT_UTF + if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ - otherd = fcc[d]; +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { @@ -2188,6 +2344,15 @@ break; /*-----------------------------------------------------------------*/ + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2198,18 +2363,18 @@ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { -#ifdef SUPPORT_UTF8 - if (utf8 && d >= 128) +#ifdef SUPPORT_UTF + if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ - otherd = fcc[d]; +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { @@ -2224,6 +2389,15 @@ break; /*-----------------------------------------------------------------*/ + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2234,18 +2408,18 @@ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { -#ifdef SUPPORT_UTF8 - if (utf8 && d >= 128) +#ifdef SUPPORT_UTF + if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ - otherd = fcc[d]; +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { @@ -2260,29 +2434,34 @@ break; /*-----------------------------------------------------------------*/ + case OP_EXACTI: + case OP_NOTEXACTI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { -#ifdef SUPPORT_UTF8 - if (utf8 && d >= 128) +#ifdef SUPPORT_UTF + if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ - otherd = fcc[d]; +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { if (++count >= GET2(code, 1)) - { ADD_NEW(state_offset + dlen + 3, 0); } + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } @@ -2290,29 +2469,38 @@ break; /*-----------------------------------------------------------------*/ + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + caseless = TRUE; + codevalue -= OP_STARI - OP_STAR; + /* Fall through */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: case OP_NOTUPTO: case OP_NOTMINUPTO: case OP_NOTPOSUPTO: - ADD_ACTIVE(state_offset + dlen + 3, 0); + ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0); count = current_state->count; /* Number already matched */ if (clen > 0) { unsigned int otherd = NOTACHAR; - if ((ims & PCRE_CASELESS) != 0) + if (caseless) { -#ifdef SUPPORT_UTF8 - if (utf8 && d >= 128) +#ifdef SUPPORT_UTF + if (utf && d >= 128) { #ifdef SUPPORT_UCP otherd = UCD_OTHERCASE(d); #endif /* SUPPORT_UCP */ } else -#endif /* SUPPORT_UTF8 */ - otherd = fcc[d]; +#endif /* SUPPORT_UTF */ + otherd = TABLE_GET(d, fcc, d); } if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR)) { @@ -2322,7 +2510,7 @@ next_active_state--; } if (++count >= GET2(code, 1)) - { ADD_NEW(state_offset + dlen + 3, 0); } + { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } @@ -2339,18 +2527,18 @@ { BOOL isinclass = FALSE; int next_state_offset; - const uschar *ecode; + const pcre_uchar *ecode; /* For a simple class, there is always just a 32-byte table, and we can set isinclass from it. */ if (codevalue != OP_XCLASS) { - ecode = code + 33; + ecode = code + 1 + (32 / sizeof(pcre_uchar)); if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : - ((code[1 + c/8] & (1 << (c&7))) != 0); + ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0); } } @@ -2361,7 +2549,7 @@ else { ecode = code + GET(code, 1); - if (clen > 0) isinclass = _pcre_xclass(c, code + 1 + LINK_SIZE); + if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); } /* At this point, isinclass is set for all kinds of class, and ecode @@ -2395,12 +2583,12 @@ case OP_CRMINRANGE: count = current_state->count; /* Already matched */ if (count >= GET2(ecode, 1)) - { ADD_ACTIVE(next_state_offset + 5, 0); } + { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } if (isinclass) { - int max = GET2(ecode, 3); + int max = GET2(ecode, 1 + IMM2_SIZE); if (++count >= max && max != 0) /* Max 0 => no limit */ - { ADD_NEW(next_state_offset + 5, 0); } + { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } else { ADD_NEW(state_offset, count); } } @@ -2431,7 +2619,7 @@ int rc; int local_offsets[2]; int local_workspace[1000]; - const uschar *endasscode = code + GET(code, 1); + const pcre_uchar *endasscode = code + GET(code, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); @@ -2444,9 +2632,7 @@ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) @@ -2470,13 +2656,17 @@ if (code[LINK_SIZE+1] == OP_CALLOUT) { rrc = 0; - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; + PUBL(callout_block) cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[LINK_SIZE+2]; cb.offset_vector = offsets; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; +#else + cb.subject = (PCRE_SPTR16)start_subject; +#endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); cb.current_position = (int)(ptr - start_subject); @@ -2485,10 +2675,11 @@ cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */ + cb.mark = NULL; /* No (*MARK) support */ + if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ } if (rrc > 0) break; /* Fail this thread */ - code += _pcre_OP_lengths[OP_CALLOUT]; /* Skip callout data */ + code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */ } condcode = code[LINK_SIZE+1]; @@ -2509,10 +2700,10 @@ else if (condcode == OP_RREF || condcode == OP_NRREF) { - int value = GET2(code, LINK_SIZE+2); + int value = GET2(code, LINK_SIZE + 2); if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND; - if (recursing > 0) - { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); } + if (md->recursive != NULL) + { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); } } @@ -2521,8 +2712,8 @@ else { int rc; - const uschar *asscode = code + LINK_SIZE + 1; - const uschar *endasscode = asscode + GET(asscode, 1); + const pcre_uchar *asscode = code + LINK_SIZE + 1; + const pcre_uchar *endasscode = asscode + GET(asscode, 1); while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); @@ -2535,9 +2726,7 @@ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == @@ -2552,28 +2741,47 @@ /*-----------------------------------------------------------------*/ case OP_RECURSE: { + dfa_recursion_info *ri; int local_offsets[1000]; int local_workspace[1000]; + const pcre_uchar *callpat = start_code + GET(code, 1); + int recno = (callpat == md->start_code)? 0 : + GET2(callpat, 1 + LINK_SIZE); int rc; - DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP, - recursing + 1)); + DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP)); + + /* Check for repeating a recursion without advancing the subject + pointer. This should catch convoluted mutual recursions. (Some simple + cases are caught at compile time.) */ + + for (ri = md->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && ptr == ri->subject_position) + return PCRE_ERROR_RECURSELOOP; + + /* Remember this recursion and where we started it so as to + catch infinite loops. */ + + new_recursive.group_num = recno; + new_recursive.subject_position = ptr; + new_recursive.prevrec = md->recursive; + md->recursive = &new_recursive; rc = internal_dfa_exec( md, /* fixed match data */ - start_code + GET(code, 1), /* this subexpression's code */ + callpat, /* this subexpression's code */ ptr, /* where we currently are */ (int)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing + 1); /* regex recurse level */ + rlevel); /* function recursion level */ + + md->recursive = new_recursive.prevrec; /* Done this recursion */ - DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP, - recursing + 1, rc)); + DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP, + rc)); /* Ran out of internal offsets */ @@ -2587,10 +2795,15 @@ { for (rc = rc*2 - 2; rc >= 0; rc -= 2) { - const uschar *p = start_subject + local_offsets[rc]; - const uschar *pp = start_subject + local_offsets[rc+1]; int charcount = local_offsets[rc+1] - local_offsets[rc]; - while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--; +#ifdef SUPPORT_UTF + if (utf) + { + const pcre_uchar *p = start_subject + local_offsets[rc]; + const pcre_uchar *pp = start_subject + local_offsets[rc+1]; + while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; + } +#endif if (charcount > 0) { ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1)); @@ -2606,7 +2819,99 @@ break; /*-----------------------------------------------------------------*/ + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + { + int charcount, matched_count; + const pcre_uchar *local_ptr = ptr; + BOOL allow_zero; + + if (codevalue == OP_BRAPOSZERO) + { + allow_zero = TRUE; + codevalue = *(++code); /* Codevalue will be one of above BRAs */ + } + else allow_zero = FALSE; + + /* Loop to match the subpattern as many times as possible as if it were + a complete pattern. */ + + for (matched_count = 0;; matched_count++) + { + int local_offsets[2]; + int local_workspace[1000]; + + int rc = internal_dfa_exec( + md, /* fixed match data */ + code, /* this subexpression's code */ + local_ptr, /* where we currently are */ + (int)(ptr - start_subject), /* start offset */ + local_offsets, /* offset vector */ + sizeof(local_offsets)/sizeof(int), /* size of same */ + local_workspace, /* workspace vector */ + sizeof(local_workspace)/sizeof(int), /* size of same */ + rlevel); /* function recursion level */ + + /* Failed to match */ + + if (rc < 0) + { + if (rc != PCRE_ERROR_NOMATCH) return rc; + break; + } + + /* Matched: break the loop if zero characters matched. */ + + charcount = local_offsets[1] - local_offsets[0]; + if (charcount == 0) break; + local_ptr += charcount; /* Advance temporary position ptr */ + } + + /* At this point we have matched the subpattern matched_count + times, and local_ptr is pointing to the character after the end of the + last match. */ + + if (matched_count > 0 || allow_zero) + { + const pcre_uchar *end_subpattern = code; + int next_state_offset; + + do { end_subpattern += GET(end_subpattern, 1); } + while (*end_subpattern == OP_ALT); + next_state_offset = + (int)(end_subpattern - start_code + LINK_SIZE + 1); + + /* Optimization: if there are no more active states, and there + are no new states yet set up, then skip over the subject string + right here, to save looping. Otherwise, set up the new state to swing + into action when the end of the matched substring is reached. */ + + if (i + 1 >= active_count && new_count == 0) + { + ptr = local_ptr; + clen = 0; + ADD_NEW(next_state_offset, 0); + } + else + { + const pcre_uchar *p = ptr; + const pcre_uchar *pp = local_ptr; + charcount = (int)(pp - p); +#ifdef SUPPORT_UTF + if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; +#endif + ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); + } + } + } + break; + + /*-----------------------------------------------------------------*/ case OP_ONCE: + case OP_ONCE_NC: { int local_offsets[2]; int local_workspace[1000]; @@ -2620,13 +2925,11 @@ sizeof(local_offsets)/sizeof(int), /* size of same */ local_workspace, /* workspace vector */ sizeof(local_workspace)/sizeof(int), /* size of same */ - ims, /* the current ims flags */ - rlevel, /* function recursion level */ - recursing); /* pass on regex recursion */ + rlevel); /* function recursion level */ if (rc >= 0) { - const uschar *end_subpattern = code; + const pcre_uchar *end_subpattern = code; int charcount = local_offsets[1] - local_offsets[0]; int next_state_offset, repeat_state_offset; @@ -2656,7 +2959,7 @@ /* Optimization: if there are no more active states, and there are no new states yet set up, then skip over the subject string right here, to save looping. Otherwise, set up the new state to swing - into action when the end of the substring is reached. */ + into action when the end of the matched substring is reached. */ else if (i + 1 >= active_count && new_count == 0) { @@ -2679,14 +2982,18 @@ } else { - const uschar *p = start_subject + local_offsets[0]; - const uschar *pp = start_subject + local_offsets[1]; - while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--; +#ifdef SUPPORT_UTF + if (utf) + { + const pcre_uchar *p = start_subject + local_offsets[0]; + const pcre_uchar *pp = start_subject + local_offsets[1]; + while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; + } +#endif ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); if (repeat_state_offset >= 0) { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); } } - } else if (rc != PCRE_ERROR_NOMATCH) return rc; } @@ -2698,13 +3005,17 @@ case OP_CALLOUT: rrc = 0; - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; + PUBL(callout_block) cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[1]; cb.offset_vector = offsets; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; +#else + cb.subject = (PCRE_SPTR16)start_subject; +#endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); cb.current_position = (int)(ptr - start_subject); @@ -2713,10 +3024,11 @@ cb.capture_top = 1; cb.capture_last = -1; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */ + cb.mark = NULL; /* No (*MARK) support */ + if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */ } if (rrc == 0) - { ADD_ACTIVE(state_offset + _pcre_OP_lengths[OP_CALLOUT], 0); } + { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); } break; @@ -2745,7 +3057,7 @@ if (new_count <= 0) { if (rlevel == 1 && /* Top level, and */ - could_continue && /* Some could go on */ + could_continue && /* Some could go on, and */ forced_fail != workspace[1] && /* Not all forced fail & */ ( /* either... */ (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */ @@ -2753,8 +3065,13 @@ ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */ match_count < 0) /* no matches */ ) && /* And... */ - ptr >= end_subject && /* Reached end of subject */ - ptr > md->start_used_ptr) /* Inspected non-empty string */ + ( + partial_newline || /* Either partial NL */ + ( /* or ... */ + ptr >= end_subject && /* End of subject and */ + ptr > md->start_used_ptr) /* Inspected non-empty string */ + ) + ) { if (offsetcount >= 2) { @@ -2813,28 +3130,33 @@ < -1 => some kind of unexpected problem */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, + PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, + int offsetcount, int *workspace, int wscount) +#endif { -real_pcre *re = (real_pcre *)argument_re; +REAL_PCRE *re = (REAL_PCRE *)argument_re; dfa_match_data match_block; dfa_match_data *md = &match_block; -BOOL utf8, anchored, startline, firstline; -const uschar *current_subject, *end_subject, *lcc; - -pcre_study_data internal_study; +BOOL utf, anchored, startline, firstline; +const pcre_uchar *current_subject, *end_subject; const pcre_study_data *study = NULL; -real_pcre internal_re; -const uschar *req_byte_ptr; -const uschar *start_bits = NULL; -BOOL first_byte_caseless = FALSE; -BOOL req_byte_caseless = FALSE; -int first_byte = -1; -int req_byte = -1; -int req_byte2 = -1; +const pcre_uchar *req_char_ptr; +const pcre_uint8 *start_bits = NULL; +BOOL has_first_char = FALSE; +BOOL has_req_char = FALSE; +pcre_uchar first_char = 0; +pcre_uchar first_char2 = 0; +pcre_uchar req_char = 0; +pcre_uchar req_char2 = 0; int newline; /* Plausibility checks */ @@ -2846,10 +3168,27 @@ if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; -/* We need to find the pointer to any study data before we test for byte -flipping, so we scan the extra_data block first. This may set two fields in the -match block, so we must initialize them beforehand. However, the other fields -in the match block must not be set until after the byte flipping. */ +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ + +if (re->magic_number != MAGIC_NUMBER) + return re->magic_number == REVERSED_MAGIC_NUMBER? + PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + +/* If restarting after a partial match, do some sanity checks on the contents +of the workspace. */ + +if ((options & PCRE_DFA_RESTART) != 0) + { + if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 || + workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK) + return PCRE_ERROR_DFA_BADRESTART; + } + +/* Set up study, callout, and table data */ md->tables = re->tables; md->callout_data = NULL; @@ -2868,28 +3207,17 @@ md->tables = extra_data->tables; } -/* Check that the first field in the block is the magic number. If it is not, -test for a regex that was compiled on a host of opposite endianness. If this is -the case, flipped values are put in internal_re and internal_study if there was -study data too. */ - -if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, study, &internal_study); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - if (study != NULL) study = &internal_study; - } - /* Set some local values */ -current_subject = (const unsigned char *)subject + start_offset; -end_subject = (const unsigned char *)subject + length; -req_byte_ptr = current_subject - 1; - -#ifdef SUPPORT_UTF8 -utf8 = (re->options & PCRE_UTF8) != 0; +current_subject = (const pcre_uchar *)subject + start_offset; +end_subject = (const pcre_uchar *)subject + length; +req_char_ptr = current_subject - 1; + +#ifdef SUPPORT_UTF +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = (re->options & PCRE_UTF8) != 0; #else -utf8 = FALSE; +utf = FALSE; #endif anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 || @@ -2897,9 +3225,9 @@ /* The remaining fixed data for passing around. */ -md->start_code = (const uschar *)argument_re + +md->start_code = (const pcre_uchar *)argument_re + re->name_table_offset + re->name_count * re->name_entry_size; -md->start_subject = (const unsigned char *)subject; +md->start_subject = (const pcre_uchar *)subject; md->end_subject = end_subject; md->start_offset = start_offset; md->moptions = options; @@ -2960,18 +3288,24 @@ /* Check a UTF-8 string if required. Unfortunately there's no way of passing back the character offset. */ -#ifdef SUPPORT_UTF8 -if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) { - int tb; - if ((tb = _pcre_valid_utf8((uschar *)subject, length)) >= 0) - return (tb == length && (options & PCRE_PARTIAL_HARD) != 0)? - PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; - if (start_offset > 0 && start_offset < length) + int erroroffset; + int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset); + if (errorcode != 0) { - tb = ((USPTR)subject)[start_offset] & 0xc0; - if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET; + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } + return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; } + if (start_offset > 0 && start_offset < length && + NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) + return PCRE_ERROR_BADUTF8_OFFSET; } #endif @@ -2979,12 +3313,11 @@ is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ -if (md->tables == NULL) md->tables = _pcre_default_tables; +if (md->tables == NULL) md->tables = PRIV(default_tables); -/* The lower casing table and the "must be at the start of a line" flag are -used in a loop when finding where to start. */ +/* The "must be at the start of a line" flags are used in a loop when finding +where to start. */ -lcc = md->tables + lcc_offset; startline = (re->flags & PCRE_STARTLINE) != 0; firstline = (re->options & PCRE_FIRSTLINE) != 0; @@ -2998,9 +3331,16 @@ { if ((re->flags & PCRE_FIRSTSET) != 0) { - first_byte = re->first_byte & 255; - if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) - first_byte = lcc[first_byte]; + has_first_char = TRUE; + first_char = first_char2 = (pcre_uchar)(re->first_char); + if ((re->flags & PCRE_FCH_CASELESS) != 0) + { + first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && first_char > 127) + first_char2 = UCD_OTHERCASE(first_char); +#endif + } } else { @@ -3015,9 +3355,16 @@ if ((re->flags & PCRE_REQCHSET) != 0) { - req_byte = re->req_byte & 255; - req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; - req_byte2 = (md->tables + fcc_offset)[req_byte]; /* case flipped */ + has_req_char = TRUE; + req_char = req_char2 = (pcre_uchar)(re->req_char); + if ((re->flags & PCRE_RCH_CASELESS) != 0) + { + req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && req_char > 127) + req_char2 = UCD_OTHERCASE(req_char); +#endif + } } /* Call the main matching function, looping for a non-anchored regex after a @@ -3030,7 +3377,7 @@ if ((options & PCRE_DFA_RESTART) == 0) { - const uschar *save_end_subject = end_subject; + const pcre_uchar *save_end_subject = end_subject; /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. Implement this by temporarily adjusting @@ -3039,14 +3386,14 @@ if (firstline) { - USPTR t = current_subject; -#ifdef SUPPORT_UTF8 - if (utf8) + PCRE_PUCHAR t = current_subject; +#ifdef SUPPORT_UTF + if (utf) { while (t < md->end_subject && !IS_NEWLINE(t)) { t++; - while (t < end_subject && (*t & 0xc0) == 0x80) t++; + ACROSSCHAR(t < end_subject, *t, t++); } } else @@ -3063,17 +3410,17 @@ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { - /* Advance to a known first byte. */ + /* Advance to a known first char. */ - if (first_byte >= 0) + if (has_first_char) { - if (first_byte_caseless) + if (first_char != first_char2) while (current_subject < end_subject && - lcc[*current_subject] != first_byte) + *current_subject != first_char && *current_subject != first_char2) current_subject++; else while (current_subject < end_subject && - *current_subject != first_byte) + *current_subject != first_char) current_subject++; } @@ -3083,16 +3430,15 @@ { if (current_subject > md->start_subject + start_offset) { -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { while (current_subject < end_subject && !WAS_NEWLINE(current_subject)) { current_subject++; - while(current_subject < end_subject && - (*current_subject & 0xc0) == 0x80) - current_subject++; + ACROSSCHAR(current_subject < end_subject, *current_subject, + current_subject++); } } else @@ -3119,13 +3465,18 @@ while (current_subject < end_subject) { register unsigned int c = *current_subject; +#ifndef COMPILE_PCRE8 + if (c > 255) c = 255; +#endif if ((start_bits[c/8] & (1 << (c&7))) == 0) { current_subject++; -#ifdef SUPPORT_UTF8 - if (utf8) - while(current_subject < end_subject && - (*current_subject & 0xc0) == 0x80) current_subject++; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + /* In non 8-bit mode, the iteration will stop for + characters > 255 at the beginning or not stop at all. */ + if (utf) + ACROSSCHAR(current_subject < end_subject, *current_subject, + current_subject++); #endif } else break; @@ -3141,7 +3492,7 @@ disabling is explicitly requested (and of course, by the test above, this code is not obeyed when restarting after a partial match). */ - if ((options & PCRE_NO_START_OPTIMIZE) == 0 && + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0) { /* If the pattern was studied, a minimum subject length may be set. This @@ -3153,8 +3504,8 @@ (pcre_uint32)(end_subject - current_subject) < study->minlength) return PCRE_ERROR_NOMATCH; - /* If req_byte is set, we know that that character must appear in the - subject for the match to succeed. If the first character is set, req_byte + /* If req_char is set, we know that that character must appear in the + subject for the match to succeed. If the first character is set, req_char must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of work in patterns with nested unlimited repeats that aren't going to match. Writing separate @@ -3166,28 +3517,28 @@ patterns. This showed up when somebody was matching /^C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. */ - if (req_byte >= 0 && end_subject - current_subject < REQ_BYTE_MAX) + if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX) { - register const uschar *p = current_subject + ((first_byte >= 0)? 1 : 0); + register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ - if (p > req_byte_ptr) + if (p > req_char_ptr) { - if (req_byte_caseless) + if (req_char != req_char2) { while (p < end_subject) { register int pp = *p++; - if (pp == req_byte || pp == req_byte2) { p--; break; } + if (pp == req_char || pp == req_char2) { p--; break; } } } else { while (p < end_subject) { - if (*p++ == req_byte) { p--; break; } + if (*p++ == req_char) { p--; break; } } } @@ -3200,7 +3551,7 @@ found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ - req_byte_ptr = p; + req_char_ptr = p; } } } @@ -3209,6 +3560,7 @@ /* OK, now we can do the business */ md->start_used_ptr = current_subject; + md->recursive = NULL; rc = internal_dfa_exec( md, /* fixed match data */ @@ -3219,9 +3571,7 @@ offsetcount, /* size of same */ workspace, /* workspace vector */ wscount, /* size of same */ - re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */ - 0, /* function recurse level */ - 0); /* regex recurse level */ + 0); /* function recurse level */ /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ @@ -3233,11 +3583,13 @@ if (firstline && IS_NEWLINE(current_subject)) break; current_subject++; - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { - while (current_subject < end_subject && (*current_subject & 0xc0) == 0x80) - current_subject++; + ACROSSCHAR(current_subject < end_subject, *current_subject, + current_subject++); } +#endif if (current_subject > end_subject) break; /* If we have just passed a CR and we are now at a LF, and the pattern does diff -Nru pcre3-8.12/pcre_exec.c pcre3-8.31/pcre_exec.c --- pcre3-8.12/pcre_exec.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_exec.c 2012-06-19 18:32:03.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -37,7 +37,6 @@ ----------------------------------------------------------------------------- */ - /* This module contains pcre_exec(), the externally visible function that does pattern matching using an NFA algorithm, trying to mimic Perl as closely as possible. There are also some static supporting functions. */ @@ -57,10 +56,12 @@ #undef min #undef max -/* Flag bits for the match() function */ +/* Values for setting in md->match_function_type to indicate two special types +of call to match(). We do it this way to save on using another stack variable, +as stack usage is to be discouraged. */ -#define match_condassert 0x01 /* Called to check a condition assertion */ -#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */ +#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */ +#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */ /* Non-error returns from the match() function. Error returns are externally defined PCRE_ERROR_xxx codes, which are all negative. */ @@ -73,18 +74,12 @@ #define MATCH_ACCEPT (-999) #define MATCH_COMMIT (-998) -#define MATCH_PRUNE (-997) -#define MATCH_SKIP (-996) -#define MATCH_SKIP_ARG (-995) -#define MATCH_THEN (-994) - -/* This is a convenience macro for code that occurs many times. */ - -#define MRRETURN(ra) \ - { \ - md->mark = markptr; \ - RRETURN(ra); \ - } +#define MATCH_KETRPOS (-997) +#define MATCH_ONCE (-996) +#define MATCH_PRUNE (-995) +#define MATCH_SKIP (-994) +#define MATCH_SKIP_ARG (-993) +#define MATCH_THEN (-992) /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, @@ -117,7 +112,7 @@ */ static void -pchars(const uschar *p, int length, BOOL is_subject, match_data *md) +pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) { unsigned int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; @@ -132,24 +127,29 @@ * Match a back-reference * *************************************************/ -/* If a back reference hasn't been set, the length that is passed is greater -than the number of characters left in the string, so the match fails. +/* Normally, if a back reference hasn't been set, the length that is passed is +negative, so the match always fails. However, in JavaScript compatibility mode, +the length passed is zero. Note that in caseless UTF-8 mode, the number of +subject bytes matched may be different to the number of reference bytes. Arguments: offset index into the offset vector - eptr points into the subject - length length to be matched + eptr pointer into the subject + length length of reference to be matched (number of bytes) md points to match data block - ims the ims flags + caseless TRUE if caseless -Returns: TRUE if matched +Returns: >= 0 the number of subject bytes matched + -1 no match + -2 partial match; always given if at end subject */ -static BOOL -match_ref(int offset, register USPTR eptr, int length, match_data *md, - unsigned long int ims) +static int +match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, + BOOL caseless) { -USPTR p = md->start_subject + md->offset_vector[offset]; +PCRE_PUCHAR eptr_start = eptr; +register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; #ifdef PCRE_DEBUG if (eptr >= md->end_subject) @@ -164,27 +164,37 @@ printf("\n"); #endif -/* Always fail if not enough characters left */ +/* Always fail if reference not set (and not JavaScript compatible - in that +case the length is passed as zero). */ -if (length > md->end_subject - eptr) return FALSE; +if (length < 0) return -1; /* Separate the caseless case for speed. In UTF-8 mode we can only do this properly if Unicode properties are supported. Otherwise, we can check only ASCII characters. */ -if ((ims & PCRE_CASELESS) != 0) +if (caseless) { -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF #ifdef SUPPORT_UCP - if (md->utf8) + if (md->utf) { - USPTR endptr = eptr + length; - while (eptr < endptr) + /* Match characters up to the end of the reference. NOTE: the number of + bytes matched may differ, because there are some characters whose upper and + lower case versions code as different numbers of bytes. For example, U+023A + (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8); + a sequence of 3 of the former uses 6 bytes, as does a sequence of two of + the latter. It is important, therefore, to check the length along the + reference, not along the subject (earlier code did this wrong). */ + + PCRE_PUCHAR endptr = p + length; + while (p < endptr) { int c, d; + if (eptr >= md->end_subject) return -2; /* Partial match */ GETCHARINC(c, eptr); GETCHARINC(d, p); - if (c != d && c != UCD_OTHERCASE(d)) return FALSE; + if (c != d && c != UCD_OTHERCASE(d)) return -1; } } else @@ -193,18 +203,30 @@ /* The same code works when not in UTF-8 mode and in UTF-8 mode when there is no UCP support. */ - - while (length-- > 0) - { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; } + { + while (length-- > 0) + { + if (eptr >= md->end_subject) return -2; /* Partial match */ + if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; + p++; + eptr++; + } + } } /* In the caseful case, we can just compare the bytes, whether or not we are in UTF-8 mode. */ else - { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } + { + while (length-- > 0) + { + if (eptr >= md->end_subject) return -2; /* Partial match */ + if (*p++ != *eptr++) return -1; + } + } -return TRUE; +return (int)(eptr - eptr_start); } @@ -256,7 +278,7 @@ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, - RM61, RM62 }; + RM61, RM62, RM63, RM64, RM65, RM66 }; /* These versions of the macros use the stack, as normal. There are debugging versions and production versions. Note that the "rw" argument of RMATCH isn't @@ -266,10 +288,10 @@ #define REGISTER register #ifdef PCRE_DEBUG -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ +#define RMATCH(ra,rb,rc,rd,re,rw) \ { \ printf("match() called in line %d\n", __LINE__); \ - rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \ printf("to line %d\n", __LINE__); \ } #define RRETURN(ra) \ @@ -278,8 +300,8 @@ return ra; \ } #else -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \ - rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1) +#define RMATCH(ra,rb,rc,rd,re,rw) \ + rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1) #define RRETURN(ra) return ra #endif @@ -292,19 +314,22 @@ #define REGISTER -#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\ +#define RMATCH(ra,rb,rc,rd,re,rw)\ {\ - heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\ - if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ - frame->Xwhere = rw; \ + heapframe *newframe = frame->Xnextframe;\ + if (newframe == NULL)\ + {\ + newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ + if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ + newframe->Xnextframe = NULL;\ + frame->Xnextframe = newframe;\ + }\ + frame->Xwhere = rw;\ newframe->Xeptr = ra;\ newframe->Xecode = rb;\ newframe->Xmstart = mstart;\ - newframe->Xmarkptr = markptr;\ newframe->Xoffset_top = rc;\ - newframe->Xims = re;\ - newframe->Xeptrb = rf;\ - newframe->Xflags = rg;\ + newframe->Xeptrb = re;\ newframe->Xrdepth = frame->Xrdepth + 1;\ newframe->Xprevframe = frame;\ frame = newframe;\ @@ -318,7 +343,6 @@ {\ heapframe *oldframe = frame;\ frame = oldframe->Xprevframe;\ - (pcre_stack_free)(oldframe);\ if (frame != NULL)\ {\ rrc = ra;\ @@ -332,30 +356,28 @@ typedef struct heapframe { struct heapframe *Xprevframe; + struct heapframe *Xnextframe; /* Function arguments that may change */ - USPTR Xeptr; - const uschar *Xecode; - USPTR Xmstart; - USPTR Xmarkptr; + PCRE_PUCHAR Xeptr; + const pcre_uchar *Xecode; + PCRE_PUCHAR Xmstart; int Xoffset_top; - long int Xims; eptrblock *Xeptrb; - int Xflags; unsigned int Xrdepth; /* Function local variables */ - USPTR Xcallpat; -#ifdef SUPPORT_UTF8 - USPTR Xcharptr; -#endif - USPTR Xdata; - USPTR Xnext; - USPTR Xpp; - USPTR Xprev; - USPTR Xsaved_eptr; + PCRE_PUCHAR Xcallpat; +#ifdef SUPPORT_UTF + PCRE_PUCHAR Xcharptr; +#endif + PCRE_PUCHAR Xdata; + PCRE_PUCHAR Xnext; + PCRE_PUCHAR Xpp; + PCRE_PUCHAR Xprev; + PCRE_PUCHAR Xsaved_eptr; recursion_info Xnew_recursive; @@ -363,17 +385,12 @@ BOOL Xcondition; BOOL Xprev_is_word; - unsigned long int Xoriginal_ims; - #ifdef SUPPORT_UCP int Xprop_type; int Xprop_value; int Xprop_fail_result; - int Xprop_category; - int Xprop_chartype; - int Xprop_script; int Xoclength; - uschar Xocchars[8]; + pcre_uchar Xocchars[6]; #endif int Xcodelink; @@ -415,7 +432,7 @@ same response. */ /* These macros pack up tests that are used for partial matching, and which -appears several times in the code. We set the "hit end" flag if the pointer is +appear several times in the code. We set the "hit end" flag if the pointer is at the end of the subject and also past the start of the subject (i.e. something has been matched). For hard partial matching, we then return immediately. The second one is used when we already know we are past the end of @@ -426,19 +443,19 @@ eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ - if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \ + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } #define SCHECK_PARTIAL()\ if (md->partial != 0 && eptr > md->start_used_ptr) \ { \ md->hitend = TRUE; \ - if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \ + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \ } /* Performance note: It might be tempting to extract commonly used fields from -the md structure (e.g. utf8, end_subject) into individual variables to improve +the md structure (e.g. utf, end_subject) into individual variables to improve performance. Tests using gcc on a SPARC disproved this; in the first case, it made performance worse. @@ -447,16 +464,10 @@ ecode pointer to current position in compiled code mstart pointer to the current match start position (can be modified by encountering \K) - markptr pointer to the most recent MARK name, or NULL offset_top current top pointer md pointer to "static" info for the match - ims current /i, /m, and /s options eptrb pointer to chain of blocks containing eptr at start of brackets - for testing for empty matches - flags can contain - match_condassert - this is an assertion condition - match_cbegroup - this is the start of an unlimited repeat - group that can match an empty string rdepth the recursion depth Returns: MATCH_MATCH if matched ) these values are >= 0 @@ -467,9 +478,9 @@ */ static int -match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart, - const uschar *markptr, int offset_top, match_data *md, unsigned long int ims, - eptrblock *eptrb, int flags, unsigned int rdepth) +match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode, + PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb, + unsigned int rdepth) { /* These variables do not need to be preserved over recursion in this function, so they can be ordinary variables in all cases. Mark some of them with @@ -478,31 +489,29 @@ register int rrc; /* Returns from recursive calls */ register int i; /* Used for loops not involving calls to RMATCH() */ register unsigned int c; /* Character values not kept over RMATCH() calls */ -register BOOL utf8; /* Local copy of UTF-8 flag for speed */ +register BOOL utf; /* Local copy of UTF flag for speed */ BOOL minimize, possessive; /* Quantifier options */ +BOOL caseless; int condcode; /* When recursion is not being used, all "local" variables that have to be -preserved over calls to RMATCH() are part of a "frame" which is obtained from -heap storage. Set up the top-level frame here; others are obtained from the -heap whenever RMATCH() does a "recursion". See the macro definitions above. */ +preserved over calls to RMATCH() are part of a "frame". We set up the top-level +frame on the stack here; subsequent instantiations are obtained from the heap +whenever RMATCH() does a "recursion". See the macro definitions above. Putting +the top-level on the stack rather than malloc-ing them all gives a performance +boost in many cases where there is not much "recursion". */ #ifdef NO_RECURSE -heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe)); -if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY); -frame->Xprevframe = NULL; /* Marks the top level */ +heapframe *frame = (heapframe *)md->match_frames_base; /* Copy in the original argument variables */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xmstart = mstart; -frame->Xmarkptr = markptr; frame->Xoffset_top = offset_top; -frame->Xims = ims; frame->Xeptrb = eptrb; -frame->Xflags = flags; frame->Xrdepth = rdepth; /* This is where control jumps back to to effect "recursion" */ @@ -514,16 +523,13 @@ #define eptr frame->Xeptr #define ecode frame->Xecode #define mstart frame->Xmstart -#define markptr frame->Xmarkptr #define offset_top frame->Xoffset_top -#define ims frame->Xims #define eptrb frame->Xeptrb -#define flags frame->Xflags #define rdepth frame->Xrdepth /* Ditto for the local variables */ -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF #define charptr frame->Xcharptr #endif #define callpat frame->Xcallpat @@ -540,15 +546,10 @@ #define condition frame->Xcondition #define prev_is_word frame->Xprev_is_word -#define original_ims frame->Xoriginal_ims - #ifdef SUPPORT_UCP #define prop_type frame->Xprop_type #define prop_value frame->Xprop_value #define prop_fail_result frame->Xprop_fail_result -#define prop_category frame->Xprop_category -#define prop_chartype frame->Xprop_chartype -#define prop_script frame->Xprop_script #define oclength frame->Xoclength #define occhars frame->Xocchars #endif @@ -578,34 +579,36 @@ #define fi i #define fc c +/* Many of the following variables are used only in small blocks of the code. +My normal style of coding would have declared them within each of those blocks. +However, in order to accommodate the version of this code that uses an external +"stack" implemented on the heap, it is easier to declare them all here, so the +declarations can be cut out in a block. The only declarations within blocks +below are for variables that do not have to be preserved over a recursive call +to RMATCH(). */ + +#ifdef SUPPORT_UTF +const pcre_uchar *charptr; +#endif +const pcre_uchar *callpat; +const pcre_uchar *data; +const pcre_uchar *next; +PCRE_PUCHAR pp; +const pcre_uchar *prev; +PCRE_PUCHAR saved_eptr; + +recursion_info new_recursive; -#ifdef SUPPORT_UTF8 /* Many of these variables are used only */ -const uschar *charptr; /* in small blocks of the code. My normal */ -#endif /* style of coding would have declared */ -const uschar *callpat; /* them within each of those blocks. */ -const uschar *data; /* However, in order to accommodate the */ -const uschar *next; /* version of this code that uses an */ -USPTR pp; /* external "stack" implemented on the */ -const uschar *prev; /* heap, it is easier to declare them all */ -USPTR saved_eptr; /* here, so the declarations can be cut */ - /* out in a block. The only declarations */ -recursion_info new_recursive; /* within blocks below are for variables */ - /* that do not have to be preserved over */ -BOOL cur_is_word; /* a recursive call to RMATCH(). */ +BOOL cur_is_word; BOOL condition; BOOL prev_is_word; -unsigned long int original_ims; - #ifdef SUPPORT_UCP int prop_type; int prop_value; int prop_fail_result; -int prop_category; -int prop_chartype; -int prop_script; int oclength; -uschar occhars[8]; +pcre_uchar occhars[6]; #endif int codelink; @@ -621,8 +624,38 @@ int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; + +/* There is a special fudge for calling match() in a way that causes it to +measure the size of its basic stack frame when the stack is being used for +recursion. The second argument (ecode) being NULL triggers this behaviour. It +cannot normally ever be NULL. The return is the negated value of the frame +size. */ + +if (ecode == NULL) + { + if (rdepth == 0) + return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1); + else + { + int len = (char *)&rdepth - (char *)eptr; + return (len > 0)? -len : len; + } + } #endif /* NO_RECURSE */ +/* To save space on the stack and in the heap frame, I have doubled up on some +of the local variables that are used only in localised parts of the code, but +still need to be preserved over recursive calls of match(). These macros define +the alternative names that are used. */ + +#define allow_zero cur_is_word +#define cbegroup condition +#define code_offset codelink +#define condassert condition +#define matched_once prev_is_word +#define foc number +#define save_mark data + /* These statements are here to stop the compiler complaining about unitialized variables. */ @@ -647,10 +680,10 @@ complicated macro. It has to be used in one particular way. This shouldn't, however, impact performance when true recursion is being used. */ -#ifdef SUPPORT_UTF8 -utf8 = md->utf8; /* Local copy of the flag */ +#ifdef SUPPORT_UTF +utf = md->utf; /* Local copy of the flag */ #else -utf8 = FALSE; +utf = FALSE; #endif /* First check that we haven't called match() too many times, or that we @@ -659,22 +692,24 @@ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT); -original_ims = ims; /* Save for resetting on ')' */ - /* At the start of a group with an unlimited repeat that may match an empty -string, the match_cbegroup flag is set. When this is the case, add the current -subject pointer to the chain of such remembered pointers, to be checked when we -hit the closing ket, in order to break infinite loops that match no characters. -When match() is called in other circumstances, don't add to the chain. The -match_cbegroup flag must NOT be used with tail recursion, because the memory -block that is used is on the stack, so a new one may be required for each -match(). */ +string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is +done this way to save having to use another function argument, which would take +up space on the stack. See also MATCH_CONDASSERT below. + +When MATCH_CBEGROUP is set, add the current subject pointer to the chain of +such remembered pointers, to be checked when we hit the closing ket, in order +to break infinite loops that match no characters. When match() is called in +other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must +NOT be used with tail recursion, because the memory block that is used is on +the stack, so a new one may be required for each match(). */ -if ((flags & match_cbegroup) != 0) +if (md->match_function_type == MATCH_CBEGROUP) { newptrb.epb_saved_eptr = eptr; newptrb.epb_prev = eptrb; eptrb = &newptrb; + md->match_function_type = 0; } /* Now start processing the opcodes. */ @@ -687,9 +722,12 @@ switch(op) { case OP_MARK: - markptr = ecode + 2; - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM55); + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM55); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an argument, and we must check whether that argument matches this MARK's @@ -698,98 +736,192 @@ position and return MATCH_SKIP. Otherwise, pass back the return code unaltered. */ - if (rrc == MATCH_SKIP_ARG && - strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0) + else if (rrc == MATCH_SKIP_ARG && + STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0) { md->start_match_ptr = eptr; RRETURN(MATCH_SKIP); } - - if (md->mark == NULL) md->mark = markptr; RRETURN(rrc); case OP_FAIL: - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); /* COMMIT overrides PRUNE, SKIP, and THEN */ case OP_COMMIT: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM52); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM52); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && rrc != MATCH_THEN) RRETURN(rrc); - MRRETURN(MATCH_COMMIT); + RRETURN(MATCH_COMMIT); /* PRUNE overrides THEN */ case OP_PRUNE: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM51); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM51); if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); - MRRETURN(MATCH_PRUNE); + RRETURN(MATCH_PRUNE); case OP_PRUNE_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM56); + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM56); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); - md->mark = ecode + 2; RRETURN(MATCH_PRUNE); /* SKIP overrides PRUNE and THEN */ case OP_SKIP: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM53); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM53); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); md->start_match_ptr = eptr; /* Pass back current position */ - MRRETURN(MATCH_SKIP); + RRETURN(MATCH_SKIP); + + /* Note that, for Perl compatibility, SKIP with an argument does NOT set + nomatch_mark. There is a flag that disables this opcode when re-matching a + pattern that ended with a SKIP for which there was not a matching MARK. */ case OP_SKIP_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, - ims, eptrb, flags, RM57); + if (md->ignore_skip_arg) + { + ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; + break; + } + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, + eptrb, RM57); if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) RRETURN(rrc); /* Pass back the current skip name by overloading md->start_match_ptr and returning the special MATCH_SKIP_ARG return code. This will either be - caught by a matching MARK, or get to the top, where it is treated the same - as PRUNE. */ + caught by a matching MARK, or get to the top, where it causes a rematch + with the md->ignore_skip_arg flag set. */ md->start_match_ptr = ecode + 2; RRETURN(MATCH_SKIP_ARG); - /* For THEN (and THEN_ARG) we pass back the address of the bracket or - the alt that is at the start of the current branch. This makes it possible - to skip back past alternatives that precede the THEN within the current - branch. */ + /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that + the branch in which it occurs can be determined. Overload the start of + match pointer to do this. */ case OP_THEN: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM54); + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM54); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - md->start_match_ptr = ecode - GET(ecode, 1); - MRRETURN(MATCH_THEN); + md->start_match_ptr = ecode; + RRETURN(MATCH_THEN); case OP_THEN_ARG: - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE], - offset_top, md, ims, eptrb, flags, RM58); + md->nomatch_mark = ecode + 2; + md->mark = NULL; /* In case previously set by assertion */ + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, + md, eptrb, RM58); + if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && + md->mark == NULL) md->mark = ecode + 2; if (rrc != MATCH_NOMATCH) RRETURN(rrc); - md->start_match_ptr = ecode - GET(ecode, 1); - md->mark = ecode + LINK_SIZE + 2; + md->start_match_ptr = ecode; RRETURN(MATCH_THEN); - /* Handle a capturing bracket. If there is space in the offset vector, save - the current subject position in the working slot at the top of the vector. - We mustn't change the current values of the data slot, because they may be - set from a previous iteration of this group, and be referred to by a - reference inside the group. - - If the bracket fails to match, we need to restore this value and also the - values of the final offsets, in case they were set by a previous iteration - of the same bracket. + /* Handle an atomic group that does not contain any capturing parentheses. + This can be handled like an assertion. Prior to 8.13, all atomic groups + were handled this way. In 8.13, the code was changed as below for ONCE, so + that backups pass through the group and thereby reset captured values. + However, this uses a lot more stack, so in 8.20, atomic groups that do not + contain any captures generate OP_ONCE_NC, which can be handled in the old, + less stack intensive way. + + Check the alternative branches in turn - the matching won't pass the KET + for this kind of subpattern. If any one branch matches, we carry on as at + the end of a normal bracket, leaving the subject pointer, but resetting + the start-of-match value in case it was changed by \K. */ + + case OP_ONCE_NC: + prev = ecode; + saved_eptr = eptr; + save_mark = md->mark; + do + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); + if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ + { + mstart = md->start_match_ptr; + break; + } + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += GET(ecode,1); + md->mark = save_mark; + } + while (*ecode == OP_ALT); + + /* If hit the end of the group (which could be repeated), fail */ + + if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); + + /* Continue as from after the group, updating the offsets high water + mark, since extracts may have been taken. */ + + do ecode += GET(ecode, 1); while (*ecode == OP_ALT); + + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + + /* For a non-repeating ket, just continue at this level. This also + happens for a repeating ket if no characters were matched in the group. + This is the forcible breaking of infinite loops as implemented in Perl + 5.005. */ + + if (*ecode == OP_KET || eptr == saved_eptr) + { + ecode += 1+LINK_SIZE; + break; + } + + /* The repeating kets try the rest of the pattern or restart from the + preceding bracket, in the appropriate order. The second "call" of match() + uses tail recursion, to avoid using another stack frame. */ + + if (*ecode == OP_KETRMIN) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode = prev; + goto TAIL_RECURSE; + } + else /* OP_KETRMAX */ + { + RMATCH(eptr, prev, offset_top, md, eptrb, RM66); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode += 1 + LINK_SIZE; + goto TAIL_RECURSE; + } + /* Control never gets here */ + + /* Handle a capturing bracket, other than those that are possessive with an + unlimited repeat. If there is space in the offset vector, save the current + subject position in the working slot at the top of the vector. We mustn't + change the current values of the data slot, because they may be set from a + previous iteration of this group, and be referred to by a reference inside + the group. A failure to match might occur after the group has succeeded, + if something later on doesn't match. For this reason, we need to restore + the working value and also the values of the final offsets, in case they + were set by a previous iteration of the same bracket. If there isn't enough space in the offset vector, treat this as if it were a non-capturing bracket. Don't worry about setting the flag for the error @@ -813,32 +945,55 @@ save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; + save_mark = md->mark; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); md->offset_vector[md->offset_end - number] = (int)(eptr - md->start_subject); - flags = (op == OP_SCBRA)? match_cbegroup : 0; - do + for (;;) { - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, - ims, eptrb, flags, RM1); - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM1); + if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ + + /* If we backed up to a THEN, check whether it is within the current + branch by comparing the address of the THEN that is passed back with + the end of the branch. If it is within the current branch, and the + branch is one of two or more alternatives (it either starts or ends + with OP_ALT), we have reached the limit of THEN's action, so convert + the return code to NOMATCH, which will cause normal backtracking to + happen from now on. Otherwise, THEN is passed back to an outer + alternative. This implements Perl's treatment of parenthesized groups, + where a group not containing | does not affect the current alternative, + that is, (X) is NOT the same as (X|(*F)). */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + /* Anything other than NOMATCH is passed back. */ + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); + md->mark = save_mark; + if (*ecode != OP_ALT) break; } - while (*ecode == OP_ALT); DPRINTF(("bracket %d failed\n", number)); - md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; - if (rrc != MATCH_THEN) md->mark = markptr; - RRETURN(MATCH_NOMATCH); + /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */ + + RRETURN(rrc); } /* FALL THROUGH ... Insufficient room for saving captured contents. Treat @@ -852,69 +1007,266 @@ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ /* VVVVVVVVVVVVVVVVVVVVVVVVV */ - /* Non-capturing bracket. Loop for all the alternatives. When we get to the - final alternative within the brackets, we would return the result of a - recursive call to match() whatever happened. We can reduce stack usage by - turning this into a tail recursion, except in the case when match_cbegroup - is set.*/ + /* Non-capturing or atomic group, except for possessive with unlimited + repeat and ONCE group with no captures. Loop for all the alternatives. + + When we get to the final alternative within the brackets, we used to return + the result of a recursive call to match() whatever happened so it was + possible to reduce stack usage by turning this into a tail recursion, + except in the case of a possibly empty group. However, now that there is + the possiblity of (*THEN) occurring in the final alternative, this + optimization is no longer always possible. + + We can optimize if we know there are no (*THEN)s in the pattern; at present + this is the best that can be done. + + MATCH_ONCE is returned when the end of an atomic group is successfully + reached, but subsequent matching fails. It passes back up the tree (causing + captured values to be reset) until the original atomic group level is + reached. This is tested by comparing md->once_target with the start of the + group. At this point, the return is converted into MATCH_NOMATCH so that + previous backup points can be taken. */ + case OP_ONCE: case OP_BRA: case OP_SBRA: DPRINTF(("start non-capturing bracket\n")); - flags = (op >= OP_SBRA)? match_cbegroup : 0; + for (;;) { - if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */ + if (op >= OP_SBRA || op == OP_ONCE) + md->match_function_type = MATCH_CBEGROUP; + + /* If this is not a possibly empty group, and there are no (*THEN)s in + the pattern, and this is the final alternative, optimize as described + above. */ + + else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) + { + ecode += PRIV(OP_lengths)[*ecode]; + goto TAIL_RECURSE; + } + + /* In all other cases, we have to make another call to match(). */ + + save_mark = md->mark; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, + RM2); + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) { - if (flags == 0) /* Not a possibly empty group */ + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) + { + if (rrc == MATCH_ONCE) { - ecode += _pcre_OP_lengths[*ecode]; - DPRINTF(("bracket 0 tail recursion\n")); - goto TAIL_RECURSE; + const pcre_uchar *scode = ecode; + if (*scode != OP_ONCE) /* If not at start, find it */ + { + while (*scode == OP_ALT) scode += GET(scode, 1); + scode -= GET(scode, 1); + } + if (md->once_target == scode) rrc = MATCH_NOMATCH; } + RRETURN(rrc); + } + ecode += GET(ecode, 1); + md->mark = save_mark; + if (*ecode != OP_ALT) break; + } - /* Possibly empty group; can't use tail recursion. */ + RRETURN(MATCH_NOMATCH); - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, - eptrb, flags, RM48); - if (rrc == MATCH_NOMATCH) md->mark = markptr; - RRETURN(rrc); + /* Handle possessive capturing brackets with an unlimited repeat. We come + here from BRAZERO with allow_zero set TRUE. The offset_vector values are + handled similarly to the normal case above. However, the matching is + different. The end of these brackets will always be OP_KETRPOS, which + returns MATCH_KETRPOS without going further in the pattern. By this means + we can handle the group by iteration rather than recursion, thereby + reducing the amount of stack needed. */ + + case OP_CBRAPOS: + case OP_SCBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_CAPTURE: + number = GET2(ecode, 1+LINK_SIZE); + offset = number << 1; + +#ifdef PCRE_DEBUG + printf("start possessive bracket %d\n", number); + printf("subject="); + pchars(eptr, 16, TRUE, md); + printf("\n"); +#endif + + if (offset < md->offset_max) + { + matched_once = FALSE; + code_offset = (int)(ecode - md->start_code); + + save_offset1 = md->offset_vector[offset]; + save_offset2 = md->offset_vector[offset+1]; + save_offset3 = md->offset_vector[md->offset_end - number]; + save_capture_last = md->capture_last; + + DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); + + /* Each time round the loop, save the current subject position for use + when the group matches. For MATCH_MATCH, the group has matched, so we + restart it with a new subject starting position, remembering that we had + at least one match. For MATCH_NOMATCH, carry on with the alternatives, as + usual. If we haven't matched any alternatives in any iteration, check to + see if a previous iteration matched. If so, the group has matched; + continue from afterwards. Otherwise it has failed; restore the previous + capture values before returning NOMATCH. */ + + for (;;) + { + md->offset_vector[md->offset_end - number] = + (int)(eptr - md->start_subject); + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM63); + if (rrc == MATCH_KETRPOS) + { + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + ecode = md->start_code + code_offset; + save_capture_last = md->capture_last; + matched_once = TRUE; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->capture_last = save_capture_last; + ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; + } + + if (!matched_once) + { + md->offset_vector[offset] = save_offset1; + md->offset_vector[offset+1] = save_offset2; + md->offset_vector[md->offset_end - number] = save_offset3; } - /* For non-final alternatives, continue the loop for a NOMATCH result; - otherwise return. */ + if (allow_zero || matched_once) + { + ecode += 1 + LINK_SIZE; + break; + } - RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims, - eptrb, flags, RM2); - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + RRETURN(MATCH_NOMATCH); + } + + /* FALL THROUGH ... Insufficient room for saving captured contents. Treat + as a non-capturing bracket. */ + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + DPRINTF(("insufficient capture room: treat as non-capturing\n")); + + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + /* VVVVVVVVVVVVVVVVVVVVVVVVV */ + + /* Non-capturing possessive bracket with unlimited repeat. We come here + from BRAZERO with allow_zero = TRUE. The code is similar to the above, + without the capturing complication. It is written out separately for speed + and cleanliness. */ + + case OP_BRAPOS: + case OP_SBRAPOS: + allow_zero = FALSE; + + POSSESSIVE_NON_CAPTURE: + matched_once = FALSE; + code_offset = (int)(ecode - md->start_code); + + for (;;) + { + if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, + eptrb, RM48); + if (rrc == MATCH_KETRPOS) + { + offset_top = md->end_offset_top; + eptr = md->end_match_ptr; + ecode = md->start_code + code_offset; + matched_once = TRUE; + continue; + } + + /* See comment in the code for capturing groups above about handling + THEN. */ + + if (rrc == MATCH_THEN) + { + next = ecode + GET(ecode,1); + if (md->start_match_ptr < next && + (*ecode == OP_ALT || *next == OP_ALT)) + rrc = MATCH_NOMATCH; + } + + if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); + if (*ecode != OP_ALT) break; } + + if (matched_once || allow_zero) + { + ecode += 1 + LINK_SIZE; + break; + } + RRETURN(MATCH_NOMATCH); + /* Control never reaches here. */ /* Conditional group: compilation checked that there are no more than two branches. If the condition is false, skipping the first branch takes us past the end if there is only one branch, but that's OK because that is - exactly what going to the ket would do. As there is only one branch to be - obeyed, we can use tail recursion to avoid using another stack frame. */ + exactly what going to the ket would do. */ case OP_COND: case OP_SCOND: - codelink= GET(ecode, 1); + codelink = GET(ecode, 1); /* Because of the way auto-callout works during compile, a callout item is inserted between OP_COND and an assertion condition. */ if (ecode[LINK_SIZE+1] == OP_CALLOUT) { - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + PUBL(callout_block) cb; + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[LINK_SIZE+2]; cb.offset_vector = md->offset_vector; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; +#else + cb.subject = (PCRE_SPTR16)md->start_subject; +#endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); @@ -923,10 +1275,11 @@ cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH); + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } - ecode += _pcre_OP_lengths[OP_CALLOUT]; + ecode += PRIV(OP_lengths)[OP_CALLOUT]; } condcode = ecode[LINK_SIZE+1]; @@ -943,16 +1296,16 @@ else { int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ - condition = (recno == RREF_ANY || recno == md->recursive->group_num); + condition = (recno == RREF_ANY || recno == md->recursive->group_num); /* If the test is for recursion into a specific subpattern, and it is false, but the test was set up by name, scan the table to see if the name refers to any other numbers, and test them. The condition is true if any one is set. */ - if (!condition && condcode == OP_NRREF && recno != RREF_ANY) + if (!condition && condcode == OP_NRREF) { - uschar *slotA = md->name_table; + pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { if (GET2(slotA, 0) == recno) break; @@ -965,11 +1318,11 @@ if (i < md->name_count) { - uschar *slotB = slotA; + pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; @@ -985,7 +1338,7 @@ for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { condition = GET2(slotB, 0) == md->recursive->group_num; if (condition) break; @@ -998,7 +1351,7 @@ /* Chose branch according to the condition */ - ecode += condition? 3 : GET(ecode, 1); + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } } @@ -1015,7 +1368,7 @@ if (!condition && condcode == OP_NCREF) { int refno = offset >> 1; - uschar *slotA = md->name_table; + pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) { @@ -1029,11 +1382,11 @@ if (i < md->name_count) { - uschar *slotB = slotA; + pcre_uchar *slotB = slotA; while (slotB > md->name_table) { slotB -= md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && @@ -1051,7 +1404,7 @@ for (i++; i < md->name_count; i++) { slotB += md->name_entry_size; - if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) { offset = GET2(slotB, 0) << 1; condition = offset < offset_top && @@ -1066,7 +1419,7 @@ /* Chose branch according to the condition */ - ecode += condition? 3 : GET(ecode, 1); + ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); } else if (condcode == OP_DEF) /* DEFINE - always false */ @@ -1076,21 +1429,26 @@ } /* The condition is an assertion. Call match() to evaluate it - setting - the final argument match_condassert causes it to stop at the end of an - assertion. */ + md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of + an assertion. */ else { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, - match_condassert, RM3); + md->match_function_type = MATCH_CONDASSERT; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3); if (rrc == MATCH_MATCH) { + if (md->end_offset_top > offset_top) + offset_top = md->end_offset_top; /* Captures may have happened */ condition = TRUE; ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2); while (*ecode == OP_ALT) ecode += GET(ecode, 1); } - else if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) + + /* PCRE doesn't allow the effect of (*THEN) to escape beyond an + assertion; it is therefore treated as NOMATCH. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) { RRETURN(rrc); /* Need braces because of following else */ } @@ -1101,26 +1459,32 @@ } } - /* We are now at the branch that is to be obeyed. As there is only one, - we can use tail recursion to avoid using another stack frame, except when - match_cbegroup is required for an unlimited repeat of a possibly empty - group. If the second alternative doesn't exist, we can just plough on. */ + /* We are now at the branch that is to be obeyed. As there is only one, can + use tail recursion to avoid using another stack frame, except when there is + unlimited repeat of a possibly empty group. In the latter case, a recursive + call to match() is always required, unless the second alternative doesn't + exist, in which case we can just plough on. Note that, for compatibility + with Perl, the | in a conditional group is NOT treated as creating two + alternatives. If a THEN is encountered in the branch, it propagates out to + the enclosing alternative (unless nested in a deeper set of alternatives, + of course). */ if (condition || *ecode == OP_ALT) { - ecode += 1 + LINK_SIZE; - if (op == OP_SCOND) /* Possibly empty group */ + if (op != OP_SCOND) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49); - RRETURN(rrc); - } - else /* Group must match something */ - { - flags = 0; + ecode += 1 + LINK_SIZE; goto TAIL_RECURSE; } + + md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49); + RRETURN(rrc); } - else /* Condition false & no alternative */ + + /* Condition false & no alternative; continue after the group. */ + + else { ecode += 1 + LINK_SIZE; } @@ -1147,39 +1511,27 @@ md->offset_vector[offset+1] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } - ecode += 3; + ecode += 1 + IMM2_SIZE; break; - /* End of the pattern, either real or forced. If we are in a top-level - recursion, we should restore the offsets appropriately and continue from - after the call. */ + /* End of the pattern, either real or forced. */ - case OP_ACCEPT: case OP_END: - if (md->recursive != NULL && md->recursive->group_num == 0) - { - recursion_info *rec = md->recursive; - DPRINTF(("End of pattern in a (?0) recursion\n")); - md->recursive = rec->prevrec; - memmove(md->offset_vector, rec->offset_save, - rec->saved_max * sizeof(int)); - offset_top = rec->save_offset_top; - ims = original_ims; - ecode = rec->after_call; - break; - } + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: - /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is - set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of - the subject. In both cases, backtracking will then try other alternatives, - if any. */ - - if (eptr == mstart && - (md->notempty || - (md->notempty_atstart && - mstart == md->start_subject + md->start_offset))) - MRRETURN(MATCH_NOMATCH); + /* If we have matched an empty string, fail if not in an assertion and not + in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART + is set and we have matched at the start of the subject. In both cases, + backtracking will then try other alternatives, if any. */ + + if (eptr == mstart && op != OP_ASSERT_ACCEPT && + md->recursive == NULL && + (md->notempty || + (md->notempty_atstart && + mstart == md->start_subject + md->start_offset))) + RRETURN(MATCH_NOMATCH); /* Otherwise, we have a match. */ @@ -1188,47 +1540,60 @@ md->start_match_ptr = mstart; /* and the start (\K can modify) */ /* For some reason, the macros don't work properly if an expression is - given as the argument to MRRETURN when the heap is in use. */ + given as the argument to RRETURN when the heap is in use. */ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT; - MRRETURN(rrc); - - /* Change option settings */ - - case OP_OPT: - ims = ecode[1]; - ecode += 2; - DPRINTF(("ims set to %02lx\n", ims)); - break; + RRETURN(rrc); /* Assertion brackets. Check the alternative branches in turn - the matching won't pass the KET for an assertion. If any one branch matches, the assertion is true. Lookbehind assertions have an OP_REVERSE item at the start of each branch to move the current point backwards, so the code at - this level is identical to the lookahead case. */ + this level is identical to the lookahead case. When the assertion is part + of a condition, we want to return immediately afterwards. The caller of + this incarnation of the match() function will have set MATCH_CONDASSERT in + md->match_function type, and one of these opcodes will be the first opcode + that is processed. We use a local variable that is preserved over calls to + match() to remember this case. */ case OP_ASSERT: case OP_ASSERTBACK: + save_mark = md->mark; + if (md->match_function_type == MATCH_CONDASSERT) + { + condassert = TRUE; + md->match_function_type = 0; + } + else condassert = FALSE; + do { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, - RM4); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4); if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { mstart = md->start_match_ptr; /* In case \K reset it */ break; } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + md->mark = save_mark; + + /* A COMMIT failure must fail the entire assertion, without trying any + subsequent branches. */ + + if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH); + + /* PCRE does not allow THEN to escape beyond an assertion; it + is treated as NOMATCH. */ + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); - if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH); + + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ - if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + if (condassert) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ @@ -1244,24 +1609,34 @@ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: + save_mark = md->mark; + if (md->match_function_type == MATCH_CONDASSERT) + { + condassert = TRUE; + md->match_function_type = 0; + } + else condassert = FALSE; + do { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, - RM5); - if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); + md->mark = save_mark; + if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) { do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); + + /* PCRE does not allow THEN to escape beyond an assertion; it is treated + as NOMATCH. */ + + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); - if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); + if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */ ecode += 1 + LINK_SIZE; continue; @@ -1272,14 +1647,14 @@ back a number of characters, not bytes. */ case OP_REVERSE: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { i = GET(ecode, 1); while (i-- > 0) { eptr--; - if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr); } } @@ -1290,7 +1665,7 @@ { eptr -= GET(ecode, 1); - if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); } /* Save the earliest consulted character, then skip to next op code */ @@ -1304,13 +1679,17 @@ function is able to force a failure. */ case OP_CALLOUT: - if (pcre_callout != NULL) + if (PUBL(callout) != NULL) { - pcre_callout_block cb; - cb.version = 1; /* Version 1 of the callout block */ + PUBL(callout_block) cb; + cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; +#else + cb.subject = (PCRE_SPTR16)md->start_subject; +#endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); cb.current_position = (int)(eptr - md->start_subject); @@ -1319,7 +1698,8 @@ cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; - if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH); + cb.mark = md->nomatch_mark; + if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; @@ -1329,38 +1709,48 @@ offset data is the offset to the starting bracket from the start of the whole pattern. (This is so that it works from duplicated subpatterns.) - If there are any capturing brackets started but not finished, we have to - save their starting points and reinstate them after the recursion. However, - we don't know how many such there are (offset_top records the completed - total) so we just have to save all the potential data. There may be up to - 65535 such values, which is too large to put on the stack, but using malloc - for small numbers seems expensive. As a compromise, the stack is used when - there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc - is used. A problem is what to do if the malloc fails ... there is no way of - returning to the top level with an error. Save the top REC_STACK_SAVE_MAX - values on the stack, and accept that the rest may be wrong. + The state of the capturing groups is preserved over recursion, and + re-instated afterwards. We don't know how many are started and not yet + finished (offset_top records the completed total) so we just have to save + all the potential data. There may be up to 65535 such values, which is too + large to put on the stack, but using malloc for small numbers seems + expensive. As a compromise, the stack is used when there are no more than + REC_STACK_SAVE_MAX values to store; otherwise malloc is used. There are also other values that have to be saved. We use a chained sequence of blocks that actually live on the stack. Thanks to Robin Houston - for the original version of this logic. */ + for the original version of this logic. It has, however, been hacked around + a lot, so he is not to blame for the current way it works. */ case OP_RECURSE: { + recursion_info *ri; + int recno; + callpat = md->start_code + GET(ecode, 1); - new_recursive.group_num = (callpat == md->start_code)? 0 : + recno = (callpat == md->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); + /* Check for repeating a recursion without advancing the subject pointer. + This should catch convoluted mutual recursions. (Some simple cases are + caught at compile time.) */ + + for (ri = md->recursive; ri != NULL; ri = ri->prevrec) + if (recno == ri->group_num && eptr == ri->subject_position) + RRETURN(PCRE_ERROR_RECURSELOOP); + /* Add to "recursing stack" */ + new_recursive.group_num = recno; + new_recursive.subject_position = eptr; new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; - /* Find where to continue from afterwards */ + /* Where to continue from afterwards */ ecode += 1 + LINK_SIZE; - new_recursive.after_call = ecode; - /* Now save the offset data. */ + /* Now save the offset data */ new_recursive.saved_max = md->offset_end; if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) @@ -1368,43 +1758,54 @@ else { new_recursive.offset_save = - (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); + (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int)); if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); } - memcpy(new_recursive.offset_save, md->offset_vector, new_recursive.saved_max * sizeof(int)); - new_recursive.save_offset_top = offset_top; - /* OK, now we can do the recursion. For each top-level alternative we - restore the offset and recursion data. */ + /* OK, now we can do the recursion. After processing each alternative, + restore the offset data. If there were nested recursions, md->recursive + might be changed, so reset it before looping. */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); - flags = (*callpat >= OP_SBRA)? match_cbegroup : 0; + cbegroup = (*callpat >= OP_SBRA); do { - RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top, - md, ims, eptrb, flags, RM6); + if (cbegroup) md->match_function_type = MATCH_CBEGROUP; + RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, + md, eptrb, RM6); + memcpy(md->offset_vector, new_recursive.offset_save, + new_recursive.saved_max * sizeof(int)); + md->recursive = new_recursive.prevrec; if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) { DPRINTF(("Recursion matched\n")); - md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); - MRRETURN(MATCH_MATCH); + (PUBL(free))(new_recursive.offset_save); + + /* Set where we got to in the subject, and reset the start in case + it was changed by \K. This *is* propagated back out of a recursion, + for Perl compatibility. */ + + eptr = md->end_match_ptr; + mstart = md->start_match_ptr; + goto RECURSION_MATCHED; /* Exit loop; end processing */ } - else if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) + + /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it + is treated as NOMATCH. */ + + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN && + rrc != MATCH_COMMIT) { DPRINTF(("Recursion gave error %d\n", rrc)); if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); + (PUBL(free))(new_recursive.offset_save); RRETURN(rrc); } md->recursive = &new_recursive; - memcpy(md->offset_vector, new_recursive.offset_save, - new_recursive.saved_max * sizeof(int)); callpat += GET(callpat, 1); } while (*callpat == OP_ALT); @@ -1412,91 +1813,12 @@ DPRINTF(("Recursion didn't match\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) - (pcre_free)(new_recursive.offset_save); - MRRETURN(MATCH_NOMATCH); - } - /* Control never reaches here */ - - /* "Once" brackets are like assertion brackets except that after a match, - the point in the subject string is not moved back. Thus there can never be - a move back into the brackets. Friedl calls these "atomic" subpatterns. - Check the alternative branches in turn - the matching won't pass the KET - for this kind of subpattern. If any one branch matches, we carry on as at - the end of a normal bracket, leaving the subject pointer, but resetting - the start-of-match value in case it was changed by \K. */ - - case OP_ONCE: - prev = ecode; - saved_eptr = eptr; - - do - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7); - if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */ - { - mstart = md->start_match_ptr; - break; - } - if (rrc != MATCH_NOMATCH && - (rrc != MATCH_THEN || md->start_match_ptr != ecode)) - RRETURN(rrc); - ecode += GET(ecode,1); - } - while (*ecode == OP_ALT); - - /* If hit the end of the group (which could be repeated), fail */ - - if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); - - /* Continue as from after the assertion, updating the offsets high water - mark, since extracts may have been taken. */ - - do ecode += GET(ecode, 1); while (*ecode == OP_ALT); - - offset_top = md->end_offset_top; - eptr = md->end_match_ptr; - - /* For a non-repeating ket, just continue at this level. This also - happens for a repeating ket if no characters were matched in the group. - This is the forcible breaking of infinite loops as implemented in Perl - 5.005. If there is an options reset, it will get obeyed in the normal - course of events. */ - - if (*ecode == OP_KET || eptr == saved_eptr) - { - ecode += 1+LINK_SIZE; - break; - } - - /* The repeating kets try the rest of the pattern or restart from the - preceding bracket, in the appropriate order. The second "call" of match() - uses tail recursion, to avoid using another stack frame. We need to reset - any options that changed within the bracket before re-running it, so - check the next opcode. */ - - if (ecode[1+LINK_SIZE] == OP_OPT) - { - ims = (ims & ~PCRE_IMS) | ecode[4]; - DPRINTF(("ims set to %02lx at group repeat\n", ims)); + (PUBL(free))(new_recursive.offset_save); + RRETURN(MATCH_NOMATCH); } - if (*ecode == OP_KETRMIN) - { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode = prev; - flags = 0; - goto TAIL_RECURSE; - } - else /* OP_KETRMAX */ - { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode += 1 + LINK_SIZE; - flags = 0; - goto TAIL_RECURSE; - } - /* Control never gets here */ + RECURSION_MATCHED: + break; /* An alternation is the end of a branch; scan along to find the end of the bracketed group and go to there. */ @@ -1512,140 +1834,181 @@ optional ones preceded by BRAZERO or BRAMINZERO. */ case OP_BRAZERO: - { - next = ecode+1; - RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - do next += GET(next,1); while (*next == OP_ALT); - ecode = next + 1 + LINK_SIZE; - } + next = ecode + 1; + RMATCH(eptr, next, offset_top, md, eptrb, RM10); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + do next += GET(next, 1); while (*next == OP_ALT); + ecode = next + 1 + LINK_SIZE; break; case OP_BRAMINZERO: - { - next = ecode+1; - do next += GET(next, 1); while (*next == OP_ALT); - RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - ecode++; - } + next = ecode + 1; + do next += GET(next, 1); while (*next == OP_ALT); + RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + ecode++; break; case OP_SKIPZERO: - { - next = ecode+1; - do next += GET(next,1); while (*next == OP_ALT); - ecode = next + 1 + LINK_SIZE; - } + next = ecode+1; + do next += GET(next,1); while (*next == OP_ALT); + ecode = next + 1 + LINK_SIZE; break; + /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything + here; just jump to the group, with allow_zero set TRUE. */ + + case OP_BRAPOSZERO: + op = *(++ecode); + allow_zero = TRUE; + if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE; + goto POSSESSIVE_NON_CAPTURE; + /* End of a group, repeated or non-repeating. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: + case OP_KETRPOS: prev = ecode - GET(ecode, 1); /* If this was a group that remembered the subject start, in order to break infinite repeats of empty string matches, retrieve the subject start from the chain. Otherwise, set it NULL. */ - if (*prev >= OP_SBRA) + if (*prev >= OP_SBRA || *prev == OP_ONCE) { saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */ eptrb = eptrb->epb_prev; /* Backup to previous group */ } else saved_eptr = NULL; - /* If we are at the end of an assertion group or an atomic group, stop - matching and return MATCH_MATCH, but record the current high water mark for - use by positive assertions. We also need to record the match start in case - it was changed by \K. */ - - if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || - *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || - *prev == OP_ONCE) + /* If we are at the end of an assertion group or a non-capturing atomic + group, stop matching and return MATCH_MATCH, but record the current high + water mark for use by positive assertions. We also need to record the match + start in case it was changed by \K. */ + + if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) || + *prev == OP_ONCE_NC) { - md->end_match_ptr = eptr; /* For ONCE */ + md->end_match_ptr = eptr; /* For ONCE_NC */ md->end_offset_top = offset_top; md->start_match_ptr = mstart; - MRRETURN(MATCH_MATCH); + RRETURN(MATCH_MATCH); /* Sets md->mark */ } /* For capturing groups we have to check the group number back at the start and if necessary complete handling an extraction by setting the offsets and - bumping the high water mark. Note that whole-pattern recursion is coded as - a recurse into group 0, so it won't be picked up here. Instead, we catch it - when the OP_END is reached. Other recursion is handled here. */ + bumping the high water mark. Whole-pattern recursion is coded as a recurse + into group 0, so it won't be picked up here. Instead, we catch it when the + OP_END is reached. Other recursion is handled here. We just have to record + the current subject position and start match pointer and give a MATCH + return. */ - if (*prev == OP_CBRA || *prev == OP_SCBRA) + if (*prev == OP_CBRA || *prev == OP_SCBRA || + *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS) { number = GET2(prev, 1+LINK_SIZE); offset = number << 1; -#ifdef PCRE_DEBUG - printf("end bracket %d", number); - printf("\n"); -#endif +#ifdef PCRE_DEBUG + printf("end bracket %d", number); + printf("\n"); +#endif + + /* Handle a recursively called group. */ + + if (md->recursive != NULL && md->recursive->group_num == number) + { + md->end_match_ptr = eptr; + md->start_match_ptr = mstart; + RRETURN(MATCH_MATCH); + } + + /* Deal with capturing */ md->capture_last = number; if (offset >= md->offset_max) md->offset_overflow = TRUE; else { + /* If offset is greater than offset_top, it means that we are + "skipping" a capturing group, and that group's offsets must be marked + unset. In earlier versions of PCRE, all the offsets were unset at the + start of matching, but this doesn't work because atomic groups and + assertions can cause a value to be set that should later be unset. + Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as + part of the atomic group, but this is not on the final matching path, + so must be unset when 2 is set. (If there is no group 2, there is no + problem, because offset_top will then be 2, indicating no capture.) */ + + if (offset > offset_top) + { + register int *iptr = md->offset_vector + offset_top; + register int *iend = md->offset_vector + offset; + while (iptr < iend) *iptr++ = -1; + } + + /* Now make the extraction */ + md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; md->offset_vector[offset+1] = (int)(eptr - md->start_subject); if (offset_top <= offset) offset_top = offset + 2; } + } - /* Handle a recursively called group. Restore the offsets - appropriately and continue from after the call. */ + /* For an ordinary non-repeating ket, just continue at this level. This + also happens for a repeating ket if no characters were matched in the + group. This is the forcible breaking of infinite loops as implemented in + Perl 5.005. For a non-repeating atomic group that includes captures, + establish a backup point by processing the rest of the pattern at a lower + level. If this results in a NOMATCH return, pass MATCH_ONCE back to the + original OP_ONCE level, thereby bypassing intermediate backup points, but + resetting any captures that happened along the way. */ - if (md->recursive != NULL && md->recursive->group_num == number) + if (*ecode == OP_KET || eptr == saved_eptr) + { + if (*prev == OP_ONCE) { - recursion_info *rec = md->recursive; - DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); - md->recursive = rec->prevrec; - memcpy(md->offset_vector, rec->offset_save, - rec->saved_max * sizeof(int)); - offset_top = rec->save_offset_top; - ecode = rec->after_call; - ims = original_ims; - break; + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); } + ecode += 1 + LINK_SIZE; /* Carry on at this level */ + break; } - /* For both capturing and non-capturing groups, reset the value of the ims - flags, in case they got changed during the group. */ - - ims = original_ims; - DPRINTF(("ims reset to %02lx\n", ims)); - - /* For a non-repeating ket, just continue at this level. This also - happens for a repeating ket if no characters were matched in the group. - This is the forcible breaking of infinite loops as implemented in Perl - 5.005. If there is an options reset, it will get obeyed in the normal - course of events. */ + /* OP_KETRPOS is a possessive repeating ket. Remember the current position, + and return the MATCH_KETRPOS. This makes it possible to do the repeats one + at a time from the outer level, thus saving stack. */ - if (*ecode == OP_KET || eptr == saved_eptr) + if (*ecode == OP_KETRPOS) { - ecode += 1 + LINK_SIZE; - break; + md->end_match_ptr = eptr; + md->end_offset_top = offset_top; + RRETURN(MATCH_KETRPOS); } - /* The repeating kets try the rest of the pattern or restart from the - preceding bracket, in the appropriate order. In the second case, we can use - tail recursion to avoid using another stack frame, unless we have an - unlimited repeat of a group that can match an empty string. */ - - flags = (*prev >= OP_SBRA)? match_cbegroup : 0; + /* The normal repeating kets try the rest of the pattern or restart from + the preceding bracket, in the appropriate order. In the second case, we can + use tail recursion to avoid using another stack frame, unless we have an + an atomic group or an unlimited repeat of a group that can match an empty + string. */ if (*ecode == OP_KETRMIN) { - RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12); + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (flags != 0) /* Could match an empty string */ + if (*prev == OP_ONCE) + { + RMATCH(eptr, prev, offset_top, md, eptrb, RM8); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */ + RRETURN(MATCH_ONCE); + } + if (*prev >= OP_SBRA) /* Could match an empty string */ { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50); + RMATCH(eptr, prev, offset_top, md, eptrb, RM50); RRETURN(rrc); } ecode = prev; @@ -1653,39 +2016,47 @@ } else /* OP_KETRMAX */ { - RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13); + RMATCH(eptr, prev, offset_top, md, eptrb, RM13); + if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (*prev == OP_ONCE) + { + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + md->once_target = prev; + RRETURN(MATCH_ONCE); + } ecode += 1 + LINK_SIZE; - flags = 0; goto TAIL_RECURSE; } /* Control never gets here */ - /* Start of subject unless notbol, or after internal newline if multiline */ + /* Not multiline mode: start of subject assertion, unless notbol. */ case OP_CIRC: - if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH); - if ((ims & PCRE_MULTILINE) != 0) - { - if (eptr != md->start_subject && - (eptr == md->end_subject || !WAS_NEWLINE(eptr))) - MRRETURN(MATCH_NOMATCH); - ecode++; - break; - } - /* ... else fall through */ + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); /* Start of subject assertion */ case OP_SOD: - if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); + ecode++; + break; + + /* Multiline mode: start of subject unless notbol, or after any newline. */ + + case OP_CIRCM: + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject && + (eptr == md->end_subject || !WAS_NEWLINE(eptr))) + RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: - if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH); + if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1696,34 +2067,47 @@ ecode++; break; - /* Assert before internal newline if multiline, or before a terminating - newline unless endonly is set, else end of subject unless noteol is set. */ + /* Multiline mode: assert before any newline, or before end of subject + unless noteol is set. */ - case OP_DOLL: - if ((ims & PCRE_MULTILINE) != 0) + case OP_DOLLM: + if (eptr < md->end_subject) { - if (eptr < md->end_subject) - { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); } - else + if (!IS_NEWLINE(eptr)) { - if (md->noteol) MRRETURN(MATCH_NOMATCH); - SCHECK_PARTIAL(); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); } - ecode++; - break; } - else /* Not multiline */ + else { - if (md->noteol) MRRETURN(MATCH_NOMATCH); - if (!md->endonly) goto ASSERT_NL_OR_EOS; + if (md->noteol) RRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); } + ecode++; + break; + + /* Not multiline mode: assert before a terminating newline or before end of + subject unless noteol is set. */ + + case OP_DOLL: + if (md->noteol) RRETURN(MATCH_NOMATCH); + if (!md->endonly) goto ASSERT_NL_OR_EOS; /* ... else fall through for endonly */ /* End of subject assertion (\z) */ case OP_EOD: - if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH); + if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); SCHECK_PARTIAL(); ecode++; break; @@ -1734,7 +2118,18 @@ ASSERT_NL_OR_EOS: if (eptr < md->end_subject && (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) - MRRETURN(MATCH_NOMATCH); + { + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + RRETURN(MATCH_NOMATCH); + } /* Either at end of string or \n before end. */ @@ -1753,15 +2148,15 @@ be "non-word" characters. Remember the earliest consulted character for partial matching. */ -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { /* Get status of previous character */ if (eptr == md->start_subject) prev_is_word = FALSE; else { - USPTR lastptr = eptr - 1; - while((*lastptr & 0xc0) == 0x80) lastptr--; + PCRE_PUCHAR lastptr = eptr - 1; + BACKCHAR(lastptr); if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; GETCHAR(c, lastptr); #ifdef SUPPORT_UCP @@ -1826,7 +2221,8 @@ } else #endif - prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0); + prev_is_word = MAX_255(eptr[-1]) + && ((md->ctypes[eptr[-1]] & ctype_word) != 0); } /* Get status of next character */ @@ -1849,30 +2245,47 @@ } else #endif - cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0); + cur_is_word = MAX_255(*eptr) + && ((md->ctypes[*eptr] & ctype_word) != 0); } /* Now see if the situation is what we want */ if ((*ecode++ == OP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; - /* Match a single character type; inline for speed */ + /* Match any single character type except newline; have to take care with + CRLF newlines and partial matching. */ case OP_ANY: - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + /* Fall through */ + /* Match any single character whatsoever. */ + case OP_ALLANY: - if (eptr++ >= md->end_subject) - { + if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + eptr++; +#ifdef SUPPORT_UTF + if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); +#endif ecode++; break; @@ -1880,11 +2293,12 @@ any byte, even newline, independent of the setting of PCRE_DOTALL. */ case OP_ANYBYTE: - if (eptr++ >= md->end_subject) - { + if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ + { /* not be updated before SCHECK_PARTIAL. */ SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } + eptr++; ecode++; break; @@ -1892,16 +2306,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_digit) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1909,16 +2323,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_digit) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1926,16 +2340,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_space) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1943,16 +2357,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_space) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1960,16 +2374,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) c < 256 && #endif (md->ctypes[c] & ctype_word) != 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1977,16 +2391,16 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); if ( -#ifdef SUPPORT_UTF8 - c >= 256 || +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + c > 255 || #endif (md->ctypes[c] & ctype_word) == 0 ) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); ecode++; break; @@ -1994,14 +2408,19 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: - if (eptr < md->end_subject && *eptr == 0x0a) eptr++; + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + } + else if (*eptr == 0x0a) eptr++; break; case 0x000a: @@ -2012,7 +2431,7 @@ case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } ecode++; @@ -2022,7 +2441,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2047,7 +2466,7 @@ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2056,12 +2475,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -2090,7 +2509,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) @@ -2103,7 +2522,7 @@ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2112,12 +2531,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -2139,7 +2558,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); { @@ -2148,59 +2567,59 @@ switch(ecode[1]) { case PT_ANY: - if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH); + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH); break; case PT_LAMP: if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || prop->chartype == ucp_Lt) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_GC: - if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) + RRETURN(MATCH_NOMATCH); break; case PT_PC: if ((ecode[2] != prop->chartype) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_SC: if ((ecode[2] != prop->script) == (op == OP_PROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; /* These are specials */ case PT_ALNUM: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) + RRETURN(MATCH_NOMATCH); break; case PT_SPACE: /* Perl space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_PXSPACE: /* POSIX space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case PT_WORD: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; /* This should never occur */ @@ -2220,24 +2639,18 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) { - int category = UCD_CATEGORY(c); - if (category == ucp_M) MRRETURN(MATCH_NOMATCH); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf8) c = *eptr; else - { - GETCHARLEN(c, eptr, len); - } - category = UCD_CATEGORY(c); - if (category != ucp_M) break; - eptr += len; - } + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } + CHECK_PARTIAL(); ecode++; break; #endif @@ -2252,129 +2665,147 @@ loops). */ case OP_REF: - { - offset = GET2(ecode, 1) << 1; /* Doubled ref number */ - ecode += 3; + case OP_REFI: + caseless = op == OP_REFI; + offset = GET2(ecode, 1) << 1; /* Doubled ref number */ + ecode += 1 + IMM2_SIZE; - /* If the reference is unset, there are two possibilities: + /* If the reference is unset, there are two possibilities: - (a) In the default, Perl-compatible state, set the length to be longer - than the amount of subject left; this ensures that every attempt at a - match fails. We can't just fail here, because of the possibility of - quantifiers with zero minima. + (a) In the default, Perl-compatible state, set the length negative; + this ensures that every attempt at a match fails. We can't just fail + here, because of the possibility of quantifiers with zero minima. - (b) If the JavaScript compatibility flag is set, set the length to zero - so that the back reference matches an empty string. + (b) If the JavaScript compatibility flag is set, set the length to zero + so that the back reference matches an empty string. - Otherwise, set the length to the length of what was matched by the - referenced subpattern. */ + Otherwise, set the length to the length of what was matched by the + referenced subpattern. */ - if (offset >= offset_top || md->offset_vector[offset] < 0) - length = (md->jscript_compat)? 0 : (int)(md->end_subject - eptr + 1); - else - length = md->offset_vector[offset+1] - md->offset_vector[offset]; + if (offset >= offset_top || md->offset_vector[offset] < 0) + length = (md->jscript_compat)? 0 : -1; + else + length = md->offset_vector[offset+1] - md->offset_vector[offset]; - /* Set up for repetition, or handle the non-repeated case */ + /* Set up for repetition, or handle the non-repeated case */ - switch (*ecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - c = *ecode++ - OP_CRSTAR; - minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ - max = rep_max[c]; /* zero for max => infinity */ - if (max == 0) max = INT_MAX; - break; + switch (*ecode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + c = *ecode++ - OP_CRSTAR; + minimize = (c & 1) != 0; + min = rep_min[c]; /* Pick up values from tables; */ + max = rep_max[c]; /* zero for max => infinity */ + if (max == 0) max = INT_MAX; + break; - case OP_CRRANGE: - case OP_CRMINRANGE: - minimize = (*ecode == OP_CRMINRANGE); - min = GET2(ecode, 1); - max = GET2(ecode, 3); - if (max == 0) max = INT_MAX; - ecode += 5; - break; + case OP_CRRANGE: + case OP_CRMINRANGE: + minimize = (*ecode == OP_CRMINRANGE); + min = GET2(ecode, 1); + max = GET2(ecode, 1 + IMM2_SIZE); + if (max == 0) max = INT_MAX; + ecode += 1 + 2 * IMM2_SIZE; + break; - default: /* No repeat follows */ - if (!match_ref(offset, eptr, length, md, ims)) - { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); - } - eptr += length; - continue; /* With the main loop */ + default: /* No repeat follows */ + if ((length = match_ref(offset, eptr, length, md, caseless)) < 0) + { + if (length == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); } + eptr += length; + continue; /* With the main loop */ + } - /* If the length of the reference is zero, just continue with the - main loop. */ + /* Handle repeated back references. If the length of the reference is + zero, just continue with the main loop. If the length is negative, it + means the reference is unset in non-Java-compatible mode. If the minimum is + zero, we can continue at the same level without recursion. For any other + minimum, carrying on will result in NOMATCH. */ - if (length == 0) continue; + if (length == 0) continue; + if (length < 0 && min == 0) continue; - /* First, ensure the minimum number of matches are present. We get back - the length of the reference string explicitly rather than passing the - address of eptr, so that eptr can be a register variable. */ + /* First, ensure the minimum number of matches are present. We get back + the length of the reference string explicitly rather than passing the + address of eptr, so that eptr can be a register variable. */ - for (i = 1; i <= min; i++) + for (i = 1; i <= min; i++) + { + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { - if (!match_ref(offset, eptr, length, md, ims)) - { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); - } - eptr += length; + if (slength == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); } + eptr += slength; + } - /* If min = max, continue at the same level without recursion. - They are not both allowed to be zero. */ + /* If min = max, continue at the same level without recursion. + They are not both allowed to be zero. */ - if (min == max) continue; + if (min == max) continue; - /* If minimizing, keep trying and advancing the pointer */ + /* If minimizing, keep trying and advancing the pointer */ - if (minimize) + if (minimize) + { + for (fi = min;; fi++) { - for (fi = min;; fi++) + int slength; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM14); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (fi >= max) RRETURN(MATCH_NOMATCH); + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); - if (!match_ref(offset, eptr, length, md, ims)) - { - CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); - } - eptr += length; + if (slength == -2) eptr = md->end_subject; /* Partial match */ + CHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); } - /* Control never gets here */ + eptr += slength; } + /* Control never gets here */ + } - /* If maximizing, find the longest string and work backwards */ + /* If maximizing, find the longest string and work backwards */ - else + else + { + pp = eptr; + for (i = min; i < max; i++) { - pp = eptr; - for (i = min; i < max; i++) + int slength; + if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) { - if (!match_ref(offset, eptr, length, md, ims)) + /* Can't use CHECK_PARTIAL because we don't want to update eptr in + the soft partial matching case. */ + + if (slength == -2 && md->partial != 0 && + md->end_subject > md->start_used_ptr) { - CHECK_PARTIAL(); - break; + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - eptr += length; - } - while (eptr >= pp) - { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - eptr -= length; + break; } - MRRETURN(MATCH_NOMATCH); + eptr += slength; + } + + while (eptr >= pp) + { + RMATCH(eptr, ecode, offset_top, md, eptrb, RM15); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr -= length; } + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -2392,8 +2823,11 @@ case OP_NCLASS: case OP_CLASS: { + /* The data variable is saved across frames, so the byte map needs to + be stored there. */ +#define BYTE_MAP ((pcre_uint8 *)data) data = ecode + 1; /* Save for matching */ - ecode += 33; /* Advance past the item */ + ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */ switch (*ecode) { @@ -2414,9 +2848,9 @@ case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); - max = GET2(ecode, 3); + max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; - ecode += 5; + ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ @@ -2426,41 +2860,45 @@ /* First, ensure the minimum number of matches are present. */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { - if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH); + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - { - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } c = *eptr++; - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } @@ -2474,47 +2912,51 @@ if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM16); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c > 255) { - if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH); + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - { - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM17); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } c = *eptr++; - if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH); +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2526,9 +2968,8 @@ { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (i = min; i < max; i++) { @@ -2544,14 +2985,12 @@ if (op == OP_CLASS) break; } else - { - if ((data[c/8] & (1 << (c&7))) == 0) break; - } + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr += len; } for (;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM18); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -2559,7 +2998,7 @@ } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -2569,19 +3008,27 @@ break; } c = *eptr; - if ((data[c/8] & (1 << (c&7))) == 0) break; +#ifndef COMPILE_PCRE8 + if (c > 255) + { + if (op == OP_CLASS) break; + } + else +#endif + if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; eptr++; } while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM19); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } +#undef BYTE_MAP } /* Control never gets here */ @@ -2590,7 +3037,7 @@ when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 mode, because Unicode properties are supported in non-UTF-8 mode. */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: { data = ecode + 1 + LINK_SIZE; /* Save for matching */ @@ -2615,9 +3062,9 @@ case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); - max = GET2(ecode, 3); + max = GET2(ecode, 1 + IMM2_SIZE); if (max == 0) max = INT_MAX; - ecode += 5; + ecode += 1 + 2 * IMM2_SIZE; break; default: /* No repeat follows */ @@ -2632,10 +3079,10 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the @@ -2650,16 +3097,16 @@ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -2677,18 +3124,24 @@ SCHECK_PARTIAL(); break; } +#ifdef SUPPORT_UTF GETCHARLENTEST(c, eptr, len); - if (!_pcre_xclass(c, data)) break; +#else + c = *eptr; +#endif + if (!PRIV(xclass)(c, data, utf)) break; eptr += len; } for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ - if (utf8) BACKCHAR(eptr); +#ifdef SUPPORT_UTF + if (utf) BACKCHAR(eptr); +#endif } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -2698,8 +3151,8 @@ /* Match a single character, casefully */ case OP_CHAR: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { length = 1; ecode++; @@ -2707,50 +3160,57 @@ if (length > md->end_subject - eptr) { CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH); + while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif - - /* Non-UTF-8 mode */ + /* Not UTF mode */ { if (md->end_subject - eptr < 1) { SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH); + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; - /* Match a single character, caselessly */ + /* Match a single character, caselessly. If we are at the end of the + subject, give up immediately. */ + + case OP_CHARI: + if (eptr >= md->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } - case OP_CHARNC: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); - if (length > md->end_subject - eptr) - { - CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); - } - /* If the pattern character's value is < 128, we have only one byte, and - can use the fast lookup table. */ + we know that its other case must also be one byte long, so we can use the + fast lookup table. We know that there is at least one byte left in the + subject. */ if (fc < 128) { - if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (md->lcc[fc] + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + ecode++; + eptr++; } - /* Otherwise we must pick up the subject character */ + /* Otherwise we must pick up the subject character. Note that we cannot + use the value of "length" to check for sufficient bytes left, because the + other case of the character may have more or fewer bytes. */ else { @@ -2766,21 +3226,18 @@ #ifdef SUPPORT_UCP if (dc != UCD_OTHERCASE(fc)) #endif - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } } else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ - /* Non-UTF-8 mode */ + /* Not UTF mode */ { - if (md->end_subject - eptr < 1) - { - SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */ - MRRETURN(MATCH_NOMATCH); - } - if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (TABLE_GET(ecode[1], md->lcc, ecode[1]) + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); + eptr++; ecode += 2; } break; @@ -2788,23 +3245,28 @@ /* Match a single character repeatedly. */ case OP_EXACT: + case OP_EXACTI: min = max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSUPTO: + case OP_POSUPTOI: possessive = TRUE; /* Fall through */ case OP_UPTO: + case OP_UPTOI: case OP_MINUPTO: + case OP_MINUPTOI: min = 0; max = GET2(ecode, 1); - minimize = *ecode == OP_MINUPTO; - ecode += 3; + minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; + ecode += 1 + IMM2_SIZE; goto REPEATCHAR; case OP_POSSTAR: + case OP_POSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -2812,6 +3274,7 @@ goto REPEATCHAR; case OP_POSPLUS: + case OP_POSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -2819,6 +3282,7 @@ goto REPEATCHAR; case OP_POSQUERY: + case OP_POSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -2826,14 +3290,19 @@ goto REPEATCHAR; case OP_STAR: + case OP_STARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_QUERY: + case OP_QUERYI: case OP_MINQUERY: - c = *ecode++ - OP_STAR; + case OP_MINQUERYI: + c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI); minimize = (c & 1) != 0; - min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; @@ -2841,8 +3310,8 @@ /* Common code for all repeated single-character matches. */ REPEATCHAR: -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { length = 1; charptr = ecode; @@ -2856,25 +3325,25 @@ { #ifdef SUPPORT_UCP unsigned int othercase; - if ((ims & PCRE_CASELESS) != 0 && + if (op >= OP_STARI && /* Caseless */ (othercase = UCD_OTHERCASE(fc)) != fc) - oclength = _pcre_ord2utf8(othercase, occhars); + oclength = PRIV(ord2utf)(othercase, occhars); else oclength = 0; #endif /* SUPPORT_UCP */ for (i = 1; i <= min; i++) { if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } @@ -2884,20 +3353,20 @@ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM22); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { CHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -2909,11 +3378,11 @@ for (i = min; i < max; i++) { if (eptr <= md->end_subject - length && - memcmp(eptr, charptr, length) == 0) eptr += length; + memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; #ifdef SUPPORT_UCP else if (oclength > 0 && eptr <= md->end_subject - oclength && - memcmp(eptr, occhars, oclength) == 0) eptr += oclength; + memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; #endif /* SUPPORT_UCP */ else { @@ -2926,9 +3395,9 @@ for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM23); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (eptr == pp) { MRRETURN(MATCH_NOMATCH); } + if (eptr == pp) { RRETURN(MATCH_NOMATCH); } #ifdef SUPPORT_UCP eptr--; BACKCHAR(eptr); @@ -2945,14 +3414,12 @@ value of fc will always be < 128. */ } else -#endif /* SUPPORT_UTF8 */ - - /* When not in UTF-8 mode, load a single-byte character. */ +#endif /* SUPPORT_UTF */ + /* When not in UTF-8 mode, load a single-byte character. */ + fc = *ecode++; - fc = *ecode++; - - /* The value of fc at this point is always less than 256, though we may or - may not be in UTF-8 mode. The code is duplicated for the caseless and + /* The value of fc at this point is always one character, though we may + or may not be in UTF mode. The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if @@ -2961,34 +3428,52 @@ maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, - max, eptr)); + max, (char *)eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_STARI) /* Caseless */ { - fc = md->lcc[fc]; +#ifdef COMPILE_PCRE8 + /* fc must be < 128 if UTF is enabled. */ + foc = md->fcc[fc]; +#else +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); +#else + if (utf && fc > 127) + foc = fc; +#endif /* SUPPORT_UCP */ + else +#endif /* SUPPORT_UTF */ + foc = TABLE_GET(fc, md->fcc, fc); +#endif /* COMPILE_PCRE8 */ + for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } /* Control never gets here */ } @@ -3002,7 +3487,7 @@ SCHECK_PARTIAL(); break; } - if (fc != md->lcc[*eptr]) break; + if (fc != *eptr && foc != *eptr) break; eptr++; } @@ -3010,11 +3495,11 @@ while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM25); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3028,9 +3513,9 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; @@ -3039,15 +3524,15 @@ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM26); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc != *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3068,11 +3553,11 @@ while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM27); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3081,24 +3566,47 @@ checking can be multibyte. */ case OP_NOT: + case OP_NOTI: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - ecode++; - GETCHARINCTEST(c, eptr); - if ((ims & PCRE_CASELESS) != 0) +#ifdef SUPPORT_UTF + if (utf) { -#ifdef SUPPORT_UTF8 - if (c < 256) -#endif - c = md->lcc[c]; - if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH); + register unsigned int ch, och; + + ecode++; + GETCHARINC(ch, ecode); + GETCHARINC(c, eptr); + + if (op == OP_NOT) + { + if (ch == c) RRETURN(MATCH_NOMATCH); + } + else + { +#ifdef SUPPORT_UCP + if (ch > 127) + och = UCD_OTHERCASE(ch); +#else + if (ch > 127) + och = ch; +#endif /* SUPPORT_UCP */ + else + och = TABLE_GET(ch, md->fcc, ch); + if (ch == c || och == c) RRETURN(MATCH_NOMATCH); + } } else +#endif { - if (*ecode++ == c) MRRETURN(MATCH_NOMATCH); + register unsigned int ch = ecode[1]; + c = *eptr++; + if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) + RRETURN(MATCH_NOMATCH); + ecode += 2; } break; @@ -3110,19 +3618,23 @@ about... */ case OP_NOTEXACT: + case OP_NOTEXACTI: min = max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: min = 0; max = GET2(ecode, 1); - minimize = *ecode == OP_NOTMINUPTO; - ecode += 3; + minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: possessive = TRUE; min = 0; max = INT_MAX; @@ -3130,6 +3642,7 @@ goto REPEATNOTCHAR; case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: possessive = TRUE; min = 1; max = INT_MAX; @@ -3137,6 +3650,7 @@ goto REPEATNOTCHAR; case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: possessive = TRUE; min = 0; max = 1; @@ -3144,19 +3658,26 @@ goto REPEATNOTCHAR; case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: possessive = TRUE; min = 0; max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATNOTCHAR; case OP_NOTSTAR: + case OP_NOTSTARI: case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_NOTMINQUERY: - c = *ecode++ - OP_NOTSTAR; + case OP_NOTMINQUERYI: + c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR); minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ @@ -3165,7 +3686,7 @@ /* Common code for all repeated single-byte matches. */ REPEATNOTCHAR: - fc = *ecode++; + GETCHARINCTEST(fc, ecode); /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the @@ -3176,15 +3697,24 @@ characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, - max, eptr)); + max, (char *)eptr)); - if ((ims & PCRE_CASELESS) != 0) + if (op >= OP_NOTSTARI) /* Caseless */ { - fc = md->lcc[fc]; +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + if (utf && fc > 127) + foc = UCD_OTHERCASE(fc); +#else + if (utf && fc > 127) + foc = fc; +#endif /* SUPPORT_UCP */ + else +#endif /* SUPPORT_UTF */ + foc = TABLE_GET(fc, md->fcc, fc); -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = 1; i <= min; i++) @@ -3192,26 +3722,25 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (d < 256) d = md->lcc[d]; - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif - - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } } @@ -3219,41 +3748,40 @@ if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM28); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (d < 256) d = md->lcc[d]; - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM29); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); + eptr++; } } /* Control never gets here */ @@ -3265,9 +3793,8 @@ { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = min; i < max; i++) @@ -3279,14 +3806,13 @@ break; } GETCHARLEN(d, eptr, len); - if (d < 256) d = md->lcc[d]; - if (fc == d) break; + if (fc == d || (unsigned int)foc == d) break; eptr += len; } - if (possessive) continue; - for(;;) + if (possessive) continue; + for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -3294,7 +3820,7 @@ } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -3303,19 +3829,19 @@ SCHECK_PARTIAL(); break; } - if (fc == md->lcc[*eptr]) break; + if (fc == *eptr || foc == *eptr) break; eptr++; } if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM31); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3324,9 +3850,8 @@ else { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = 1; i <= min; i++) @@ -3334,24 +3859,24 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } @@ -3359,40 +3884,39 @@ if (minimize) { -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM32); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(d, eptr); - if (fc == d) MRRETURN(MATCH_NOMATCH); + if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM33); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (fc == *eptr++) MRRETURN(MATCH_NOMATCH); + if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3404,9 +3928,8 @@ { pp = eptr; -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { register unsigned int d; for (i = min; i < max; i++) @@ -3424,7 +3947,7 @@ if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM34); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); @@ -3432,7 +3955,7 @@ } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (i = min; i < max; i++) { @@ -3447,13 +3970,13 @@ if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM35); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -3465,7 +3988,7 @@ case OP_TYPEEXACT: min = max = GET2(ecode, 1); minimize = TRUE; - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEUPTO: @@ -3473,7 +3996,7 @@ min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_TYPEMINUPTO; - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPEPOSSTAR: @@ -3501,7 +4024,7 @@ possessive = TRUE; min = 0; max = GET2(ecode, 1); - ecode += 3; + ecode += 1 + IMM2_SIZE; goto REPEATTYPE; case OP_TYPESTAR: @@ -3547,13 +4070,13 @@ switch(prop_type) { case PT_ANY: - if (prop_fail_result) MRRETURN(MATCH_NOMATCH); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); } @@ -3562,17 +4085,18 @@ case PT_LAMP: for (i = 1; i <= min; i++) { + int chartype; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3582,12 +4106,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3597,12 +4120,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3612,28 +4134,27 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; case PT_ALNUM: for (i = 1; i <= min; i++) { + int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } break; @@ -3643,14 +4164,13 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3660,31 +4180,30 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case PT_WORD: for (i = 1; i <= min; i++) { + int category; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N || - c == CHAR_UNDERSCORE) + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3705,20 +4224,18 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; - if (!utf8) c = *eptr; - else { GETCHARLEN(c, eptr, len); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } } @@ -3727,8 +4244,8 @@ /* Handle all other cases when the coding is UTF-8 */ -#ifdef SUPPORT_UTF8 - if (utf8) switch(ctype) +#ifdef SUPPORT_UTF + if (utf) switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) @@ -3736,11 +4253,20 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3750,15 +4276,15 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; case OP_ANYBYTE: - if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH); + if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH); eptr += min; break; @@ -3768,12 +4294,13 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -3786,7 +4313,7 @@ case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -3798,7 +4325,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3823,7 +4350,7 @@ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3834,12 +4361,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -3870,7 +4397,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) @@ -3883,7 +4410,7 @@ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } } break; @@ -3894,12 +4421,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -3918,11 +4445,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINC(c, eptr); if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; @@ -3932,10 +4459,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3946,11 +4474,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) - MRRETURN(MATCH_NOMATCH); - while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3960,10 +4489,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -3974,11 +4504,12 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); - while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); + RRETURN(MATCH_NOMATCH); + eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } break; @@ -3988,10 +4519,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ } break; @@ -4001,7 +4533,7 @@ } /* End switch(ctype) */ else -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* Code for the non-UTF-8 case for minimum matching of operators other than OP_PROP and OP_NOTPROP. */ @@ -4013,10 +4545,19 @@ { if (eptr >= md->end_subject) { - SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); + if (md->partial != 0 && + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); } - if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); eptr++; } break; @@ -4025,7 +4566,7 @@ if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4034,7 +4575,7 @@ if (eptr > md->end_subject - min) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } eptr += min; break; @@ -4045,21 +4586,27 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); + case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; + case 0x000a: break; case 0x000b: case 0x000c: case 0x0085: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } } @@ -4071,7 +4618,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4079,7 +4626,25 @@ case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif + RRETURN(MATCH_NOMATCH); } } break; @@ -4090,14 +4655,32 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif break; } } @@ -4109,7 +4692,7 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { @@ -4119,7 +4702,11 @@ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif + RRETURN(MATCH_NOMATCH); } } break; @@ -4130,16 +4717,20 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } switch(*eptr++) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif break; } } @@ -4151,9 +4742,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4163,9 +4756,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4175,9 +4770,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4187,9 +4784,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4199,10 +4798,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4212,10 +4812,11 @@ if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } - if ((md->ctypes[*eptr++] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) + RRETURN(MATCH_NOMATCH); + eptr++; } break; @@ -4242,170 +4843,167 @@ case PT_ANY: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM36); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - if (prop_fail_result) MRRETURN(MATCH_NOMATCH); + if (prop_fail_result) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_LAMP: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37); + int chartype; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM37); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_GC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM38); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM39); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SC: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM40); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_ALNUM: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59); + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM59); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_SPACE: /* Perl space */ for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM60); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_PXSPACE: /* POSIX space */ for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM61); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ case PT_WORD: for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62); + int category; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM62); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || - prop_category == ucp_N || + category = UCD_CATEGORY(c); + if ((category == ucp_L || + category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -4423,52 +5021,59 @@ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM41); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; - if (!utf8) c = *eptr; - else { GETCHARLEN(c, eptr, len); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } } - else #endif /* SUPPORT_UCP */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM42); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(ctype) { - case OP_ANY: /* This is the non-NL case */ + case OP_ANY: /* This is the non-NL case */ + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + break; + case OP_ALLANY: case OP_ANYBYTE: break; @@ -4476,7 +5081,7 @@ case OP_ANYNL: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -4488,7 +5093,7 @@ case 0x0085: case 0x2028: case 0x2029: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4516,14 +5121,14 @@ case 0x202f: /* NARROW NO-BREAK SPACE */ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ @@ -4558,14 +5163,14 @@ case 0x85: /* NEL */ case 0x2028: /* LINE SEPARATOR */ case 0x2029: /* PARAGRAPH SEPARATOR */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ @@ -4579,32 +5184,32 @@ case OP_NOT_DIGIT: if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (c < 256 && (md->ctypes[c] & ctype_space) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: - if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) - MRRETURN(MATCH_NOMATCH); + if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) + RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (c < 256 && (md->ctypes[c] & ctype_word) != 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); break; default: @@ -4614,24 +5219,35 @@ } else #endif - /* Not UTF-8 mode */ + /* Not UTF mode */ { for (fi = min;; fi++) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM43); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) MRRETURN(MATCH_NOMATCH); + if (fi >= max) RRETURN(MATCH_NOMATCH); if (eptr >= md->end_subject) { SCHECK_PARTIAL(); - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } if (ctype == OP_ANY && IS_NEWLINE(eptr)) - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); c = *eptr++; switch(ctype) { - case OP_ANY: /* This is the non-NL case */ + case OP_ANY: /* This is the non-NL case */ + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + c == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } + break; + case OP_ALLANY: case OP_ANYBYTE: break; @@ -4639,7 +5255,7 @@ case OP_ANYNL: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x000d: if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; @@ -4650,7 +5266,11 @@ case 0x000b: case 0x000c: case 0x0085: - if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: + case 0x2029: +#endif + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } break; @@ -4662,17 +5282,53 @@ case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif + RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x09: /* HT */ case 0x20: /* SPACE */ case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ +#endif break; } break; @@ -4686,45 +5342,53 @@ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ - MRRETURN(MATCH_NOMATCH); +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif + RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { - default: MRRETURN(MATCH_NOMATCH); + default: RRETURN(MATCH_NOMATCH); case 0x0a: /* LF */ case 0x0b: /* VT */ case 0x0c: /* FF */ case 0x0d: /* CR */ case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ +#endif break; } break; case OP_NOT_DIGIT: - if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: - if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: - if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: - if ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: - if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH); + if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: - if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH); + if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: @@ -4766,6 +5430,7 @@ case PT_LAMP: for (i = min; i < max; i++) { + int chartype; int len = 1; if (eptr >= md->end_subject) { @@ -4773,10 +5438,10 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == ucp_Lu || - prop_chartype == ucp_Ll || - prop_chartype == ucp_Lt) == prop_fail_result) + chartype = UCD_CHARTYPE(c); + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == prop_fail_result) break; eptr+= len; } @@ -4792,9 +5457,7 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == prop_value) == prop_fail_result) - break; + if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4809,9 +5472,7 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_chartype = UCD_CHARTYPE(c); - if ((prop_chartype == prop_value) == prop_fail_result) - break; + if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4826,9 +5487,7 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_script = UCD_SCRIPT(c); - if ((prop_script == prop_value) == prop_fail_result) - break; + if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break; eptr+= len; } break; @@ -4836,6 +5495,7 @@ case PT_ALNUM: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4843,9 +5503,8 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N) - == prop_fail_result) + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N) == prop_fail_result) break; eptr+= len; } @@ -4861,8 +5520,7 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; @@ -4880,8 +5538,7 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL || + if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == prop_fail_result) break; @@ -4892,6 +5549,7 @@ case PT_WORD: for (i = min; i < max; i++) { + int category; int len = 1; if (eptr >= md->end_subject) { @@ -4899,8 +5557,8 @@ break; } GETCHARLENTEST(c, eptr, len); - prop_category = UCD_CATEGORY(c); - if ((prop_category == ucp_L || prop_category == ucp_N || + category = UCD_CATEGORY(c); + if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE) == prop_fail_result) break; eptr+= len; @@ -4916,10 +5574,10 @@ if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ - if (utf8) BACKCHAR(eptr); + if (utf) BACKCHAR(eptr); } } @@ -4930,25 +5588,23 @@ { for (i = min; i < max; i++) { + int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } - GETCHARINCTEST(c, eptr); - prop_category = UCD_CATEGORY(c); - if (prop_category == ucp_M) break; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) == ucp_M) break; + eptr += len; while (eptr < md->end_subject) { - int len = 1; - if (!utf8) c = *eptr; else - { - GETCHARLEN(c, eptr, len); - } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; eptr += len; } + CHECK_PARTIAL(); } /* eptr is now past the end of the maximum run */ @@ -4957,19 +5613,17 @@ for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM45); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ for (;;) /* Move back over one extended */ { - int len = 1; - if (!utf8) c = *eptr; else + if (!utf) c = *eptr; else { BACKCHAR(eptr); - GETCHARLEN(c, eptr, len); + GETCHAR(c, eptr); } - prop_category = UCD_CATEGORY(c); - if (prop_category != ucp_M) break; + if (UCD_CATEGORY(c) != ucp_M) break; eptr--; } } @@ -4978,10 +5632,8 @@ else #endif /* SUPPORT_UCP */ -#ifdef SUPPORT_UTF8 - /* UTF-8 mode */ - - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { switch(ctype) { @@ -4996,8 +5648,17 @@ break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } @@ -5013,8 +5674,17 @@ break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } break; @@ -5030,10 +5700,14 @@ break; } eptr++; - while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; + ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); } } - else eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + else + { + eptr = md->end_subject; /* Unlimited UTF-8 repeat */ + SCHECK_PARTIAL(); + } break; /* The byte case is the same as non-UTF8 */ @@ -5241,21 +5915,26 @@ RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run */ + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character, unless we are matching \R and the last thing matched was + \r\n, in which case, back up two bytes. */ if (possessive) continue; for(;;) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46); + RMATCH(eptr, ecode, offset_top, md, eptrb, RM46); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } else -#endif /* SUPPORT_UTF8 */ - - /* Not UTF-8 mode */ +#endif /* SUPPORT_UTF */ + /* Not UTF mode */ { switch(ctype) { @@ -5268,6 +5947,15 @@ break; } if (IS_NEWLINE(eptr)) break; + if (md->partial != 0 && /* Take care with CRLF partial */ + eptr + 1 >= md->end_subject && + NLBLOCK->nltype == NLTYPE_FIXED && + NLBLOCK->nllen == 2 && + *eptr == NLBLOCK->nl[0]) + { + md->hitend = TRUE; + if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); + } eptr++; } break; @@ -5299,10 +5987,12 @@ } else { - if (c != 0x000a && - (md->bsr_anycrlf || - (c != 0x000b && c != 0x000c && c != 0x0085))) - break; + if (c != 0x000a && (md->bsr_anycrlf || + (c != 0x000b && c != 0x000c && c != 0x0085 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 +#endif + ))) break; eptr++; } } @@ -5317,7 +6007,12 @@ break; } c = *eptr; - if (c == 0x09 || c == 0x20 || c == 0xa0) break; + if (c == 0x09 || c == 0x20 || c == 0xa0 +#ifdef COMPILE_PCRE16 + || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A) + || c == 0x202f || c == 0x205f || c == 0x3000 +#endif + ) break; eptr++; } break; @@ -5331,7 +6026,12 @@ break; } c = *eptr; - if (c != 0x09 && c != 0x20 && c != 0xa0) break; + if (c != 0x09 && c != 0x20 && c != 0xa0 +#ifdef COMPILE_PCRE16 + && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A) + && c != 0x202f && c != 0x205f && c != 0x3000 +#endif + ) break; eptr++; } break; @@ -5345,8 +6045,11 @@ break; } c = *eptr; - if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85) - break; + if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85 +#ifdef COMPILE_PCRE16 + || c == 0x2028 || c == 0x2029 +#endif + ) break; eptr++; } break; @@ -5360,8 +6063,11 @@ break; } c = *eptr; - if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85) - break; + if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 +#endif + ) break; eptr++; } break; @@ -5374,7 +6080,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_digit) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break; eptr++; } break; @@ -5387,7 +6093,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_digit) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break; eptr++; } break; @@ -5400,7 +6106,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_space) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break; eptr++; } break; @@ -5413,7 +6119,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_space) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break; eptr++; } break; @@ -5426,7 +6132,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_word) != 0) break; + if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break; eptr++; } break; @@ -5439,7 +6145,7 @@ SCHECK_PARTIAL(); break; } - if ((md->ctypes[*eptr] & ctype_word) == 0) break; + if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break; eptr++; } break; @@ -5448,20 +6154,26 @@ RRETURN(PCRE_ERROR_INTERNAL); } - /* eptr is now past the end of the maximum run */ + /* eptr is now past the end of the maximum run. If possessive, we are + done (no backing up). Otherwise, match at this position; anything other + than no match is immediately returned. For nomatch, back up one + character (byte), unless we are matching \R and the last thing matched + was \r\n, in which case, back up two bytes. */ if (possessive) continue; while (eptr >= pp) { - RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47); - eptr--; + RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); if (rrc != MATCH_NOMATCH) RRETURN(rrc); + eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } /* Get here if we can't make it match with any permitted repetitions */ - MRRETURN(MATCH_NOMATCH); + RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -5494,17 +6206,25 @@ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17) LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33) LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) - LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) -#ifdef SUPPORT_UTF8 - LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30) + LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) + LBL(65) LBL(66) +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + LBL(21) +#endif +#ifdef SUPPORT_UTF + LBL(16) LBL(18) LBL(20) + LBL(22) LBL(23) LBL(28) LBL(30) LBL(32) LBL(34) LBL(42) LBL(46) #ifdef SUPPORT_UCP LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) LBL(59) LBL(60) LBL(61) LBL(62) #endif /* SUPPORT_UCP */ -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ default: DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); + +printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere); + return PCRE_ERROR_INTERNAL; } #undef LBL @@ -5523,7 +6243,6 @@ #undef ecode #undef mstart #undef offset_top -#undef ims #undef eptrb #undef flags @@ -5541,8 +6260,6 @@ #undef condition #undef prev_is_word -#undef original_ims - #undef ctype #undef length #undef max @@ -5569,6 +6286,31 @@ ***************************************************************************/ +#ifdef NO_RECURSE +/************************************************* +* Release allocated heap frames * +*************************************************/ + +/* This function releases all the allocated frames. The base frame is on the +machine stack, and so must not be freed. + +Argument: the address of the base frame +Returns: nothing +*/ + +static void +release_match_heapframes (heapframe *frame_base) +{ +heapframe *nextframe = frame_base->Xnextframe; +while (nextframe != NULL) + { + heapframe *oldframe = nextframe; + nextframe = nextframe->Xnextframe; + (PUBL(stack_free))(oldframe); + } +} +#endif + /************************************************* * Execute a Regular Expression * @@ -5594,52 +6336,150 @@ < -1 => some kind of unexpected problem */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, int offsetcount) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, + PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, + int offsetcount) +#endif { -int rc, resetcount, ocount; -int first_byte = -1; -int req_byte = -1; -int req_byte2 = -1; +int rc, ocount, arg_offset_max; int newline; -unsigned long int ims; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; BOOL firstline; -BOOL first_byte_caseless = FALSE; -BOOL req_byte_caseless = FALSE; -BOOL utf8; +BOOL utf; +BOOL has_first_char = FALSE; +BOOL has_req_char = FALSE; +pcre_uchar first_char = 0; +pcre_uchar first_char2 = 0; +pcre_uchar req_char = 0; +pcre_uchar req_char2 = 0; match_data match_block; match_data *md = &match_block; -const uschar *tables; -const uschar *start_bits = NULL; -USPTR start_match = (USPTR)subject + start_offset; -USPTR end_subject; -USPTR start_partial = NULL; -USPTR req_byte_ptr = start_match - 1; +const pcre_uint8 *tables; +const pcre_uint8 *start_bits = NULL; +PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset; +PCRE_PUCHAR end_subject; +PCRE_PUCHAR start_partial = NULL; +PCRE_PUCHAR req_char_ptr = start_match - 1; -pcre_study_data internal_study; const pcre_study_data *study; +const REAL_PCRE *re = (const REAL_PCRE *)argument_re; + +#ifdef NO_RECURSE +heapframe frame_zero; +frame_zero.Xprevframe = NULL; /* Marks the top level */ +frame_zero.Xnextframe = NULL; /* None are allocated yet */ +md->match_frames_base = &frame_zero; +#endif + +/* Check for the special magic call that measures the size of the stack used +per recursive call of match(). Without the funny casting for sizeof, a Windows +compiler gave this error: "unary minus operator applied to unsigned type, +result still unsigned". Hopefully the cast fixes that. */ -real_pcre internal_re; -const real_pcre *external_re = (const real_pcre *)argument_re; -const real_pcre *re = external_re; +if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && + start_offset == -999) +#ifdef NO_RECURSE + return -((int)sizeof(heapframe)); +#else + return match(NULL, NULL, NULL, 0, NULL, NULL, 0); +#endif /* Plausibility checks */ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; -if (re == NULL || subject == NULL || - (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; +if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) + return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; -/* This information is for finding all the numbers associated with a given -name, for condition testing. */ +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ + +if (re->magic_number != MAGIC_NUMBER) + return re->magic_number == REVERSED_MAGIC_NUMBER? + PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; + +/* These two settings are used in the code for checking a UTF-8 string that +follows immediately afterwards. Other values in the md block are used only +during "normal" pcre_exec() processing, not when the JIT support is in use, +so they are set up later. */ + +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = md->utf = (re->options & PCRE_UTF8) != 0; +md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : + ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; + +/* Check a UTF-8 string if required. Pass back the character offset and error +code for an invalid string if a results vector is available. */ + +#ifdef SUPPORT_UTF +if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) + { + int erroroffset; + int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset); + if (errorcode != 0) + { + if (offsetcount >= 2) + { + offsets[0] = erroroffset; + offsets[1] = errorcode; + } +#ifdef COMPILE_PCRE16 + return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? + PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; +#else + return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; +#endif + } + + /* Check that a start_offset points to the start of a UTF character. */ + if (start_offset > 0 && start_offset < length && + NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) + return PCRE_ERROR_BADUTF8_OFFSET; + } +#endif + +/* If the pattern was successfully studied with JIT support, run the JIT +executable instead of the rest of this function. Most options must be set at +compile time for the JIT code to be usable. Fallback to the normal code path if +an unsupported flag is set. */ + +#ifdef SUPPORT_JIT +if (extra_data != NULL + && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | + PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT + && extra_data->executable_jit != NULL + && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | + PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | + PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) + { + rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, + start_offset, options, offsets, offsetcount); + + /* PCRE_ERROR_NULL means that the selected normal or partial matching + mode is not compiled. In this case we simply fallback to interpreter. */ + + if (rc != PCRE_ERROR_NULL) return rc; + } +#endif -md->name_table = (uschar *)re + re->name_table_offset; +/* Carry on with non-JIT matching. This information is for finding all the +numbers associated with a given name, for condition testing. */ + +md->name_table = (pcre_uchar *)re + re->name_table_offset; md->name_count = re->name_count; md->name_entry_size = re->name_entry_size; @@ -5653,7 +6493,7 @@ /* The table pointer is always in native byte order. */ -tables = external_re->tables; +tables = re->tables; if (extra_data != NULL) { @@ -5673,19 +6513,7 @@ is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ -if (tables == NULL) tables = _pcre_default_tables; - -/* Check that the first field in the block is the magic number. If it is not, -test for a regex that was compiled on a host of opposite endianness. If this is -the case, flipped values are put in internal_re and internal_study if there was -study data too. */ - -if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, study, &internal_study); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - if (study != NULL) study = &internal_study; - } +if (tables == NULL) tables = PRIV(default_tables); /* Set up other data */ @@ -5695,31 +6523,35 @@ /* The code starts after the real_pcre block and the capture name table. */ -md->start_code = (const uschar *)external_re + re->name_table_offset + +md->start_code = (const pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; -md->start_subject = (USPTR)subject; +md->start_subject = (PCRE_PUCHAR)subject; md->start_offset = start_offset; md->end_subject = md->start_subject + length; end_subject = md->end_subject; md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; -utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0; md->use_ucp = (re->options & PCRE_UCP) != 0; md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; +md->ignore_skip_arg = FALSE; + +/* Some options are unpacked into BOOL variables in the hope that testing +them will be faster than individual option bits. */ md->notbol = (options & PCRE_NOTBOL) != 0; md->noteol = (options & PCRE_NOTEOL) != 0; md->notempty = (options & PCRE_NOTEMPTY) != 0; md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; -md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : - ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; + md->hitend = FALSE; -md->mark = NULL; /* In case never set */ +md->mark = md->nomatch_mark = NULL; /* In case never set */ md->recursive = NULL; /* No recursion at top level */ +md->hasthen = (re->flags & PCRE_HASTHEN) != 0; md->lcc = tables + lcc_offset; +md->fcc = tables + fcc_offset; md->ctypes = tables + ctypes_offset; /* Handle different \R options. */ @@ -5795,41 +6627,18 @@ if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0) return PCRE_ERROR_BADPARTIAL; -/* Check a UTF-8 string if required. Unfortunately there's no way of passing -back the character offset. */ - -#ifdef SUPPORT_UTF8 -if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) - { - int tb; - if ((tb = _pcre_valid_utf8((USPTR)subject, length)) >= 0) - return (tb == length && md->partial > 1)? - PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; - if (start_offset > 0 && start_offset < length) - { - tb = ((USPTR)subject)[start_offset] & 0xc0; - if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET; - } - } -#endif - -/* The ims options can vary during the matching as a result of the presence -of (?ims) items in the pattern. They are kept in a local variable so that -restoring at the exit of a group is easy. */ - -ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); - /* If the expression has got more back references than the offsets supplied can hold, we get a temporary chunk of working store to use during the matching. Otherwise, we can use the vector supplied, rounding down its size to a multiple of 3. */ ocount = offsetcount - (offsetcount % 3); +arg_offset_max = (2*ocount)/3; if (re->top_backref > 0 && re->top_backref >= ocount/3) { ocount = re->top_backref * 3 + 3; - md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); + md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int)); if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY; using_temporary_offsets = TRUE; DPRINTF(("Got memory to hold back references\n")); @@ -5841,25 +6650,22 @@ md->offset_overflow = FALSE; md->capture_last = -1; -/* Compute the minimum number of offsets that we need to reset each time. Doing -this makes a huge difference to execution time when there aren't many brackets -in the pattern. */ - -resetcount = 2 + re->top_bracket * 2; -if (resetcount > offsetcount) resetcount = ocount; - /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we -initialize them to avoid reading uninitialized locations. */ +initialize them to avoid reading uninitialized locations. Also, unset the +offsets for the matched string. This is really just for tidiness with callouts, +in case they inspect these fields. */ if (md->offset_vector != NULL) { register int *iptr = md->offset_vector + ocount; - register int *iend = iptr - resetcount/2 + 1; + register int *iend = iptr - re->top_bracket; + if (iend < md->offset_vector + 2) iend = md->offset_vector + 2; while (--iptr >= iend) *iptr = -1; + md->offset_vector[0] = md->offset_vector[1] = -1; } -/* Set up the first character to match, if available. The first_byte value is +/* Set up the first character to match, if available. The first_char value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was @@ -5869,9 +6675,16 @@ { if ((re->flags & PCRE_FIRSTSET) != 0) { - first_byte = re->first_byte & 255; - if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) - first_byte = md->lcc[first_byte]; + has_first_char = TRUE; + first_char = first_char2 = (pcre_uchar)(re->first_char); + if ((re->flags & PCRE_FCH_CASELESS) != 0) + { + first_char2 = TABLE_GET(first_char, md->fcc, first_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && first_char > 127) + first_char2 = UCD_OTHERCASE(first_char); +#endif + } } else if (!startline && study != NULL && @@ -5884,9 +6697,16 @@ if ((re->flags & PCRE_REQCHSET) != 0) { - req_byte = re->req_byte & 255; - req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; - req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ + has_req_char = TRUE; + req_char = req_char2 = (pcre_uchar)(re->req_char); + if ((re->flags & PCRE_RCH_CASELESS) != 0) + { + req_char2 = TABLE_GET(req_char, md->fcc, req_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (utf && req_char > 127) + req_char2 = UCD_OTHERCASE(req_char); +#endif + } } @@ -5897,17 +6717,8 @@ for(;;) { - USPTR save_end_subject = end_subject; - USPTR new_start_match; - - /* Reset the maximum number of extractions we might see. */ - - if (md->offset_vector != NULL) - { - register int *iptr = md->offset_vector; - register int *iend = iptr + resetcount; - while (iptr < iend) *iptr++ = -1; - } + PCRE_PUCHAR save_end_subject = end_subject; + PCRE_PUCHAR new_start_match; /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the first @@ -5917,14 +6728,14 @@ if (firstline) { - USPTR t = start_match; -#ifdef SUPPORT_UTF8 - if (utf8) + PCRE_PUCHAR t = start_match; +#ifdef SUPPORT_UTF + if (utf) { while (t < md->end_subject && !IS_NEWLINE(t)) { t++; - while (t < end_subject && (*t & 0xc0) == 0x80) t++; + ACROSSCHAR(t < end_subject, *t, t++); } } else @@ -5941,15 +6752,16 @@ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) { - /* Advance to a unique first byte if there is one. */ + /* Advance to a unique first char if there is one. */ - if (first_byte >= 0) + if (has_first_char) { - if (first_byte_caseless) - while (start_match < end_subject && md->lcc[*start_match] != first_byte) + if (first_char != first_char2) + while (start_match < end_subject && + *start_match != first_char && *start_match != first_char2) start_match++; else - while (start_match < end_subject && *start_match != first_byte) + while (start_match < end_subject && *start_match != first_char) start_match++; } @@ -5959,14 +6771,14 @@ { if (start_match > md->start_subject + start_offset) { -#ifdef SUPPORT_UTF8 - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { while (start_match < end_subject && !WAS_NEWLINE(start_match)) { start_match++; - while(start_match < end_subject && (*start_match & 0xc0) == 0x80) - start_match++; + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); } } else @@ -5993,13 +6805,18 @@ while (start_match < end_subject) { register unsigned int c = *start_match; +#ifndef COMPILE_PCRE8 + if (c > 255) c = 255; +#endif if ((start_bits[c/8] & (1 << (c&7))) == 0) { start_match++; -#ifdef SUPPORT_UTF8 - if (utf8) - while(start_match < end_subject && (*start_match & 0xc0) == 0x80) - start_match++; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + /* In non 8-bit mode, the iteration will stop for + characters > 255 at the beginning or not stop at all. */ + if (utf) + ACROSSCHAR(start_match < end_subject, *start_match, + start_match++); #endif } else break; @@ -6014,7 +6831,7 @@ /* The following two optimizations are disabled for partial matching or if disabling is explicitly requested. */ - if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial) + if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial) { /* If the pattern was studied, a minimum subject length may be set. This is a lower bound; no actual string of that length may actually match the @@ -6028,8 +6845,8 @@ break; } - /* If req_byte is set, we know that that character must appear in the - subject for the match to succeed. If the first character is set, req_byte + /* If req_char is set, we know that that character must appear in the + subject for the match to succeed. If the first character is set, req_char must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code @@ -6042,28 +6859,28 @@ 32-megabyte string... so we don't do this when the string is sufficiently long. */ - if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX) + if (has_req_char && end_subject - start_match < REQ_BYTE_MAX) { - register USPTR p = start_match + ((first_byte >= 0)? 1 : 0); + register PCRE_PUCHAR p = start_match + (has_first_char? 1:0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ - if (p > req_byte_ptr) + if (p > req_char_ptr) { - if (req_byte_caseless) + if (req_char != req_char2) { while (p < end_subject) { register int pp = *p++; - if (pp == req_byte || pp == req_byte2) { p--; break; } + if (pp == req_char || pp == req_char2) { p--; break; } } } else { while (p < end_subject) { - if (*p++ == req_byte) { p--; break; } + if (*p++ == req_char) { p--; break; } } } @@ -6080,7 +6897,7 @@ found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ - req_byte_ptr = p; + req_char_ptr = p; } } } @@ -6097,12 +6914,25 @@ md->start_match_ptr = start_match; md->start_used_ptr = start_match; md->match_call_count = 0; - rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL, - 0, 0); + md->match_function_type = 0; + md->end_offset_top = 0; + rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0); if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr; switch(rc) { + /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched + the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP + entirely. The only way we can do that is to re-do the match at the same + point, with a flag to force SKIP with an argument to be ignored. Just + treating this case as NOMATCH does not work because it does not check other + alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */ + + case MATCH_SKIP_ARG: + new_start_match = start_match; + md->ignore_skip_arg = TRUE; + break; + /* SKIP passes back the next starting point explicitly, but if it is the same as the match we have just done, treat it as NOMATCH. */ @@ -6114,23 +6944,18 @@ } /* Fall through */ - /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched - the SKIP's arg was not found. We also treat this as NOMATCH. */ - - case MATCH_SKIP_ARG: - /* Fall through */ - /* NOMATCH and PRUNE advance by one character. THEN at this level acts - exactly like PRUNE. */ + exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */ case MATCH_NOMATCH: case MATCH_PRUNE: case MATCH_THEN: + md->ignore_skip_arg = FALSE; new_start_match = start_match + 1; -#ifdef SUPPORT_UTF8 - if (utf8) - while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80) - new_start_match++; +#ifdef SUPPORT_UTF + if (utf) + ACROSSCHAR(new_start_match < end_subject, *new_start_match, + new_start_match++); #endif break; @@ -6168,9 +6993,13 @@ /* If we have just passed a CR and we are now at a LF, and the pattern does not contain any explicit matches for \r or \n, and the newline option is CRLF - or ANY or ANYCRLF, advance the match position by one more character. */ + or ANY or ANYCRLF, advance the match position by one more character. In + normal matching start_match will aways be greater than the first position at + this stage, but a failed *SKIP can cause a return at the same point, which is + why the first test exists. */ - if (start_match[-1] == CHAR_CR && + if (start_match > (PCRE_PUCHAR)subject + start_offset && + start_match[-1] == CHAR_CR && start_match < end_subject && *start_match == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && @@ -6208,21 +7037,41 @@ { if (using_temporary_offsets) { - if (offsetcount >= 4) + if (arg_offset_max >= 4) { memcpy(offsets + 2, md->offset_vector + 2, - (offsetcount - 2) * sizeof(int)); + (arg_offset_max - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } - if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE; + if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; DPRINTF(("Freeing temporary memory\n")); - (pcre_free)(md->offset_vector); + (PUBL(free))(md->offset_vector); } - /* Set the return code to the number of captured strings, or 0 if there are + /* Set the return code to the number of captured strings, or 0 if there were too many to fit into the vector. */ - rc = md->offset_overflow? 0 : md->end_offset_top/2; + rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)? + 0 : md->end_offset_top/2; + + /* If there is space in the offset vector, set any unused pairs at the end of + the pattern to -1 for backwards compatibility. It is documented that this + happens. In earlier versions, the whole set of potential capturing offsets + was set to -1 each time round the loop, but this is handled differently now. + "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only + those at the end that need unsetting here. We can't just unset them all at + the start of the whole thing because they may get set in one branch that is + not the final matching branch. */ + + if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL) + { + register int *iptr, *iend; + int resetcount = 2 + re->top_bracket * 2; + if (resetcount > offsetcount) resetcount = offsetcount; + iptr = offsets + md->end_offset_top; + iend = offsets + resetcount; + while (iptr < iend) *iptr++ = -1; + } /* If there is space, set up the whole thing as substring 0. The value of md->start_match_ptr might be modified if \K was encountered on the success @@ -6234,8 +7083,15 @@ offsets[1] = (int)(md->end_match_ptr - md->start_subject); } + /* Return MARK data if requested */ + + if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) + *(extra_data->mark) = (pcre_uchar *)md->mark; DPRINTF((">>>> returning %d\n", rc)); - goto RETURN_MARK; +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif + return rc; } /* Control gets here if there has been an error, or if the overall match @@ -6244,7 +7100,7 @@ if (using_temporary_offsets) { DPRINTF(("Freeing temporary memory\n")); - (pcre_free)(md->offset_vector); + (PUBL(free))(md->offset_vector); } /* For anything other than nomatch or partial match, just return the code. */ @@ -6252,6 +7108,9 @@ if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) { DPRINTF((">>>> error: returning %d\n", rc)); +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif return rc; } @@ -6263,8 +7122,8 @@ md->mark = NULL; if (offsetcount > 1) { - offsets[0] = (int)(start_partial - (USPTR)subject); - offsets[1] = (int)(end_subject - (USPTR)subject); + offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); + offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); } rc = PCRE_ERROR_PARTIAL; } @@ -6279,10 +7138,11 @@ /* Return the MARK data if it has been requested. */ -RETURN_MARK: - if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) - *(extra_data->mark) = (unsigned char *)(md->mark); + *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; +#ifdef NO_RECURSE + release_match_heapframes(&frame_zero); +#endif return rc; } diff -Nru pcre3-8.12/pcre_fullinfo.c pcre3-8.31/pcre_fullinfo.c --- pcre3-8.12/pcre_fullinfo.c 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/pcre_fullinfo.c 2012-06-02 10:55:16.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -65,13 +65,17 @@ Returns: 0 if data returned, negative on error */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, - void *where) +pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, + int what, void *where) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, + int what, void *where) +#endif { -real_pcre internal_re; -pcre_study_data internal_study; -const real_pcre *re = (const real_pcre *)argument_re; +const REAL_PCRE *re = (const REAL_PCRE *)argument_re; const pcre_study_data *study = NULL; if (re == NULL || where == NULL) return PCRE_ERROR_NULL; @@ -79,12 +83,18 @@ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; +/* Check that the first field in the block is the magic number. If it is not, +return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to +REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which +means that the pattern is likely compiled with different endianness. */ + if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, study, &internal_study); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - if (study != NULL) study = &internal_study; - } + return re->magic_number == REVERSED_MAGIC_NUMBER? + PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; + +/* Check that this pattern was compiled in the correct bit mode */ + +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; switch (what) { @@ -100,6 +110,18 @@ *((size_t *)where) = (study == NULL)? 0 : study->size; break; + case PCRE_INFO_JITSIZE: +#ifdef SUPPORT_JIT + *((size_t *)where) = + (extra_data != NULL && + (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra_data->executable_jit != NULL)? + PRIV(jit_get_size)(extra_data->executable_jit) : 0; +#else + *((size_t *)where) = 0; +#endif + break; + case PCRE_INFO_CAPTURECOUNT: *((int *)where) = re->top_bracket; break; @@ -110,7 +132,7 @@ case PCRE_INFO_FIRSTBYTE: *((int *)where) = - ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte : + ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char : ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; break; @@ -118,7 +140,7 @@ block, not the internal copy (with flipped integer fields). */ case PCRE_INFO_FIRSTTABLE: - *((const uschar **)where) = + *((const pcre_uint8 **)where) = (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)? ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; break; @@ -126,12 +148,18 @@ case PCRE_INFO_MINLENGTH: *((int *)where) = (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)? - study->minlength : -1; + (int)(study->minlength) : -1; + break; + + case PCRE_INFO_JIT: + *((int *)where) = extra_data != NULL && + (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra_data->executable_jit != NULL; break; case PCRE_INFO_LASTLITERAL: *((int *)where) = - ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1; + ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1; break; case PCRE_INFO_NAMEENTRYSIZE: @@ -143,11 +171,11 @@ break; case PCRE_INFO_NAMETABLE: - *((const uschar **)where) = (const uschar *)re + re->name_table_offset; + *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset; break; case PCRE_INFO_DEFAULT_TABLES: - *((const uschar **)where) = (const uschar *)(_pcre_default_tables); + *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables)); break; /* From release 8.00 this will always return TRUE because NOPARTIAL is @@ -165,6 +193,10 @@ *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0; break; + case PCRE_INFO_MAXLOOKBEHIND: + *((int *)where) = re->max_lookbehind; + break; + default: return PCRE_ERROR_BADOPTION; } diff -Nru pcre3-8.12/pcre_get.c pcre3-8.31/pcre_get.c --- pcre3-8.12/pcre_get.c 2008-07-09 15:58:24.000000000 +0000 +++ pcre3-8.31/pcre_get.c 2012-01-17 14:10:47.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -65,14 +65,20 @@ (PCRE_ERROR_NOSUBSTRING) if not found */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringnumber(const pcre *code, const char *stringname) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname) +#endif { int rc; int entrysize; int top, bot; -uschar *nametable; +pcre_uchar *nametable; +#ifdef COMPILE_PCRE8 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; @@ -81,14 +87,26 @@ return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif bot = 0; while (top > bot) { int mid = (top + bot) / 2; - uschar *entry = nametable + entrysize*mid; - int c = strcmp(stringname, (char *)(entry + 2)); - if (c == 0) return (entry[0] << 8) + entry[1]; + pcre_uchar *entry = nametable + entrysize*mid; + int c = STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(entry + IMM2_SIZE)); + if (c == 0) return GET2(entry, 0); if (c > 0) bot = mid + 1; else top = mid; } @@ -114,15 +132,22 @@ (PCRE_ERROR_NOSUBSTRING) if not found */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringtable_entries(const pcre *code, const char *stringname, char **firstptr, char **lastptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname, + PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr) +#endif { int rc; int entrysize; int top, bot; -uschar *nametable, *lastentry; +pcre_uchar *nametable, *lastentry; +#ifdef COMPILE_PCRE8 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; @@ -131,30 +156,49 @@ return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; +#endif +#ifdef COMPILE_PCRE16 +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) + return rc; +if (top <= 0) return PCRE_ERROR_NOSUBSTRING; + +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) + return rc; +if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) + return rc; +#endif lastentry = nametable + entrysize * (top - 1); bot = 0; while (top > bot) { int mid = (top + bot) / 2; - uschar *entry = nametable + entrysize*mid; - int c = strcmp(stringname, (char *)(entry + 2)); + pcre_uchar *entry = nametable + entrysize*mid; + int c = STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(entry + IMM2_SIZE)); if (c == 0) { - uschar *first = entry; - uschar *last = entry; + pcre_uchar *first = entry; + pcre_uchar *last = entry; while (first > nametable) { - if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break; + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break; first -= entrysize; } while (last < lastentry) { - if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break; + if (STRCMP_UC_UC((pcre_uchar *)stringname, + (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break; last += entrysize; } +#ifdef COMPILE_PCRE8 *firstptr = (char *)first; *lastptr = (char *)last; +#else + *firstptr = (PCRE_UCHAR16 *)first; + *lastptr = (PCRE_UCHAR16 *)last; +#endif return entrysize; } if (c > 0) bot = mid + 1; else top = mid; @@ -182,23 +226,39 @@ or a negative number on error */ +#ifdef COMPILE_PCRE8 static int get_first_set(const pcre *code, const char *stringname, int *ovector) +#else +static int +get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) +#endif { -const real_pcre *re = (const real_pcre *)code; +const REAL_PCRE *re = (const REAL_PCRE *)code; int entrysize; +pcre_uchar *entry; +#ifdef COMPILE_PCRE8 char *first, *last; -uschar *entry; +#else +PCRE_UCHAR16 *first, *last; +#endif + +#ifdef COMPILE_PCRE8 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre_get_stringnumber(code, stringname); entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); +#else +if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) + return pcre16_get_stringnumber(code, stringname); +entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last); +#endif if (entrysize <= 0) return entrysize; -for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize) +for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) { - int n = (entry[0] << 8) + entry[1]; + int n = GET2(entry, 0); if (ovector[n*2] >= 0) return n; } -return (first[0] << 8) + first[1]; +return GET2(entry, 0); } @@ -231,9 +291,15 @@ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_UCHAR16 *buffer, int size) +#endif { int yield; if (stringnumber < 0 || stringnumber >= stringcount) @@ -241,7 +307,7 @@ stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; if (size < yield + 1) return PCRE_ERROR_NOMEMORY; -memcpy(buffer, subject + ovector[stringnumber], yield); +memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield)); buffer[yield] = 0; return yield; } @@ -276,13 +342,25 @@ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre_copy_named_substring(const pcre *code, const char *subject, + int *ovector, int stringcount, const char *stringname, + char *buffer, int size) +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, - int stringcount, const char *stringname, char *buffer, int size) +pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 stringname, + PCRE_UCHAR16 *buffer, int size) +#endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; +#ifdef COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); +#else +return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size); +#endif } @@ -308,29 +386,39 @@ PCRE_ERROR_NOMEMORY (-6) failed to get store */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, + PCRE_SPTR16 **listptr) +#endif { int i; -int size = sizeof(char *); +int size = sizeof(pcre_uchar *); int double_count = stringcount * 2; -char **stringlist; -char *p; +pcre_uchar **stringlist; +pcre_uchar *p; for (i = 0; i < double_count; i += 2) - size += sizeof(char *) + ovector[i+1] - ovector[i] + 1; + size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); -stringlist = (char **)(pcre_malloc)(size); +stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; +#ifdef COMPILE_PCRE8 *listptr = (const char **)stringlist; -p = (char *)(stringlist + stringcount + 1); +#else +*listptr = (PCRE_SPTR16 *)stringlist; +#endif +p = (pcre_uchar *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { int len = ovector[i+1] - ovector[i]; - memcpy(p, subject + ovector[i], len); + memcpy(p, subject + ovector[i], IN_UCHARS(len)); *stringlist++ = p; p += len; *p++ = 0; @@ -347,16 +435,22 @@ *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C -programs that can call its functions, but not free() or (pcre_free)() directly. +programs that can call its functions, but not free() or (PUBL(free))() +directly. Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring_list(const char **pointer) +#else +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring_list(PCRE_SPTR16 *pointer) +#endif { -(pcre_free)((void *)pointer); +(PUBL(free))((void *)pointer); } @@ -386,21 +480,31 @@ PCRE_ERROR_NOSUBSTRING (-7) substring not present */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, + int stringnumber, PCRE_SPTR16 *stringptr) +#endif { int yield; -char *substring; +pcre_uchar *substring; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; -substring = (char *)(pcre_malloc)(yield + 1); +substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1)); if (substring == NULL) return PCRE_ERROR_NOMEMORY; -memcpy(substring, subject + ovector[stringnumber], yield); +memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield)); substring[yield] = 0; -*stringptr = substring; +#ifdef COMPILE_PCRE8 +*stringptr = (const char *)substring; +#else +*stringptr = (PCRE_SPTR16)substring; +#endif return yield; } @@ -433,13 +537,25 @@ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, - int stringcount, const char *stringname, const char **stringptr) +pcre_get_named_substring(const pcre *code, const char *subject, + int *ovector, int stringcount, const char *stringname, + const char **stringptr) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, + int *ovector, int stringcount, PCRE_SPTR16 stringname, + PCRE_SPTR16 *stringptr) +#endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; +#ifdef COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); +#else +return pcre16_get_substring(subject, ovector, stringcount, n, stringptr); +#endif } @@ -450,16 +566,22 @@ *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C -programs that can call its functions, but not free() or (pcre_free)() directly. +programs that can call its functions, but not free() or (PUBL(free))() +directly. Argument: the result of a previous pcre_get_substring() Returns: nothing */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring(const char *pointer) +#else +PCRE_EXP_DEFN void PCRE_CALL_CONVENTION +pcre16_free_substring(PCRE_SPTR16 pointer) +#endif { -(pcre_free)((void *)pointer); +(PUBL(free))((void *)pointer); } /* End of pcre_get.c */ diff -Nru pcre3-8.12/pcre_globals.c pcre3-8.31/pcre_globals.c --- pcre3-8.12/pcre_globals.c 2010-03-10 16:05:24.000000000 +0000 +++ pcre3-8.31/pcre_globals.c 2012-01-05 17:07:07.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -67,18 +67,18 @@ { free(aPtr); } -PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = LocalPcreMalloc; -PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = LocalPcreFree; -PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = LocalPcreMalloc; -PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = LocalPcreFree; -PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; +PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc; +PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree; +PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc; +PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree; +PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #elif !defined VPCOMPAT -PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc; -PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free; -PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc; -PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free; -PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL; +PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free; +PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc; +PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free; +PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL; #endif /* End of pcre_globals.c */ diff -Nru pcre3-8.12/pcre_info.c pcre3-8.31/pcre_info.c --- pcre3-8.12/pcre_info.c 2009-03-15 16:56:56.000000000 +0000 +++ pcre3-8.31/pcre_info.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains the external function pcre_info(), which gives some -information about a compiled pattern. However, use of this function is now -deprecated, as it has been superseded by pcre_fullinfo(). */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre_internal.h" - - -/************************************************* -* (Obsolete) Return info about compiled pattern * -*************************************************/ - -/* This is the original "info" function. It picks potentially useful data out -of the private structure, but its interface was too rigid. It remains for -backwards compatibility. The public options are passed back in an int - though -the re->options field has been expanded to a long int, all the public options -at the low end of it, and so even on 16-bit systems this will still be OK. -Therefore, I haven't changed the API for pcre_info(). - -Arguments: - argument_re points to compiled code - optptr where to pass back the options - first_byte where to pass back the first character, - or -1 if multiline and all branches start ^, - or -2 otherwise - -Returns: number of capturing subpatterns - or negative values on error -*/ - -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_info(const pcre *argument_re, int *optptr, int *first_byte) -{ -real_pcre internal_re; -const real_pcre *re = (const real_pcre *)argument_re; -if (re == NULL) return PCRE_ERROR_NULL; -if (re->magic_number != MAGIC_NUMBER) - { - re = _pcre_try_flipped(re, &internal_re, NULL, NULL); - if (re == NULL) return PCRE_ERROR_BADMAGIC; - } -if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_COMPILE_OPTIONS); -if (first_byte != NULL) - *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte : - ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; -return re->top_bracket; -} - -/* End of pcre_info.c */ diff -Nru pcre3-8.12/pcre_internal.h pcre3-8.31/pcre_internal.h --- pcre3-8.12/pcre_internal.h 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_internal.h 2012-06-17 16:06:48.000000000 +0000 @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -40,7 +40,8 @@ /* This header contains definitions that are shared between the different modules, but which are not relevant to the exported API. This includes some -functions whose names all begin with "_pcre_". */ +functions whose names all begin with "_pcre_" or "_pcre16_" depending on +the PRIV macro. */ #ifndef PCRE_INTERNAL_H #define PCRE_INTERNAL_H @@ -51,20 +52,39 @@ #define PCRE_DEBUG #endif -/* We do not support both EBCDIC and UTF-8 at the same time. The "configure" -script prevents both being selected, but not everybody uses "configure". */ - -#if defined EBCDIC && defined SUPPORT_UTF8 -#error The use of both EBCDIC and SUPPORT_UTF8 is not supported. +/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */ +#ifndef COMPILE_PCRE16 +#define COMPILE_PCRE8 #endif -/* If SUPPORT_UCP is defined, SUPPORT_UTF8 must also be defined. The +/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The "configure" script ensures this, but not everybody uses "configure". */ -#if defined SUPPORT_UCP && !defined SUPPORT_UTF8 +#if defined SUPPORT_UCP && !(defined SUPPORT_UTF) +#define SUPPORT_UTF 1 +#endif + +/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility +reasons with existing code. */ + +#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF) +#define SUPPORT_UTF 1 +#endif + +/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code. +Until then we define it if SUPPORT_UTF is defined. */ + +#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8) #define SUPPORT_UTF8 1 #endif +/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure" +script prevents both being selected, but not everybody uses "configure". */ + +#if defined EBCDIC && defined SUPPORT_UTF +#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported. +#endif + /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef inline, and there are *still* stupid compilers about that don't like indented pre-processor statements, or at least there were when I first wrote this. After @@ -158,12 +178,14 @@ #define PCRE_CALL_CONVENTION #endif -/* We need to have types that specify unsigned 16-bit and 32-bit integers. We +/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We cannot determine these outside the compilation (e.g. by running a program as part of "configure") because PCRE is often cross-compiled for use on other systems. Instead we make use of the maximum sizes that are available at preprocessor time in standard C environments. */ +typedef unsigned char pcre_uint8; + #if USHRT_MAX == 65535 typedef unsigned short pcre_uint16; typedef short pcre_int16; @@ -206,12 +228,47 @@ /* All character handling must be done as unsigned characters. Otherwise there are problems with top-bit-set characters and functions such as isspace(). -However, we leave the interface to the outside world as char *, because that -should make things easier for callers. We define a short type for unsigned char -to save lots of typing. I tried "uchar", but it causes problems on Digital -Unix, where it is defined in sys/types, so use "uschar" instead. */ +However, we leave the interface to the outside world as char * or short *, +because that should make things easier for callers. This character type is +called pcre_uchar. + +The IN_UCHARS macro multiply its argument with the byte size of the current +pcre_uchar type. Useful for memcpy and such operations, whose require the +byte size of their input/output buffers. + +The MAX_255 macro checks whether its pcre_uchar input is less than 256. + +The TABLE_GET macro is designed for accessing elements of tables whose contain +exactly 256 items. When the character is able to contain more than 256 +items, some check is needed before accessing these tables. +*/ + +#ifdef COMPILE_PCRE8 + +typedef unsigned char pcre_uchar; +#define IN_UCHARS(x) (x) +#define MAX_255(c) 1 +#define TABLE_GET(c, table, default) ((table)[c]) + +#else + +#ifdef COMPILE_PCRE16 +#if USHRT_MAX != 65535 +/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in +pcre.h(.in) and disable (comment out) this message. */ +#error Warning: PCRE_UCHAR16 is not a 16 bit data type. +#endif + +typedef pcre_uint16 pcre_uchar; +#define IN_UCHARS(x) ((x) << 1) +#define MAX_255(c) ((c) <= 255u) +#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) -typedef unsigned char uschar; +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* This is an unsigned int value that no character can ever have. UTF-8 characters only go up to 0x7fffffff (though Unicode doesn't go beyond @@ -234,8 +291,8 @@ #define IS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) < NLBLOCK->PSEND && \ - _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\ - utf8)) \ + PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \ + &(NLBLOCK->nllen), utf)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ (p)[0] == NLBLOCK->nl[0] && \ @@ -248,8 +305,8 @@ #define WAS_NEWLINE(p) \ ((NLBLOCK->nltype != NLTYPE_FIXED)? \ ((p) > NLBLOCK->PSSTART && \ - _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ - &(NLBLOCK->nllen), utf8)) \ + PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \ + &(NLBLOCK->nllen), utf)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \ @@ -267,15 +324,11 @@ must begin with PCRE_. */ #ifdef CUSTOM_SUBJECT_PTR -#define PCRE_SPTR CUSTOM_SUBJECT_PTR -#define USPTR CUSTOM_SUBJECT_PTR +#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR #else -#define PCRE_SPTR const char * -#define USPTR const unsigned char * +#define PCRE_PUCHAR const pcre_uchar * #endif - - /* Include the public PCRE header and the definitions of UCP character property values. */ @@ -343,6 +396,8 @@ the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ +#ifdef COMPILE_PCRE8 + #if LINK_SIZE == 2 #define PUT(a,n,d) \ @@ -379,13 +434,54 @@ #define GET(a,n) \ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) -#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) + +#else +#error LINK_SIZE must be either 2, 3, or 4 +#endif + +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 + +#if LINK_SIZE == 2 + +#undef LINK_SIZE +#define LINK_SIZE 1 + +#define PUT(a,n,d) \ + (a[n] = (d)) + +#define GET(a,n) \ + (a[n]) + +#define MAX_PATTERN_SIZE (1 << 16) + +#elif LINK_SIZE == 3 || LINK_SIZE == 4 +#undef LINK_SIZE +#define LINK_SIZE 2 + +#define PUT(a,n,d) \ + (a[n] = (d) >> 16), \ + (a[(n)+1] = (d) & 65535) + +#define GET(a,n) \ + (((a)[n] << 16) | (a)[(n)+1]) + +/* Keep it positive */ +#define MAX_PATTERN_SIZE (1 << 30) #else #error LINK_SIZE must be either 2, 3, or 4 #endif +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* Convenience macro defined in terms of the others */ @@ -396,6 +492,10 @@ offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ +#ifdef COMPILE_PCRE8 + +#define IMM2_SIZE 2 + #define PUT2(a,n,d) \ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 @@ -403,17 +503,44 @@ #define GET2(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) -#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2 +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 + +#define IMM2_SIZE 1 + +#define PUT2(a,n,d) \ + a[n] = d + +#define GET2(a,n) \ + a[n] + +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ + +#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE + +/* The maximum length of a MARK name is currently one data unit; it may be +changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */ + +#define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1) +/* When UTF encoding is being used, a character is no longer just a single +character. The macros for character handling generate simple sequences when +used in character-mode, and more complicated ones for UTF characters. +GETCHARLENTEST and other macros are not used when UTF is not supported, +so they are not defined. To make sure they can never even appear when +UTF support is omitted, we don't even define them. */ -/* When UTF-8 encoding is being used, a character is no longer just a single -byte. The macros for character handling generate simple sequences when used in -byte-mode, and more complicated ones for UTF-8 characters. GETCHARLENTEST is -not used when UTF-8 is not supported, so it is not defined, and BACKCHAR should -never be called in byte mode. To make sure they can never even appear when -UTF-8 support is omitted, we don't even define them. */ +#ifndef SUPPORT_UTF -#ifndef SUPPORT_UTF8 +/* #define MAX_VALUE_FOR_SINGLE_CHAR */ +/* #define HAS_EXTRALEN(c) */ +/* #define GET_EXTRALEN(c) */ +/* #define NOT_FIRSTCHAR(c) */ #define GETCHAR(c, eptr) c = *eptr; #define GETCHARTEST(c, eptr) c = *eptr; #define GETCHARINC(c, eptr) c = *eptr++; @@ -421,14 +548,36 @@ #define GETCHARLEN(c, eptr, len) c = *eptr; /* #define GETCHARLENTEST(c, eptr, len) */ /* #define BACKCHAR(eptr) */ +/* #define FORWARDCHAR(eptr) */ +/* #define ACROSSCHAR(condition, eptr, action) */ -#else /* SUPPORT_UTF8 */ +#else /* SUPPORT_UTF */ + +#ifdef COMPILE_PCRE8 /* These macros were originally written in the form of loops that used data -from the tables whose names start with _pcre_utf8_table. They were rewritten by +from the tables whose names start with PRIV(utf8_table). They were rewritten by a user so as not to use loops, because in some environments this gives a significant performance advantage, and it seems never to do any harm. */ +/* Tells the biggest code point which can be encoded as a single character. */ + +#define MAX_VALUE_FOR_SINGLE_CHAR 127 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) ((c) >= 0xc0) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) + +/* Returns TRUE, if the given character is not the first character +of a UTF sequence. */ + +#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80) + /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer. */ @@ -463,7 +612,7 @@ #define GETCHARTEST(c, eptr) \ c = *eptr; \ - if (utf8 && c >= 0xc0) GETUTF8(c, eptr); + if (utf && c >= 0xc0) GETUTF8(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, advancing the pointer. */ @@ -511,7 +660,7 @@ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ - if (utf8 && c >= 0xc0) GETUTF8INC(c, eptr); + if (utf && c >= 0xc0) GETUTF8INC(c, eptr); /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer, incrementing the length. */ @@ -563,7 +712,7 @@ #define GETCHARLENTEST(c, eptr, len) \ c = *eptr; \ - if (utf8 && c >= 0xc0) GETUTF8LEN(c, eptr, len); + if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro @@ -571,7 +720,116 @@ #define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr-- -#endif /* SUPPORT_UTF8 */ +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + while((condition) && ((eptr) & 0xc0) == 0x80) action + +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 + +/* Tells the biggest code point which can be encoded as a single character. */ + +#define MAX_VALUE_FOR_SINGLE_CHAR 65535 + +/* Tests whether the code point needs extra characters to decode. */ + +#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) 1 + +/* Returns TRUE, if the given character is not the first character +of a UTF sequence. */ + +#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00) + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer. */ + +#define GETUTF16(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, not advancing the pointer. This is called when +we know we are in UTF-16 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, advancing +the pointer. */ + +#define GETUTF16INC(c, eptr) \ + { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; } + +/* Get the next UTF-16 character, advancing the pointer. This is called when we +know we are in UTF-16 mode. */ + +#define GETCHARINC(c, eptr) \ + c = *eptr++; \ + if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Get the next character, testing for UTF-16 mode, and advancing the pointer. +This is called when we don't know if we are in UTF-16 mode. */ + +#define GETCHARINCTEST(c, eptr) \ + c = *eptr++; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr); + +/* Base macro to pick up the low surrogate of a UTF-16 character, not +advancing the pointer, incrementing the length. */ + +#define GETUTF16LEN(c, eptr, len) \ + { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; } + +/* Get the next UTF-16 character, not advancing the pointer, incrementing +length if there is a low surrogate. This is called when we know we are in +UTF-16 mode. */ + +#define GETCHARLEN(c, eptr, len) \ + c = *eptr; \ + if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the +pointer, incrementing length if there is a low surrogate. This is called when +we do not know if we are in UTF-16 mode. */ + +#define GETCHARLENTEST(c, eptr, len) \ + c = *eptr; \ + if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); + +/* If the pointer is not at the start of a character, move it back until +it is. This is called only in UTF-16 mode - we don't put a test within the +macro because almost all calls are already within a block of UTF-16 only +code. */ + +#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr-- + +/* Same as above, just in the other direction. */ +#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++ + +/* Same as above, but it allows a fully customizable form. */ +#define ACROSSCHAR(condition, eptr, action) \ + if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action + +#endif + +#endif /* COMPILE_PCRE8 */ + +#endif /* SUPPORT_UTF */ /* In case there is no definition of offsetof() provided - though any proper @@ -582,27 +840,32 @@ #endif -/* These are the public options that can change during matching. */ - -#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) - /* Private flags containing information about the compiled regex. They used to live at the top end of the options word, but that got almost full, so now they are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the restrictions on partial matching have been lifted. It remains for backwards compatibility. */ -#define PCRE_NOPARTIAL 0x0001 /* can't use partial with this regex */ -#define PCRE_FIRSTSET 0x0002 /* first_byte is set */ -#define PCRE_REQCHSET 0x0004 /* req_byte is set */ -#define PCRE_STARTLINE 0x0008 /* start after \n for multiline */ -#define PCRE_JCHANGED 0x0010 /* j option used in regex */ -#define PCRE_HASCRORLF 0x0020 /* explicit \r or \n in pattern */ +#ifdef COMPILE_PCRE8 +#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */ +#endif +#ifdef COMPILE_PCRE16 +#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */ +#endif +#define PCRE_FIRSTSET 0x0010 /* first_char is set */ +#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ +#define PCRE_REQCHSET 0x0040 /* req_byte is set */ +#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */ +#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */ +#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */ +#define PCRE_JCHANGED 0x0400 /* j option used in regex */ +#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ +#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ -/* Options for the "extra" block produced by pcre_study(). */ +/* Flags for the "extra" block produced by pcre_study(). */ -#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ -#define PCRE_STUDY_MINLEN 0x02 /* a minimum length field exists */ +#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */ +#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */ /* Masks for identifying the public options that are permitted at compile time, run time, or study time, respectively. */ @@ -628,13 +891,19 @@ PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \ PCRE_NO_START_OPTIMIZE) -#define PUBLIC_STUDY_OPTIONS 0 /* None defined */ +#define PUBLIC_STUDY_OPTIONS \ + (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \ + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) -/* Magic number to provide a small check against being handed junk. Also used -to detect whether a pattern was compiled on a host of different endianness. */ +/* Magic number to provide a small check against being handed junk. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ +/* This variable is used to detect a loaded regular expression +in different endianness. */ + +#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */ + /* Negative values for the firstchar and reqchar variables */ #define REQ_UNSET (-2) @@ -645,12 +914,6 @@ #define REQ_BYTE_MAX 1000 -/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a -variable-length repeat, or a anything other than literal characters. */ - -#define REQ_CASELESS 0x0100 /* indicates caselessness */ -#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */ - /* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in environments where these macros are defined elsewhere. Unfortunately, there is no way to do the same for the typedef. */ @@ -679,7 +942,7 @@ application that did need both could compile two versions of the library, using macros to give the functions distinct names. */ -#ifndef SUPPORT_UTF8 +#ifndef SUPPORT_UTF /* UTF-8 support is not enabled; use the platform-dependent character literals so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */ @@ -939,11 +1202,16 @@ #define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" #define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" #define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" -#define STRING_UTF8_RIGHTPAR "UTF8)" +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR "UTF8)" +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR "UTF16)" +#endif #define STRING_UCP_RIGHTPAR "UCP)" #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" -#else /* SUPPORT_UTF8 */ +#else /* SUPPORT_UTF */ /* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode @@ -1194,11 +1462,16 @@ #define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS -#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#endif #define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* Escape items that are just an encoding of a particular data value. */ @@ -1238,7 +1511,7 @@ #define PT_WORD 8 /* Word - L plus N plus underscore */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that -contain UTF-8 characters with values greater than 255. */ +contain characters with values greater than 255. */ #define XCL_NOT 0x01 /* Flag: this is a negative class */ #define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ @@ -1254,8 +1527,8 @@ their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL mode rather than an escape sequence. It is also -used for [^] in JavaScript compatibility mode. In non-DOTALL mode, "." behaves -like \N. +used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In +non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. when PCRE_UCP is set, when replacement of \d etc by \p sequences is required. @@ -1299,6 +1572,7 @@ OP_WHITESPACE, /* 9 \s */ OP_NOT_WORDCHAR, /* 10 \W */ OP_WORDCHAR, /* 11 \w */ + OP_ANY, /* 12 Match any character except newline */ OP_ALLANY, /* 13 Match any character */ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ @@ -1313,141 +1587,205 @@ OP_EODN, /* 23 End of data or \n at end of data: \Z. */ OP_EOD, /* 24 End of data: \z */ - OP_OPT, /* 25 Set runtime options */ - OP_CIRC, /* 26 Start of line - varies with multiline switch */ - OP_DOLL, /* 27 End of line - varies with multiline switch */ - OP_CHAR, /* 28 Match one character, casefully */ - OP_CHARNC, /* 29 Match one character, caselessly */ - OP_NOT, /* 30 Match one character, not the following one */ - - OP_STAR, /* 31 The maximizing and minimizing versions of */ - OP_MINSTAR, /* 32 these six opcodes must come in pairs, with */ - OP_PLUS, /* 33 the minimizing one second. */ - OP_MINPLUS, /* 34 This first set applies to single characters.*/ - OP_QUERY, /* 35 */ - OP_MINQUERY, /* 36 */ - - OP_UPTO, /* 37 From 0 to n matches */ - OP_MINUPTO, /* 38 */ - OP_EXACT, /* 39 Exactly n matches */ - - OP_POSSTAR, /* 40 Possessified star */ - OP_POSPLUS, /* 41 Possessified plus */ - OP_POSQUERY, /* 42 Posesssified query */ - OP_POSUPTO, /* 43 Possessified upto */ - - OP_NOTSTAR, /* 44 The maximizing and minimizing versions of */ - OP_NOTMINSTAR, /* 45 these six opcodes must come in pairs, with */ - OP_NOTPLUS, /* 46 the minimizing one second. They must be in */ - OP_NOTMINPLUS, /* 47 exactly the same order as those above. */ - OP_NOTQUERY, /* 48 This set applies to "not" single characters. */ - OP_NOTMINQUERY, /* 49 */ - - OP_NOTUPTO, /* 50 From 0 to n matches */ - OP_NOTMINUPTO, /* 51 */ - OP_NOTEXACT, /* 52 Exactly n matches */ - - OP_NOTPOSSTAR, /* 53 Possessified versions */ - OP_NOTPOSPLUS, /* 54 */ - OP_NOTPOSQUERY, /* 55 */ - OP_NOTPOSUPTO, /* 56 */ - - OP_TYPESTAR, /* 57 The maximizing and minimizing versions of */ - OP_TYPEMINSTAR, /* 58 these six opcodes must come in pairs, with */ - OP_TYPEPLUS, /* 59 the minimizing one second. These codes must */ - OP_TYPEMINPLUS, /* 60 be in exactly the same order as those above. */ - OP_TYPEQUERY, /* 61 This set applies to character types such as \d */ - OP_TYPEMINQUERY, /* 62 */ - - OP_TYPEUPTO, /* 63 From 0 to n matches */ - OP_TYPEMINUPTO, /* 64 */ - OP_TYPEEXACT, /* 65 Exactly n matches */ - - OP_TYPEPOSSTAR, /* 66 Possessified versions */ - OP_TYPEPOSPLUS, /* 67 */ - OP_TYPEPOSQUERY, /* 68 */ - OP_TYPEPOSUPTO, /* 69 */ - - OP_CRSTAR, /* 70 The maximizing and minimizing versions of */ - OP_CRMINSTAR, /* 71 all these opcodes must come in pairs, with */ - OP_CRPLUS, /* 72 the minimizing one second. These codes must */ - OP_CRMINPLUS, /* 73 be in exactly the same order as those above. */ - OP_CRQUERY, /* 74 These are for character classes and back refs */ - OP_CRMINQUERY, /* 75 */ - OP_CRRANGE, /* 76 These are different to the three sets above. */ - OP_CRMINRANGE, /* 77 */ - - OP_CLASS, /* 78 Match a character class, chars < 256 only */ - OP_NCLASS, /* 79 Same, but the bitmap was created from a negative - class - the difference is relevant only when a UTF-8 - character > 255 is encountered. */ - - OP_XCLASS, /* 80 Extended class for handling UTF-8 chars within the - class. This does both positive and negative. */ - - OP_REF, /* 81 Match a back reference */ - OP_RECURSE, /* 82 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 83 Call out to external function if provided */ - - OP_ALT, /* 84 Start of alternation */ - OP_KET, /* 85 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 86 These two must remain together and in this */ - OP_KETRMIN, /* 87 order. They are for groups the repeat for ever. */ - - /* The assertions must come before BRA, CBRA, ONCE, and COND.*/ - - OP_ASSERT, /* 88 Positive lookahead */ - OP_ASSERT_NOT, /* 89 Negative lookahead */ - OP_ASSERTBACK, /* 90 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 91 Negative lookbehind */ - OP_REVERSE, /* 92 Move pointer back - used in lookbehind assertions */ - - /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first, - as there's a test for >= ONCE for a subpattern that isn't an assertion. */ - - OP_ONCE, /* 93 Atomic group */ - OP_BRA, /* 94 Start of non-capturing bracket */ - OP_CBRA, /* 95 Start of capturing bracket */ - OP_COND, /* 96 Conditional group */ + OP_CIRC, /* 25 Start of line - not multiline */ + OP_CIRCM, /* 26 Start of line - multiline */ + OP_DOLL, /* 27 End of line - not multiline */ + OP_DOLLM, /* 28 End of line - multiline */ + OP_CHAR, /* 29 Match one character, casefully */ + OP_CHARI, /* 30 Match one character, caselessly */ + OP_NOT, /* 31 Match one character, not the given one, casefully */ + OP_NOTI, /* 32 Match one character, not the given one, caselessly */ + + /* The following sets of 13 opcodes must always be kept in step because + the offset from the first one is used to generate the others. */ + + /**** Single characters, caseful, must precede the caseless ones ****/ + + OP_STAR, /* 33 The maximizing and minimizing versions of */ + OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */ + OP_PLUS, /* 35 the minimizing one second. */ + OP_MINPLUS, /* 36 */ + OP_QUERY, /* 37 */ + OP_MINQUERY, /* 38 */ + + OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/ + OP_MINUPTO, /* 40 */ + OP_EXACT, /* 41 Exactly n matches */ + + OP_POSSTAR, /* 42 Possessified star, caseful */ + OP_POSPLUS, /* 43 Possessified plus, caseful */ + OP_POSQUERY, /* 44 Posesssified query, caseful */ + OP_POSUPTO, /* 45 Possessified upto, caseful */ + + /**** Single characters, caseless, must follow the caseful ones */ + + OP_STARI, /* 46 */ + OP_MINSTARI, /* 47 */ + OP_PLUSI, /* 48 */ + OP_MINPLUSI, /* 49 */ + OP_QUERYI, /* 50 */ + OP_MINQUERYI, /* 51 */ + + OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */ + OP_MINUPTOI, /* 53 */ + OP_EXACTI, /* 54 */ + + OP_POSSTARI, /* 55 Possessified star, caseless */ + OP_POSPLUSI, /* 56 Possessified plus, caseless */ + OP_POSQUERYI, /* 57 Posesssified query, caseless */ + OP_POSUPTOI, /* 58 Possessified upto, caseless */ + + /**** The negated ones must follow the non-negated ones, and match them ****/ + /**** Negated single character, caseful; must precede the caseless ones ****/ + + OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */ + OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */ + OP_NOTPLUS, /* 61 the minimizing one second. They must be in */ + OP_NOTMINPLUS, /* 62 exactly the same order as those above. */ + OP_NOTQUERY, /* 63 */ + OP_NOTMINQUERY, /* 64 */ + + OP_NOTUPTO, /* 65 From 0 to n matches, caseful */ + OP_NOTMINUPTO, /* 66 */ + OP_NOTEXACT, /* 67 Exactly n matches */ + + OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */ + OP_NOTPOSPLUS, /* 69 */ + OP_NOTPOSQUERY, /* 70 */ + OP_NOTPOSUPTO, /* 71 */ + + /**** Negated single character, caseless; must follow the caseful ones ****/ + + OP_NOTSTARI, /* 72 */ + OP_NOTMINSTARI, /* 73 */ + OP_NOTPLUSI, /* 74 */ + OP_NOTMINPLUSI, /* 75 */ + OP_NOTQUERYI, /* 76 */ + OP_NOTMINQUERYI, /* 77 */ + + OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */ + OP_NOTMINUPTOI, /* 79 */ + OP_NOTEXACTI, /* 80 Exactly n matches */ + + OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */ + OP_NOTPOSPLUSI, /* 82 */ + OP_NOTPOSQUERYI, /* 83 */ + OP_NOTPOSUPTOI, /* 84 */ + + /**** Character types ****/ + + OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */ + OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */ + OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */ + OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */ + OP_TYPEQUERY, /* 89 */ + OP_TYPEMINQUERY, /* 90 */ + + OP_TYPEUPTO, /* 91 From 0 to n matches */ + OP_TYPEMINUPTO, /* 92 */ + OP_TYPEEXACT, /* 93 Exactly n matches */ + + OP_TYPEPOSSTAR, /* 94 Possessified versions */ + OP_TYPEPOSPLUS, /* 95 */ + OP_TYPEPOSQUERY, /* 96 */ + OP_TYPEPOSUPTO, /* 97 */ + + /* These are used for character classes and back references; only the + first six are the same as the sets above. */ + + OP_CRSTAR, /* 98 The maximizing and minimizing versions of */ + OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */ + OP_CRPLUS, /* 100 the minimizing one second. These codes must */ + OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */ + OP_CRQUERY, /* 102 */ + OP_CRMINQUERY, /* 103 */ + + OP_CRRANGE, /* 104 These are different to the three sets above. */ + OP_CRMINRANGE, /* 105 */ + + /* End of quantifier opcodes */ + + OP_CLASS, /* 106 Match a character class, chars < 256 only */ + OP_NCLASS, /* 107 Same, but the bitmap was created from a negative + class - the difference is relevant only when a + character > 255 is encountered. */ + OP_XCLASS, /* 108 Extended class for handling > 255 chars within the + class. This does both positive and negative. */ + OP_REF, /* 109 Match a back reference, casefully */ + OP_REFI, /* 110 Match a back reference, caselessly */ + OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 112 Call out to external function if provided */ + + OP_ALT, /* 113 Start of alternation */ + OP_KET, /* 114 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 115 These two must remain together and in this */ + OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 117 Possessive unlimited repeat. */ + + /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four + asserts must remain in order. */ + + OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */ + OP_ASSERT, /* 119 Positive lookahead */ + OP_ASSERT_NOT, /* 120 Negative lookahead */ + OP_ASSERTBACK, /* 121 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */ + + /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately + after the assertions, with ONCE first, as there's a test for >= ONCE for a + subpattern that isn't an assertion. The POS versions must immediately follow + the non-POS versions in each case. */ + + OP_ONCE, /* 123 Atomic group, contains captures */ + OP_ONCE_NC, /* 124 Atomic group containing no captures */ + OP_BRA, /* 125 Start of non-capturing bracket */ + OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 127 Start of capturing bracket */ + OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 129 Conditional group */ - /* These three must follow the previous three, in the same order. There's a + /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 97 Start of non-capturing bracket, check empty */ - OP_SCBRA, /* 98 Start of capturing bracket, check empty */ - OP_SCOND, /* 99 Conditional group, check empty */ + OP_SBRA, /* 130 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 132 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 134 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 100 Used to hold a capture number as condition */ - OP_NCREF, /* 101 Same, but generaged by a name reference*/ - OP_RREF, /* 102 Used to hold a recursion number as condition */ - OP_NRREF, /* 103 Same, but generaged by a name reference*/ - OP_DEF, /* 104 The DEFINE condition */ - - OP_BRAZERO, /* 105 These two must remain together and in this */ - OP_BRAMINZERO, /* 106 order. */ + OP_CREF, /* 135 Used to hold a capture number as condition */ + OP_NCREF, /* 136 Same, but generated by a name reference*/ + OP_RREF, /* 137 Used to hold a recursion number as condition */ + OP_NRREF, /* 138 Same, but generated by a name reference*/ + OP_DEF, /* 139 The DEFINE condition */ + + OP_BRAZERO, /* 140 These two must remain together and in this */ + OP_BRAMINZERO, /* 141 order. */ + OP_BRAPOSZERO, /* 142 */ /* These are backtracking control verbs */ - OP_MARK, /* 107 always has an argument */ - OP_PRUNE, /* 108 */ - OP_PRUNE_ARG, /* 109 same, but with argument */ - OP_SKIP, /* 110 */ - OP_SKIP_ARG, /* 111 same, but with argument */ - OP_THEN, /* 112 */ - OP_THEN_ARG, /* 113 same, but with argument */ - OP_COMMIT, /* 114 */ + OP_MARK, /* 143 always has an argument */ + OP_PRUNE, /* 144 */ + OP_PRUNE_ARG, /* 145 same, but with argument */ + OP_SKIP, /* 146 */ + OP_SKIP_ARG, /* 147 same, but with argument */ + OP_THEN, /* 148 */ + OP_THEN_ARG, /* 149 same, but with argument */ + OP_COMMIT, /* 150 */ /* These are forced failure and success verbs */ - OP_FAIL, /* 115 */ - OP_ACCEPT, /* 116 */ - OP_CLOSE, /* 117 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 151 */ + OP_ACCEPT, /* 152 */ + OP_ASSERT_ACCEPT, /* 153 Used inside assertions */ + OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 118 */ + OP_SKIPZERO, /* 155 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1462,29 +1800,45 @@ /* This macro defines textual names for all the opcodes. These are used only -for debugging. The macro is referenced only in pcre_printint.c. */ +for debugging, and some of them are only partial names. The macro is referenced +only in pcre_printint.c, which fills out the full names in many cases (and in +some cases doesn't actually use these names at all). */ #define OP_NAME_LIST \ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \ "extuni", "\\Z", "\\z", \ - "Opt", "^", "$", "char", "charnc", "not", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "^", "^", "$", "$", "char", "chari", "not", "noti", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ "*+","++", "?+", "{", \ - "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ + "*+","++", "?+", "{", \ + "*", "*?", "+", "+?", "?", "??", \ + "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ - "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \ - "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \ - "AssertB", "AssertB not", "Reverse", \ - "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond", \ + "class", "nclass", "xclass", "Ref", "Refi", \ + "Recurse", "Callout", \ + "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ + "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ + "Once", "Once_NC", \ + "Bra", "BraPos", "CBra", "CBraPos", \ + "Cond", \ + "SBra", "SBraPos", "SCBra", "SCBraPos", \ + "SCond", \ "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \ - "Brazero", "Braminzero", \ + "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ - "*THEN", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT", \ + "*THEN", "*THEN", "*COMMIT", "*FAIL", \ + "*ACCEPT", "*ASSERT_ACCEPT", \ "Close", "Skip zero" @@ -1505,56 +1859,75 @@ 3, 3, /* \P, \p */ \ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \ 1, /* \X */ \ - 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \ + 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \ 2, /* Char - the minimum length */ \ - 2, /* Charnc - the minimum length */ \ + 2, /* Chari - the minimum length */ \ 2, /* not */ \ - /* Positive single-char repeats ** These are */ \ - 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ - 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \ - 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \ + 2, /* noti */ \ + /* Positive single-char repeats ** These are */ \ + 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \ + 2+IMM2_SIZE, /* exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \ + 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \ + 2+IMM2_SIZE, /* exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \ /* Negative single-char repeats - only for chars < 256 */ \ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ - 4, 4, 4, /* NOT upto, minupto, exact */ \ - 2, 2, 2, 4, /* Possessive *, +, ?, upto */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \ + 2+IMM2_SIZE, /* NOT exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \ + 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \ + 2+IMM2_SIZE, /* NOT exact I */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ - 4, 4, 4, /* Type upto, minupto, exact */ \ - 2, 2, 2, 4, /* Possessive *+, ++, ?+, upto+ */ \ + 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \ + 2+IMM2_SIZE, /* Type exact */ \ + 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ - 5, 5, /* CRRANGE, CRMINRANGE */ \ - 33, /* CLASS */ \ - 33, /* NCLASS */ \ + 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \ + 1+(32/sizeof(pcre_uchar)), /* CLASS */ \ + 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ - 3, /* REF */ \ + 1+IMM2_SIZE, /* REF */ \ + 1+IMM2_SIZE, /* REFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ 1+LINK_SIZE, /* Ket */ \ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ + 1+LINK_SIZE, /* KetRpos */ \ + 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ - 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* ONCE */ \ + 1+LINK_SIZE, /* ONCE_NC */ \ 1+LINK_SIZE, /* BRA */ \ - 3+LINK_SIZE, /* CBRA */ \ + 1+LINK_SIZE, /* BRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \ 1+LINK_SIZE, /* COND */ \ 1+LINK_SIZE, /* SBRA */ \ - 3+LINK_SIZE, /* SCBRA */ \ + 1+LINK_SIZE, /* SBRAPOS */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \ + 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \ 1+LINK_SIZE, /* SCOND */ \ - 3, 3, /* CREF, NCREF */ \ - 3, 3, /* RREF, NRREF */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \ + 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \ 1, /* DEF */ \ - 1, 1, /* BRAZERO, BRAMINZERO */ \ + 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ 1, 3, /* SKIP, SKIP_ARG */ \ - 1+LINK_SIZE, 3+LINK_SIZE, /* THEN, THEN_ARG */ \ - 1, 1, 1, 3, 1 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */ - + 1, 3, /* THEN, THEN_ARG */ \ + 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ + 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */ /* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion" condition. */ @@ -1571,8 +1944,12 @@ ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, - ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, - ERRCOUNT }; + ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, + ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERRCOUNT }; + +/* JIT compiling modes. The function list is indexed by them. */ +enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE, + JIT_NUMBER_OF_COMPILE_MODES }; /* The real format of the start of the pcre block; the index of names and the code vector run on as long as necessary after the end. We store an explicit @@ -1591,24 +1968,29 @@ NOTE NOTE NOTE */ -typedef struct real_pcre { +#ifdef COMPILE_PCRE8 +#define REAL_PCRE real_pcre +#else +#define REAL_PCRE real_pcre16 +#endif + +typedef struct REAL_PCRE { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ pcre_uint16 flags; /* Private flags */ - pcre_uint16 dummy1; /* For future use */ - pcre_uint16 top_bracket; - pcre_uint16 top_backref; - pcre_uint16 first_byte; - pcre_uint16 req_byte; + pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ + pcre_uint16 top_bracket; /* Highest numbered group */ + pcre_uint16 top_backref; /* Highest numbered back reference */ + pcre_uint16 first_char; /* Starting character */ + pcre_uint16 req_char; /* This character must be seen */ pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 ref_count; /* Reference count */ - - const unsigned char *tables; /* Pointer to tables or NULL for std */ - const unsigned char *nullpad; /* NULL padding */ -} real_pcre; + const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ + const pcre_uint8 *nullpad; /* NULL padding */ +} REAL_PCRE; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ @@ -1616,7 +1998,7 @@ typedef struct pcre_study_data { pcre_uint32 size; /* Total that was malloced */ pcre_uint32 flags; /* Private flags */ - uschar start_bits[32]; /* Starting char bits */ + pcre_uint8 start_bits[32]; /* Starting char bits */ pcre_uint32 minlength; /* Minimum subject length */ } pcre_study_data; @@ -1635,60 +2017,71 @@ doing the compiling, so that they are thread-safe. */ typedef struct compile_data { - const uschar *lcc; /* Points to lower casing table */ - const uschar *fcc; /* Points to case-flipping table */ - const uschar *cbits; /* Points to character type table */ - const uschar *ctypes; /* Points to table of type maps */ - const uschar *start_workspace;/* The start of working space */ - const uschar *start_code; /* The start of the compiled code */ - const uschar *start_pattern; /* The start of the pattern */ - const uschar *end_pattern; /* The end of the pattern */ - open_capitem *open_caps; /* Chain of open capture items */ - uschar *hwm; /* High watermark of workspace */ - uschar *name_table; /* The name/number table */ - int names_found; /* Number of entries so far */ - int name_entry_size; /* Size of each entry */ - int bracount; /* Count of capturing parens as we compile */ - int final_bracount; /* Saved value after first pass */ - int top_backref; /* Maximum back reference */ - unsigned int backref_map; /* Bitmap of low back refs */ - int external_options; /* External (initial) options */ - int external_flags; /* External flag bits to be set */ - int req_varyopt; /* "After variable item" flag for reqbyte */ - BOOL had_accept; /* (*ACCEPT) encountered */ - BOOL check_lookbehind; /* Lookbehinds need later checking */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - uschar nl[4]; /* Newline string when fixed length */ + const pcre_uint8 *lcc; /* Points to lower casing table */ + const pcre_uint8 *fcc; /* Points to case-flipping table */ + const pcre_uint8 *cbits; /* Points to character type table */ + const pcre_uint8 *ctypes; /* Points to table of type maps */ + const pcre_uchar *start_workspace;/* The start of working space */ + const pcre_uchar *start_code; /* The start of the compiled code */ + const pcre_uchar *start_pattern; /* The start of the pattern */ + const pcre_uchar *end_pattern; /* The end of the pattern */ + open_capitem *open_caps; /* Chain of open capture items */ + pcre_uchar *hwm; /* High watermark of workspace */ + pcre_uchar *name_table; /* The name/number table */ + int names_found; /* Number of entries so far */ + int name_entry_size; /* Size of each entry */ + int workspace_size; /* Size of workspace */ + int bracount; /* Count of capturing parens as we compile */ + int final_bracount; /* Saved value after first pass */ + int max_lookbehind; /* Maximum lookbehind (characters) */ + int top_backref; /* Maximum back reference */ + unsigned int backref_map; /* Bitmap of low back refs */ + int assert_depth; /* Depth of nested assertions */ + int external_options; /* External (initial) options */ + int external_flags; /* External flag bits to be set */ + int req_varyopt; /* "After variable item" flag for reqbyte */ + BOOL had_accept; /* (*ACCEPT) encountered */ + BOOL check_lookbehind; /* Lookbehinds need later checking */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + pcre_uchar nl[4]; /* Newline string when fixed length */ } compile_data; /* Structure for maintaining a chain of pointers to the currently incomplete -branches, for testing for left recursion. */ +branches, for testing for left recursion while compiling. */ typedef struct branch_chain { struct branch_chain *outer; - uschar *current_branch; + pcre_uchar *current_branch; } branch_chain; /* Structure for items in a linked list that represents an explicit recursive -call within the pattern. */ +call within the pattern; used by pcre_exec(). */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ - int group_num; /* Number of group that was called */ - const uschar *after_call; /* "Return value": points after the call in the expr */ - int *offset_save; /* Pointer to start of saved offsets */ - int saved_max; /* Number of saved offsets */ - int save_offset_top; /* Current value of offset_top */ + int group_num; /* Number of group that was called */ + int *offset_save; /* Pointer to start of saved offsets */ + int saved_max; /* Number of saved offsets */ + PCRE_PUCHAR subject_position; /* Position at start of recursion */ } recursion_info; +/* A similar structure for pcre_dfa_exec(). */ + +typedef struct dfa_recursion_info { + struct dfa_recursion_info *prevrec; + int group_num; + PCRE_PUCHAR subject_position; +} dfa_recursion_info; + /* Structure for building a chain of data for holding the values of the subject pointer at the start of each subpattern, so as to detect when an empty string -has been matched by a subpattern - to break infinite loops. */ +has been matched by a subpattern - to break infinite loops; used by +pcre_exec(). */ typedef struct eptrblock { struct eptrblock *epb_prev; - USPTR epb_saved_eptr; + PCRE_PUCHAR epb_saved_eptr; } eptrblock; @@ -1699,61 +2092,71 @@ unsigned long int match_call_count; /* As it says */ unsigned long int match_limit; /* As it says */ unsigned long int match_limit_recursion; /* As it says */ - int *offset_vector; /* Offset vector */ - int offset_end; /* One past the end */ - int offset_max; /* The maximum usable for return data */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - int name_count; /* Number of names in name table */ - int name_entry_size; /* Size of entry in names table */ - uschar *name_table; /* Table of names */ - uschar nl[4]; /* Newline string when fixed */ - const uschar *lcc; /* Points to lower casing table */ - const uschar *ctypes; /* Points to table of type maps */ - BOOL offset_overflow; /* Set if too many extractions */ - BOOL notbol; /* NOTBOL flag */ - BOOL noteol; /* NOTEOL flag */ - BOOL utf8; /* UTF8 flag */ - BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */ - BOOL use_ucp; /* PCRE_UCP flag */ - BOOL endonly; /* Dollar not before final \n */ - BOOL notempty; /* Empty string match not wanted */ - BOOL notempty_atstart; /* Empty string match at start not wanted */ - BOOL hitend; /* Hit the end of the subject at some point */ - BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ - const uschar *start_code; /* For use when recursing */ - USPTR start_subject; /* Start of the subject string */ - USPTR end_subject; /* End of the subject string */ - USPTR start_match_ptr; /* Start of matched string */ - USPTR end_match_ptr; /* Subject position at end match */ - USPTR start_used_ptr; /* Earliest consulted character */ - int partial; /* PARTIAL options */ - int end_offset_top; /* Highwater mark at end of match */ - int capture_last; /* Most recent capture number */ - int start_offset; /* The start offset value */ - eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ - int eptrn; /* Next free eptrblock */ - recursion_info *recursive; /* Linked list of recursion data */ - void *callout_data; /* To pass back to callouts */ - const uschar *mark; /* Mark pointer to pass back */ + int *offset_vector; /* Offset vector */ + int offset_end; /* One past the end */ + int offset_max; /* The maximum usable for return data */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + int name_count; /* Number of names in name table */ + int name_entry_size; /* Size of entry in names table */ + pcre_uchar *name_table; /* Table of names */ + pcre_uchar nl[4]; /* Newline string when fixed */ + const pcre_uint8 *lcc; /* Points to lower casing table */ + const pcre_uint8 *fcc; /* Points to case-flipping table */ + const pcre_uint8 *ctypes; /* Points to table of type maps */ + BOOL offset_overflow; /* Set if too many extractions */ + BOOL notbol; /* NOTBOL flag */ + BOOL noteol; /* NOTEOL flag */ + BOOL utf; /* UTF-8 / UTF-16 flag */ + BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */ + BOOL use_ucp; /* PCRE_UCP flag */ + BOOL endonly; /* Dollar not before final \n */ + BOOL notempty; /* Empty string match not wanted */ + BOOL notempty_atstart; /* Empty string match at start not wanted */ + BOOL hitend; /* Hit the end of the subject at some point */ + BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */ + BOOL hasthen; /* Pattern contains (*THEN) */ + BOOL ignore_skip_arg; /* For re-run when SKIP name not found */ + const pcre_uchar *start_code; /* For use when recursing */ + PCRE_PUCHAR start_subject; /* Start of the subject string */ + PCRE_PUCHAR end_subject; /* End of the subject string */ + PCRE_PUCHAR start_match_ptr; /* Start of matched string */ + PCRE_PUCHAR end_match_ptr; /* Subject position at end match */ + PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */ + int partial; /* PARTIAL options */ + int end_offset_top; /* Highwater mark at end of match */ + int capture_last; /* Most recent capture number */ + int start_offset; /* The start offset value */ + int match_function_type; /* Set for certain special calls of MATCH() */ + eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */ + int eptrn; /* Next free eptrblock */ + recursion_info *recursive; /* Linked list of recursion data */ + void *callout_data; /* To pass back to callouts */ + const pcre_uchar *mark; /* Mark pointer to pass back on success */ + const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */ + const pcre_uchar *once_target; /* Where to back up to for atomic groups */ +#ifdef NO_RECURSE + void *match_frames_base; /* For remembering malloc'd frames */ +#endif } match_data; /* A similar structure is used for the same purpose by the DFA matching functions. */ typedef struct dfa_match_data { - const uschar *start_code; /* Start of the compiled pattern */ - const uschar *start_subject; /* Start of the subject string */ - const uschar *end_subject; /* End of subject string */ - const uschar *start_used_ptr; /* Earliest consulted character */ - const uschar *tables; /* Character tables */ - int start_offset; /* The start offset value */ - int moptions; /* Match options */ - int poptions; /* Pattern options */ - int nltype; /* Newline type */ - int nllen; /* Newline string length */ - uschar nl[4]; /* Newline string when fixed */ - void *callout_data; /* To pass back to callouts */ + const pcre_uchar *start_code; /* Start of the compiled pattern */ + const pcre_uchar *start_subject ; /* Start of the subject string */ + const pcre_uchar *end_subject; /* End of subject string */ + const pcre_uchar *start_used_ptr; /* Earliest consulted character */ + const pcre_uint8 *tables; /* Character tables */ + int start_offset; /* The start offset value */ + int moptions; /* Match options */ + int poptions; /* Pattern options */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ + pcre_uchar nl[4]; /* Newline string when fixed */ + void *callout_data; /* To pass back to callouts */ + dfa_recursion_info *recursive; /* Linked list of recursion data */ } dfa_match_data; /* Bit definitions for entries in the pcre_ctypes table. */ @@ -1789,6 +2192,28 @@ #define ctypes_offset (cbits_offset + cbit_length) #define tables_length (ctypes_offset + 256) +/* Internal function and data prefixes. */ + +#ifdef COMPILE_PCRE8 +#ifndef PUBL +#define PUBL(name) pcre_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre_##name +#endif +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 +#ifndef PUBL +#define PUBL(name) pcre16_##name +#endif +#ifndef PRIV +#define PRIV(name) _pcre16_##name +#endif +#else +#error Unsupported compiling mode +#endif /* COMPILE_PCRE16 */ +#endif /* COMPILE_PCRE8 */ + /* Layout of the UCP type table that translates property names into types and codes. Each entry used to point directly to a name, but to reduce the number of relocations in shared libraries, it now has an offset into a single string @@ -1806,62 +2231,116 @@ but are not part of the PCRE public API. The data for these tables is in the pcre_tables.c module. */ -extern const int _pcre_utf8_table1[]; -extern const int _pcre_utf8_table2[]; -extern const int _pcre_utf8_table3[]; -extern const uschar _pcre_utf8_table4[]; +#ifdef COMPILE_PCRE8 + +extern const int PRIV(utf8_table1)[]; +extern const int PRIV(utf8_table1_size); +extern const int PRIV(utf8_table2)[]; +extern const int PRIV(utf8_table3)[]; +extern const pcre_uint8 PRIV(utf8_table4)[]; -extern const int _pcre_utf8_table1_size; +#endif /* COMPILE_PCRE8 */ -extern const char _pcre_utt_names[]; -extern const ucp_type_table _pcre_utt[]; -extern const int _pcre_utt_size; +extern const char PRIV(utt_names)[]; +extern const ucp_type_table PRIV(utt)[]; +extern const int PRIV(utt_size); -extern const uschar _pcre_default_tables[]; +extern const pcre_uint8 PRIV(default_tables)[]; -extern const uschar _pcre_OP_lengths[]; +extern const pcre_uint8 PRIV(OP_lengths)[]; /* Internal shared functions. These are functions that are used by more than one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. */ -extern const uschar *_pcre_find_bracket(const uschar *, BOOL, int); -extern BOOL _pcre_is_newline(USPTR, int, USPTR, int *, BOOL); -extern int _pcre_ord2utf8(int, uschar *); -extern real_pcre *_pcre_try_flipped(const real_pcre *, real_pcre *, - const pcre_study_data *, pcre_study_data *); -extern int _pcre_valid_utf8(USPTR, int); -extern BOOL _pcre_was_newline(USPTR, int, USPTR, int *, BOOL); -extern BOOL _pcre_xclass(int, const uschar *); +/* String comparison functions. */ +#ifdef COMPILE_PCRE8 + +#define STRCMP_UC_UC(str1, str2) \ + strcmp((char *)(str1), (char *)(str2)) +#define STRCMP_UC_C8(str1, str2) \ + strcmp((char *)(str1), (str2)) +#define STRNCMP_UC_UC(str1, str2, num) \ + strncmp((char *)(str1), (char *)(str2), (num)) +#define STRNCMP_UC_C8(str1, str2, num) \ + strncmp((char *)(str1), (str2), (num)) +#define STRLEN_UC(str) strlen((const char *)str) + +#else +extern int PRIV(strcmp_uc_uc)(const pcre_uchar *, + const pcre_uchar *); +extern int PRIV(strcmp_uc_c8)(const pcre_uchar *, + const char *); +extern int PRIV(strncmp_uc_uc)(const pcre_uchar *, + const pcre_uchar *, unsigned int num); +extern int PRIV(strncmp_uc_c8)(const pcre_uchar *, + const char *, unsigned int num); +extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str); + +#define STRCMP_UC_UC(str1, str2) \ + PRIV(strcmp_uc_uc)((str1), (str2)) +#define STRCMP_UC_C8(str1, str2) \ + PRIV(strcmp_uc_c8)((str1), (str2)) +#define STRNCMP_UC_UC(str1, str2, num) \ + PRIV(strncmp_uc_uc)((str1), (str2), (num)) +#define STRNCMP_UC_C8(str1, str2, num) \ + PRIV(strncmp_uc_c8)((str1), (str2), (num)) +#define STRLEN_UC(str) PRIV(strlen_uc)(str) + +#endif /* COMPILE_PCRE8 */ + +extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int); +extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, + int *, BOOL); +extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *); +extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *); +extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, + int *, BOOL); +extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL); + +#ifdef SUPPORT_JIT +extern void PRIV(jit_compile)(const REAL_PCRE *, + PUBL(extra) *, int); +extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *, + const pcre_uchar *, int, int, int, int *, int); +extern void PRIV(jit_free)(void *); +extern int PRIV(jit_get_size)(void *); +extern const char* PRIV(jit_get_target)(void); +#endif /* Unicode character database (UCD) */ typedef struct { - uschar script; - uschar chartype; + pcre_uint8 script; + pcre_uint8 chartype; pcre_int32 other_case; } ucd_record; -extern const ucd_record _pcre_ucd_records[]; -extern const uschar _pcre_ucd_stage1[]; -extern const pcre_uint16 _pcre_ucd_stage2[]; -extern const int _pcre_ucp_gentype[]; - +extern const ucd_record PRIV(ucd_records)[]; +extern const pcre_uint8 PRIV(ucd_stage1)[]; +extern const pcre_uint16 PRIV(ucd_stage2)[]; +extern const int PRIV(ucp_gentype)[]; +#ifdef SUPPORT_JIT +extern const int PRIV(ucp_typerange)[]; +#endif +#ifdef SUPPORT_UCP /* UCD access macros */ #define UCD_BLOCK_SIZE 128 -#define GET_UCD(ch) (_pcre_ucd_records + \ - _pcre_ucd_stage2[_pcre_ucd_stage1[(ch) / UCD_BLOCK_SIZE] * \ - UCD_BLOCK_SIZE + ch % UCD_BLOCK_SIZE]) +#define GET_UCD(ch) (PRIV(ucd_records) + \ + PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \ + UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE]) #define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype #define UCD_SCRIPT(ch) GET_UCD(ch)->script -#define UCD_CATEGORY(ch) _pcre_ucp_gentype[UCD_CHARTYPE(ch)] +#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] #define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case) +#endif /* SUPPORT_UCP */ + #endif /* End of pcre_internal.h */ diff -Nru pcre3-8.12/pcre_jit_compile.c pcre3-8.31/pcre_jit_compile.c --- pcre3-8.12/pcre_jit_compile.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre_jit_compile.c 2012-06-17 16:04:44.000000000 +0000 @@ -0,0 +1,7454 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + + The machine code generator part (this module) was written by Zoltan Herczeg + Copyright (c) 2010-2012 + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + +#ifdef SUPPORT_JIT + +/* All-in-one: Since we use the JIT compiler only from here, +we just include it. This way we don't need to touch the build +system files. */ + +#define SLJIT_MALLOC(size) (PUBL(malloc))(size) +#define SLJIT_FREE(ptr) (PUBL(free))(ptr) +#define SLJIT_CONFIG_AUTO 1 +#define SLJIT_CONFIG_STATIC 1 +#define SLJIT_VERBOSE 0 +#define SLJIT_DEBUG 0 + +#include "sljit/sljitLir.c" + +#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED +#error Unsupported architecture +#endif + +/* Allocate memory on the stack. Fast, but limited size. */ +#define LOCAL_SPACE_SIZE 32768 + +#define STACK_GROWTH_RATE 8192 + +/* Enable to check that the allocation could destroy temporaries. */ +#if defined SLJIT_DEBUG && SLJIT_DEBUG +#define DESTROY_REGISTERS 1 +#endif + +/* +Short summary about the backtracking mechanism empolyed by the jit code generator: + +The code generator follows the recursive nature of the PERL compatible regular +expressions. The basic blocks of regular expressions are condition checkers +whose execute different commands depending on the result of the condition check. +The relationship between the operators can be horizontal (concatenation) and +vertical (sub-expression) (See struct backtrack_common for more details). + + 'ab' - 'a' and 'b' regexps are concatenated + 'a+' - 'a' is the sub-expression of the '+' operator + +The condition checkers are boolean (true/false) checkers. Machine code is generated +for the checker itself and for the actions depending on the result of the checker. +The 'true' case is called as the try path (expected path), and the other is called as +the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken +branches on the try path. + + Greedy star operator (*) : + Try path: match happens. + Backtrack path: match failed. + Non-greedy star operator (*?) : + Try path: no need to perform a match. + Backtrack path: match is required. + +The following example shows how the code generated for a capturing bracket +with two alternatives. Let A, B, C, D are arbirary regular expressions, and +we have the following regular expression: + + A(B|C)D + +The generated code will be the following: + + A try path + '(' try path (pushing arguments to the stack) + B try path + ')' try path (pushing arguments to the stack) + D try path + return with successful match + + D backtrack path + ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") + B backtrack path + C expected path + jump to D try path + C backtrack path + A backtrack path + + Notice, that the order of backtrack code paths are the opposite of the fast + code paths. In this way the topmost value on the stack is always belong + to the current backtrack code path. The backtrack path must check + whether there is a next alternative. If so, it needs to jump back to + the try path eventually. Otherwise it needs to clear out its own stack + frame and continue the execution on the backtrack code paths. +*/ + +/* +Saved stack frames: + +Atomic blocks and asserts require reloading the values of local variables +when the backtrack mechanism performed. Because of OP_RECURSE, the locals +are not necessarly known in compile time, thus we need a dynamic restore +mechanism. + +The stack frames are stored in a chain list, and have the following format: +([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] + +Thus we can restore the locals to a particular point in the stack. +*/ + +typedef struct jit_arguments { + /* Pointers first. */ + struct sljit_stack *stack; + const pcre_uchar *str; + const pcre_uchar *begin; + const pcre_uchar *end; + int *offsets; + pcre_uchar *uchar_ptr; + pcre_uchar *mark_ptr; + /* Everything else after. */ + int offsetcount; + int calllimit; + pcre_uint8 notbol; + pcre_uint8 noteol; + pcre_uint8 notempty; + pcre_uint8 notempty_atstart; +} jit_arguments; + +typedef struct executable_functions { + void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; + PUBL(jit_callback) callback; + void *userdata; + sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; +} executable_functions; + +typedef struct jump_list { + struct sljit_jump *jump; + struct jump_list *next; +} jump_list; + +enum stub_types { stack_alloc }; + +typedef struct stub_list { + enum stub_types type; + int data; + struct sljit_jump *start; + struct sljit_label *leave; + struct stub_list *next; +} stub_list; + +typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); + +/* The following structure is the key data type for the recursive +code generator. It is allocated by compile_trypath, and contains +the aguments for compile_backtrackpath. Must be the first member +of its descendants. */ +typedef struct backtrack_common { + /* Concatenation stack. */ + struct backtrack_common *prev; + jump_list *nextbacktracks; + /* Internal stack (for component operators). */ + struct backtrack_common *top; + jump_list *topbacktracks; + /* Opcode pointer. */ + pcre_uchar *cc; +} backtrack_common; + +typedef struct assert_backtrack { + backtrack_common common; + jump_list *condfailed; + /* Less than 0 (-1) if a frame is not needed. */ + int framesize; + /* Points to our private memory word on the stack. */ + int localptr; + /* For iterators. */ + struct sljit_label *trypath; +} assert_backtrack; + +typedef struct bracket_backtrack { + backtrack_common common; + /* Where to coninue if an alternative is successfully matched. */ + struct sljit_label *alttrypath; + /* For rmin and rmax iterators. */ + struct sljit_label *recursivetrypath; + /* For greedy ? operator. */ + struct sljit_label *zerotrypath; + /* Contains the branches of a failed condition. */ + union { + /* Both for OP_COND, OP_SCOND. */ + jump_list *condfailed; + assert_backtrack *assert; + /* For OP_ONCE. -1 if not needed. */ + int framesize; + } u; + /* Points to our private memory word on the stack. */ + int localptr; +} bracket_backtrack; + +typedef struct bracketpos_backtrack { + backtrack_common common; + /* Points to our private memory word on the stack. */ + int localptr; + /* Reverting stack is needed. */ + int framesize; + /* Allocated stack size. */ + int stacksize; +} bracketpos_backtrack; + +typedef struct braminzero_backtrack { + backtrack_common common; + struct sljit_label *trypath; +} braminzero_backtrack; + +typedef struct iterator_backtrack { + backtrack_common common; + /* Next iteration. */ + struct sljit_label *trypath; +} iterator_backtrack; + +typedef struct recurse_entry { + struct recurse_entry *next; + /* Contains the function entry. */ + struct sljit_label *entry; + /* Collects the calls until the function is not created. */ + jump_list *calls; + /* Points to the starting opcode. */ + int start; +} recurse_entry; + +typedef struct recurse_backtrack { + backtrack_common common; +} recurse_backtrack; + +typedef struct compiler_common { + struct sljit_compiler *compiler; + pcre_uchar *start; + + /* Opcode local area direct map. */ + int *localptrs; + int cbraptr; + /* OVector starting point. Must be divisible by 2. */ + int ovector_start; + /* Last known position of the requested byte. */ + int req_char_ptr; + /* Head of the last recursion. */ + int recursive_head; + /* First inspected character for partial matching. */ + int start_used_ptr; + /* Starting pointer for partial soft matches. */ + int hit_start; + /* End pointer of the first line. */ + int first_line_end; + /* Points to the marked string. */ + int mark_ptr; + + /* Other */ + const pcre_uint8 *fcc; + sljit_w lcc; + int mode; + int nltype; + int newline; + int bsr_nltype; + int endonly; + BOOL has_set_som; + sljit_w ctypes; + sljit_uw name_table; + sljit_w name_count; + sljit_w name_entry_size; + + /* Labels and jump lists. */ + struct sljit_label *partialmatchlabel; + struct sljit_label *leavelabel; + struct sljit_label *acceptlabel; + stub_list *stubs; + recurse_entry *entries; + recurse_entry *currententry; + jump_list *partialmatch; + jump_list *leave; + jump_list *accept; + jump_list *calllimit; + jump_list *stackalloc; + jump_list *revertframes; + jump_list *wordboundary; + jump_list *anynewline; + jump_list *hspace; + jump_list *vspace; + jump_list *casefulcmp; + jump_list *caselesscmp; + BOOL jscript_compat; +#ifdef SUPPORT_UTF + BOOL utf; +#ifdef SUPPORT_UCP + BOOL use_ucp; +#endif + jump_list *utfreadchar; +#ifdef COMPILE_PCRE8 + jump_list *utfreadtype8; +#endif +#endif /* SUPPORT_UTF */ +#ifdef SUPPORT_UCP + jump_list *getucd; +#endif +} compiler_common; + +/* For byte_sequence_compare. */ + +typedef struct compare_context { + int length; + int sourcereg; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + int ucharptr; + union { + sljit_i asint; + sljit_uh asushort; +#ifdef COMPILE_PCRE8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#else +#ifdef COMPILE_PCRE16 + sljit_uh asuchars[2]; +#endif +#endif + } c; + union { + sljit_i asint; + sljit_uh asushort; +#ifdef COMPILE_PCRE8 + sljit_ub asbyte; + sljit_ub asuchars[4]; +#else +#ifdef COMPILE_PCRE16 + sljit_uh asuchars[2]; +#endif +#endif + } oc; +#endif +} compare_context; + +enum { + frame_end = 0, + frame_setstrbegin = -1, + frame_setmark = -2 +}; + +/* Undefine sljit macros. */ +#undef CMP + +/* Used for accessing the elements of the stack. */ +#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) + +#define TMP1 SLJIT_TEMPORARY_REG1 +#define TMP2 SLJIT_TEMPORARY_REG3 +#define TMP3 SLJIT_TEMPORARY_EREG2 +#define STR_PTR SLJIT_SAVED_REG1 +#define STR_END SLJIT_SAVED_REG2 +#define STACK_TOP SLJIT_TEMPORARY_REG2 +#define STACK_LIMIT SLJIT_SAVED_REG3 +#define ARGUMENTS SLJIT_SAVED_EREG1 +#define CALL_COUNT SLJIT_SAVED_EREG2 +#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 + +/* Locals layout. */ +/* These two locals can be used by the current opcode. */ +#define LOCALS0 (0 * sizeof(sljit_w)) +#define LOCALS1 (1 * sizeof(sljit_w)) +/* Two local variables for possessive quantifiers (char1 cannot use them). */ +#define POSSESSIVE0 (2 * sizeof(sljit_w)) +#define POSSESSIVE1 (3 * sizeof(sljit_w)) +/* Max limit of recursions. */ +#define CALL_LIMIT (4 * sizeof(sljit_w)) +/* The output vector is stored on the stack, and contains pointers +to characters. The vector data is divided into two groups: the first +group contains the start / end character pointers, and the second is +the start pointers when the end of the capturing group has not yet reached. */ +#define OVECTOR_START (common->ovector_start) +#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) +#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) +#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) + +#ifdef COMPILE_PCRE8 +#define MOV_UCHAR SLJIT_MOV_UB +#define MOVU_UCHAR SLJIT_MOVU_UB +#else +#ifdef COMPILE_PCRE16 +#define MOV_UCHAR SLJIT_MOV_UH +#define MOVU_UCHAR SLJIT_MOVU_UH +#else +#error Unsupported compiling mode +#endif +#endif + +/* Shortcuts. */ +#define DEFINE_COMPILER \ + struct sljit_compiler *compiler = common->compiler +#define OP1(op, dst, dstw, src, srcw) \ + sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw)) +#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \ + sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w)) +#define LABEL() \ + sljit_emit_label(compiler) +#define JUMP(type) \ + sljit_emit_jump(compiler, (type)) +#define JUMPTO(type, label) \ + sljit_set_label(sljit_emit_jump(compiler, (type)), (label)) +#define JUMPHERE(jump) \ + sljit_set_label((jump), sljit_emit_label(compiler)) +#define CMP(type, src1, src1w, src2, src2w) \ + sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) +#define CMPTO(type, src1, src1w, src2, src2w, label) \ + sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) +#define COND_VALUE(op, dst, dstw, type) \ + sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) +#define GET_LOCAL_BASE(dst, dstw, offset) \ + sljit_get_local_base(compiler, (dst), (dstw), (offset)) + +static pcre_uchar* bracketend(pcre_uchar* cc) +{ +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +do cc += GET(cc, 1); while (*cc == OP_ALT); +SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); +cc += 1 + LINK_SIZE; +return cc; +} + +/* Functions whose might need modification for all new supported opcodes: + next_opcode + get_localspace + set_localptrs + get_framesize + init_frame + get_localsize + copy_locals + compile_trypath + compile_backtrackpath +*/ + +static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) +{ +SLJIT_UNUSED_ARG(common); +switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_DEF: + case OP_BRAZERO: + case OP_BRAMINZERO: + case OP_BRAPOSZERO: + case OP_COMMIT: + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_SKIPZERO: + return cc + 1; + + case OP_ANYBYTE: +#ifdef SUPPORT_UTF + if (common->utf) return NULL; +#endif + return cc + 1; + + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + return cc; + + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSUPTO: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSUPTOI: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSUPTO: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSUPTOI: + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + return cc; + + case OP_NOTPROP: + case OP_PROP: + return cc + 1 + 2; + + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSUPTO: + case OP_REF: + case OP_REFI: + case OP_CREF: + case OP_NCREF: + case OP_RREF: + case OP_NRREF: + case OP_CLOSE: + cc += 1 + IMM2_SIZE; + return cc; + + case OP_CRRANGE: + case OP_CRMINRANGE: + return cc + 1 + 2 * IMM2_SIZE; + + case OP_CLASS: + case OP_NCLASS: + return cc + 1 + 32 / sizeof(pcre_uchar); + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + return cc + GET(cc, 1); +#endif + + case OP_RECURSE: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_REVERSE: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_BRAPOS: + case OP_COND: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + case OP_ALT: + case OP_KET: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + return cc + 1 + LINK_SIZE; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + return cc + 1 + LINK_SIZE + IMM2_SIZE; + + case OP_MARK: + return cc + 1 + 2 + cc[1]; + + default: + return NULL; + } +} + +static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +{ +int localspace = 0; +pcre_uchar *alternative; +/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ +while (cc < ccend) + { + switch(*cc) + { + case OP_SET_SOM: + common->has_set_som = TRUE; + cc += 1; + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + case OP_RECURSE: + /* Set its value only once. */ + if (common->recursive_head == 0) + { + common->recursive_head = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + } + cc += 1 + LINK_SIZE; + break; + + case OP_MARK: + if (common->mark_ptr == 0) + { + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + } + cc += 1 + 2 + cc[1]; + break; + + default: + cc = next_opcode(common, cc); + if (cc == NULL) + return -1; + break; + } + } +return localspace; +} + +static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend) +{ +pcre_uchar *cc = common->start; +pcre_uchar *alternative; +while (cc < ccend) + { + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + } + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +} + +/* Returns with -1 if no need for frame. */ +static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive) +{ +pcre_uchar *ccend = bracketend(cc); +int length = 0; +BOOL possessive = FALSE; +BOOL setsom_found = recursive; +BOOL setmark_found = recursive; + +if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) + { + length = 3; + possessive = TRUE; + } + +cc = next_opcode(common, cc); +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + SLJIT_ASSERT(common->has_set_som); + if (!setsom_found) + { + length += 2; + setsom_found = TRUE; + } + cc += 1; + break; + + case OP_MARK: + SLJIT_ASSERT(common->mark_ptr != 0); + if (!setmark_found) + { + length += 2; + setmark_found = TRUE; + } + cc += 1 + 2 + cc[1]; + break; + + case OP_RECURSE: + if (common->has_set_som && !setsom_found) + { + length += 2; + setsom_found = TRUE; + } + if (common->mark_ptr != 0 && !setmark_found) + { + length += 2; + setmark_found = TRUE; + } + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + length += 3; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +/* Possessive quantifiers can use a special case. */ +if (SLJIT_UNLIKELY(possessive) && length == 3) + return -1; + +if (length > 0) + return length + 1; +return -1; +} + +static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive) +{ +DEFINE_COMPILER; +pcre_uchar *ccend = bracketend(cc); +BOOL setsom_found = recursive; +BOOL setmark_found = recursive; +int offset; + +/* >= 1 + shortest item size (2) */ +SLJIT_UNUSED_ARG(stacktop); +SLJIT_ASSERT(stackpos >= stacktop + 2); + +stackpos = STACK(stackpos); +if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) + cc = next_opcode(common, cc); +SLJIT_ASSERT(cc != NULL); +while (cc < ccend) + switch(*cc) + { + case OP_SET_SOM: + SLJIT_ASSERT(common->has_set_som); + if (!setsom_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + setsom_found = TRUE; + } + cc += 1; + break; + + case OP_MARK: + SLJIT_ASSERT(common->mark_ptr != 0); + if (!setmark_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + setmark_found = TRUE; + } + cc += 1 + 2 + cc[1]; + break; + + case OP_RECURSE: + if (common->has_set_som && !setsom_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + setsom_found = TRUE; + } + if (common->mark_ptr != 0 && !setmark_found) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + setmark_found = TRUE; + } + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + offset = (GET2(cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); + stackpos += (int)sizeof(sljit_w); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); + stackpos += (int)sizeof(sljit_w); + + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); +SLJIT_ASSERT(stackpos == STACK(stacktop)); +} + +static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +{ +int localsize = 2; +pcre_uchar *alternative; +/* Calculate the sum of the local variables. */ +while (cc < ccend) + { + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + localsize++; + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + localsize++; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + localsize += 2; + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + localsize++; + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + } +SLJIT_ASSERT(cc == ccend); +return localsize; +} + +static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, + BOOL save, int stackptr, int stacktop) +{ +DEFINE_COMPILER; +int srcw[2]; +int count; +BOOL tmp1next = TRUE; +BOOL tmp1empty = TRUE; +BOOL tmp2empty = TRUE; +pcre_uchar *alternative; +enum { + start, + loop, + end +} status; + +status = save ? start : loop; +stackptr = STACK(stackptr - 2); +stacktop = STACK(stacktop - 1); + +if (!save) + { + stackptr += sizeof(sljit_w); + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + tmp1empty = FALSE; + } + if (stackptr < stacktop) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + tmp2empty = FALSE; + } + /* The tmp1next must be TRUE in either way. */ + } + +while (status != end) + { + count = 0; + switch(status) + { + case start: + SLJIT_ASSERT(save && common->recursive_head != 0); + count = 1; + srcw[0] = common->recursive_head; + status = loop; + break; + + case loop: + if (cc >= ccend) + { + status = end; + break; + } + + switch(*cc) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_SCOND: + count = 1; + srcw[0] = PRIV_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE; + break; + + case OP_CBRA: + case OP_SCBRA: + count = 1; + srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + count = 2; + srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); + srcw[0] = PRIV_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + cc += 1 + LINK_SIZE + IMM2_SIZE; + break; + + case OP_COND: + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + { + count = 1; + srcw[0] = PRIV_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); + } + cc += 1 + LINK_SIZE; + break; + + default: + cc = next_opcode(common, cc); + SLJIT_ASSERT(cc != NULL); + break; + } + break; + + case end: + SLJIT_ASSERT_STOP(); + break; + } + + while (count > 0) + { + count--; + if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); + tmp1empty = FALSE; + tmp1next = FALSE; + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); + tmp2empty = FALSE; + tmp1next = TRUE; + } + } + else + { + if (tmp1next) + { + SLJIT_ASSERT(!tmp1empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0); + tmp1empty = stackptr >= stacktop; + if (!tmp1empty) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + } + tmp1next = FALSE; + } + else + { + SLJIT_ASSERT(!tmp2empty); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0); + tmp2empty = stackptr >= stacktop; + if (!tmp2empty) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); + stackptr += sizeof(sljit_w); + } + tmp1next = TRUE; + } + } + } + } + +if (save) + { + if (tmp1next) + { + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + } + else + { + if (!tmp2empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); + stackptr += sizeof(sljit_w); + } + if (!tmp1empty) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); + stackptr += sizeof(sljit_w); + } + } + } +SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); +} + +static SLJIT_INLINE BOOL ispowerof2(unsigned int value) +{ +return (value & (value - 1)) == 0; +} + +static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) +{ +while (list) + { + /* sljit_set_label is clever enough to do nothing + if either the jump or the label is NULL */ + sljit_set_label(list->jump, label); + list = list->next; + } +} + +static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) +{ +jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); +if (list_item) + { + list_item->next = *list; + list_item->jump = jump; + *list = list_item; + } +} + +static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start) +{ +DEFINE_COMPILER; +stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); + +if (list_item) + { + list_item->type = type; + list_item->data = data; + list_item->start = start; + list_item->leave = LABEL(); + list_item->next = common->stubs; + common->stubs = list_item; + } +} + +static void flush_stubs(compiler_common *common) +{ +DEFINE_COMPILER; +stub_list* list_item = common->stubs; + +while (list_item) + { + JUMPHERE(list_item->start); + switch(list_item->type) + { + case stack_alloc: + add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); + break; + } + JUMPTO(SLJIT_JUMP, list_item->leave); + list_item = list_item->next; + } +common->stubs = NULL; +} + +static SLJIT_INLINE void decrease_call_count(compiler_common *common) +{ +DEFINE_COMPILER; + +OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); +add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); +} + +static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) +{ +/* May destroy all locals and registers except TMP2. */ +DEFINE_COMPILER; + +OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); +#ifdef DESTROY_REGISTERS +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); +OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); +#endif +add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); +} + +static SLJIT_INLINE void free_stack(compiler_common *common, int size) +{ +DEFINE_COMPILER; +OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); +} + +static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +int i; +/* At this point we can freely use all temporary registers. */ +/* TMP1 returns with begin - 1. */ +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); +if (length < 8) + { + for (i = 0; i < length; i++) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); + } +else + { + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, loop); + } +} + +static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *earlyexit; + +/* At this point we can freely use all registers. */ +OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); + +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); +OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); +GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); +/* Unlikely, but possible */ +earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); +loop = LABEL(); +OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); +OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); +/* Copy the integer value to the output buffer */ +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); +#endif +OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); +JUMPTO(SLJIT_C_NOT_ZERO, loop); +JUMPHERE(earlyexit); + +/* Calculate the return value, which is the maximum ovector value. */ +if (topbracket > 1) + { + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); + + /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ + loop = LABEL(); + OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); + OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); + } +else + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); +} + +static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) +{ +DEFINE_COMPILER; + +SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); +SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); + +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); +OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); + +/* Store match begin and end. */ +OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); +OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); +#endif +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); + +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); +#endif +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); + +JUMPTO(SLJIT_JUMP, leave); +} + +static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) +{ +/* May destroy TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (common->mode == JIT_PARTIAL_SOFT_COMPILE) + { + /* The value of -1 must be kept for start_used_ptr! */ + OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); + /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting + is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ + jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +else if (common->mode == JIT_PARTIAL_HARD_COMPILE) + { + jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +} + +static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) +{ +/* Detects if the character has an othercase. */ +unsigned int c; + +#ifdef SUPPORT_UTF +if (common->utf) + { + GETCHAR(c, cc); + if (c > 127) + { +#ifdef SUPPORT_UCP + return c != UCD_OTHERCASE(c); +#else + return FALSE; +#endif + } +#ifndef COMPILE_PCRE8 + return common->fcc[c] != c; +#endif + } +else +#endif + c = *cc; +return MAX_255(c) ? common->fcc[c] != c : FALSE; +} + +static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c) +{ +/* Returns with the othercase. */ +#ifdef SUPPORT_UTF +if (common->utf && c > 127) + { +#ifdef SUPPORT_UCP + return UCD_OTHERCASE(c); +#else + return c; +#endif + } +#endif +return TABLE_GET(c, common->fcc, c); +} + +static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc) +{ +/* Detects if the character and its othercase has only 1 bit difference. */ +unsigned int c, oc, bit; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +int n; +#endif + +#ifdef SUPPORT_UTF +if (common->utf) + { + GETCHAR(c, cc); + if (c <= 127) + oc = common->fcc[c]; + else + { +#ifdef SUPPORT_UCP + oc = UCD_OTHERCASE(c); +#else + oc = c; +#endif + } + } +else + { + c = *cc; + oc = TABLE_GET(c, common->fcc, c); + } +#else +c = *cc; +oc = TABLE_GET(c, common->fcc, c); +#endif + +SLJIT_ASSERT(c != oc); + +bit = c ^ oc; +/* Optimized for English alphabet. */ +if (c <= 127 && bit == 0x20) + return (0 << 8) | 0x20; + +/* Since c != oc, they must have at least 1 bit difference. */ +if (!ispowerof2(bit)) + return 0; + +#ifdef COMPILE_PCRE8 + +#ifdef SUPPORT_UTF +if (common->utf && c > 127) + { + n = GET_EXTRALEN(*cc); + while ((bit & 0x3f) == 0) + { + n--; + bit >>= 6; + } + return (n << 8) | bit; + } +#endif /* SUPPORT_UTF */ +return (0 << 8) | bit; + +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 +#ifdef SUPPORT_UTF +if (common->utf && c > 65535) + { + if (bit >= (1 << 10)) + bit >>= 10; + else + return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); + } +#endif /* SUPPORT_UTF */ +return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ +} + +static void check_partial(compiler_common *common, BOOL force) +{ +/* Checks whether a partial matching is occured. Does not modify registers. */ +DEFINE_COMPILER; +struct sljit_jump *jump = NULL; + +SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); + +if (common->mode == JIT_COMPILE) + return; + +if (!force) + jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); +else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) + jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); + +if (common->mode == JIT_PARTIAL_SOFT_COMPILE) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); +else + { + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } + +if (jump != NULL) + JUMPHERE(jump); +} + +static struct sljit_jump *check_str_end(compiler_common *common) +{ +/* Does not affect registers. Usually used in a tight spot. */ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_jump *nohit; +struct sljit_jump *return_value; + +if (common->mode == JIT_COMPILE) + return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); +if (common->mode == JIT_PARTIAL_SOFT_COMPILE) + { + nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); + JUMPHERE(nohit); + return_value = JUMP(SLJIT_JUMP); + } +else + { + return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } +JUMPHERE(jump); +return return_value; +} + +static void detect_partial_match(compiler_common *common, jump_list **backtracks) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +if (common->mode == JIT_COMPILE) + { + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + return; + } + +/* Partial matching mode. */ +jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); +add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); +if (common->mode == JIT_PARTIAL_SOFT_COMPILE) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + } +else + { + if (common->partialmatchlabel != NULL) + JUMPTO(SLJIT_JUMP, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); + } +JUMPHERE(jump); +} + +static void read_char(compiler_common *common) +{ +/* Reads the character into TMP1, updates STR_PTR. +Does not check STR_END. TMP2 Destroyed. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF +struct sljit_jump *jump; +#endif + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF +if (common->utf) + { +#ifdef COMPILE_PCRE8 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); +#else +#ifdef COMPILE_PCRE16 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); +#endif +#endif /* COMPILE_PCRE8 */ + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); + } +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +} + +static void peek_char(compiler_common *common) +{ +/* Reads the character into TMP1, keeps STR_PTR. +Does not check STR_END. TMP2 Destroyed. */ +DEFINE_COMPILER; +#ifdef SUPPORT_UTF +struct sljit_jump *jump; +#endif + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF +if (common->utf) + { +#ifdef COMPILE_PCRE8 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); +#else +#ifdef COMPILE_PCRE16 + jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); +#endif +#endif /* COMPILE_PCRE8 */ + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + JUMPHERE(jump); + } +#endif +} + +static void read_char8_type(compiler_common *common) +{ +/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ +DEFINE_COMPILER; +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 +struct sljit_jump *jump; +#endif + +#ifdef SUPPORT_UTF +if (common->utf) + { + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#ifdef COMPILE_PCRE8 + /* This can be an extra read in some situations, but hopefully + it is needed in most cases. */ + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); + add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); +#else +#ifdef COMPILE_PCRE16 + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); + jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + JUMPHERE(jump); + /* Skip low surrogate if necessary. */ + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +#endif +#endif /* COMPILE_PCRE8 */ + return; + } +#endif +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#ifdef COMPILE_PCRE16 +/* The ctypes array contains only 256 values. */ +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +#ifdef COMPILE_PCRE16 +JUMPHERE(jump); +#endif +} + +static void skip_char_back(compiler_common *common) +{ +/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ +DEFINE_COMPILER; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +struct sljit_label *label; + +if (common->utf) + { + label = LABEL(); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); + return; + } +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + /* Skip low surrogate if necessary. */ + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + return; + } +#endif +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +} + +static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue) +{ +/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ +DEFINE_COMPILER; + +if (nltype == NLTYPE_ANY) + { + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + } +else if (nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + } +else + { + SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); + add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } +} + +#ifdef SUPPORT_UTF + +#ifdef COMPILE_PCRE8 +static void do_utfreadchar(compiler_common *common) +{ +/* Fast decoding a UTF-8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +/* Searching for the first zero. */ +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* Two byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* Three byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +/* Four byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void do_utfreadtype8(compiler_common *common) +{ +/* Fast decoding a UTF-8 character type. TMP2 contains the first byte +of the character (>= 0xc0). Return value in TMP1. */ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_jump *compare; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); +jump = JUMP(SLJIT_C_NOT_ZERO); +/* Two byte sequence. */ +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); +OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); +compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(compare); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +JUMPHERE(jump); + +/* We only have types for characters less than 256. */ +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 +static void do_utfreadchar(compiler_common *common) +{ +/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char +of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); +/* Do nothing, only return. */ +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +/* Combine two 16 bit characters. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ + +#endif /* SUPPORT_UTF */ + +#ifdef SUPPORT_UCP + +/* UCD_BLOCK_SIZE must be 128 (see the assert below). */ +#define UCD_BLOCK_MASK 127 +#define UCD_BLOCK_SHIFT 7 + +static void do_getucd(compiler_common *common) +{ +/* Search the UCD record for the character comes in TMP1. +Returns chartype in TMP1 and UCD offset in TMP2. */ +DEFINE_COMPILER; + +SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2)); +OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} +#endif + +static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *mainloop; +struct sljit_label *newlinelabel = NULL; +struct sljit_jump *start; +struct sljit_jump *end = NULL; +struct sljit_jump *nl = NULL; +#ifdef SUPPORT_UTF +struct sljit_jump *singlechar; +#endif +jump_list *newline = NULL; +BOOL newlinecheck = FALSE; +BOOL readuchar = FALSE; + +if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || + common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) + newlinecheck = TRUE; + +if (firstline) + { + /* Search for the end of the first line. */ + SLJIT_ASSERT(common->first_line_end != 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + mainloop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + { + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + mainloop = LABEL(); + /* Continual stores does not cause data dependency. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); + read_char(common); + check_newlinechar(common, common->nltype, &newline, TRUE); + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); + set_jumps(newline, LABEL()); + } + + JUMPHERE(end); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + } + +start = JUMP(SLJIT_JUMP); + +if (newlinecheck) + { + newlinelabel = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + nl = JUMP(SLJIT_JUMP); + } + +mainloop = LABEL(); + +/* Increasing the STR_PTR here requires one less jump in the most common case. */ +#ifdef SUPPORT_UTF +if (common->utf) readuchar = TRUE; +#endif +if (newlinecheck) readuchar = TRUE; + +if (readuchar) + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if (newlinecheck) + CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +if (common->utf) + { + singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlechar); + } +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(singlechar); + } +#endif +JUMPHERE(start); + +if (newlinecheck) + { + JUMPHERE(end); + JUMPHERE(nl); + } + +return mainloop; +} + +static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *leave; +struct sljit_jump *found; +pcre_uchar oc, bit; + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +start = LABEL(); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +oc = first_char; +if (caseless) + { + oc = TABLE_GET(first_char, common->fcc, first_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (first_char > 127 && common->utf) + oc = UCD_OTHERCASE(first_char); +#endif + } +if (first_char == oc) + found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char); +else + { + bit = first_char ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + found = JUMP(SLJIT_C_NOT_ZERO); + } + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(leave); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *lastchar; +struct sljit_jump *firstchar; +struct sljit_jump *leave; +struct sljit_jump *foundcr = NULL; +struct sljit_jump *notfoundnl; +jump_list *newline = NULL; + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + + loop = LABEL(); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); + + JUMPHERE(leave); + JUMPHERE(firstchar); + JUMPHERE(lastchar); + + if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + return; + } + +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); +skip_char_back(common); + +loop = LABEL(); +read_char(common); +lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); +check_newlinechar(common, common->nltype, &newline, FALSE); +set_jumps(newline, loop); + +if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) + { + leave = JUMP(SLJIT_JUMP); + JUMPHERE(foundcr); + notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(notfoundnl); + JUMPHERE(leave); + } +JUMPHERE(lastchar); +JUMPHERE(firstchar); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *leave; +struct sljit_jump *found; +#ifndef COMPILE_PCRE8 +struct sljit_jump *jump; +#endif + +if (firstline) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + } + +start = LABEL(); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +#ifdef SUPPORT_UTF +if (common->utf) + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +#endif +#ifndef COMPILE_PCRE8 +jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); +JUMPHERE(jump); +#endif +OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits); +OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); +OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); +found = JUMP(SLJIT_C_NOT_ZERO); + +#ifdef SUPPORT_UTF +if (common->utf) + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +#endif +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +JUMPTO(SLJIT_JUMP, start); +JUMPHERE(found); +JUMPHERE(leave); + +if (firstline) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); +} + +static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar) +{ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_jump *toolong; +struct sljit_jump *alreadyfound; +struct sljit_jump *found; +struct sljit_jump *foundoc = NULL; +struct sljit_jump *notfound; +pcre_uchar oc, bit; + +SLJIT_ASSERT(common->req_char_ptr != 0); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); +OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); +toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); +alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); + +if (has_firstchar) + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +else + OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); + +loop = LABEL(); +notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); +oc = req_char; +if (caseless) + { + oc = TABLE_GET(req_char, common->fcc, req_char); +#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) + if (req_char > 127 && common->utf) + oc = UCD_OTHERCASE(req_char); +#endif + } +if (req_char == oc) + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); +else + { + bit = req_char ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); + } + else + { + found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); + foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); + } + } +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_JUMP, loop); + +JUMPHERE(found); +if (foundoc) + JUMPHERE(foundoc); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0); +JUMPHERE(alreadyfound); +JUMPHERE(toolong); +return notfound; +} + +static void do_revertframes(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *mainloop; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); +GET_LOCAL_BASE(TMP3, 0, 0); + +/* Drop frames until we reach STACK_TOP. */ +mainloop = LABEL(); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); +jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); +JUMPTO(SLJIT_JUMP, mainloop); + +JUMPHERE(jump); +jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); +/* End of dropping frames. */ +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); +jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); +/* Set string begin. */ +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); +JUMPTO(SLJIT_JUMP, mainloop); + +JUMPHERE(jump); +if (common->mark_ptr != 0) + { + jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); + JUMPTO(SLJIT_JUMP, mainloop); + + JUMPHERE(jump); + } + +/* Unknown command. */ +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); +JUMPTO(SLJIT_JUMP, mainloop); +} + +static void check_wordboundary(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *skipread; +#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF +struct sljit_jump *jump; +#endif + +SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); + +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +/* Get type of the previous char, and put it to LOCALS1. */ +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); +skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); +skip_char_back(common); +check_start_used_ptr(common); +read_char(common); + +/* Testing char type. */ +#ifdef SUPPORT_UCP +if (common->use_ucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); + } +else +#endif + { +#ifndef COMPILE_PCRE8 + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#elif defined SUPPORT_UTF + /* Here LOCALS1 has already been zeroed. */ + jump = NULL; + if (common->utf) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif /* COMPILE_PCRE8 */ + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0); +#ifndef COMPILE_PCRE8 + JUMPHERE(jump); +#elif defined SUPPORT_UTF + if (jump != NULL) + JUMPHERE(jump); +#endif /* COMPILE_PCRE8 */ + } +JUMPHERE(skipread); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); +skipread = check_str_end(common); +peek_char(common); + +/* Testing char type. This is a code duplication. */ +#ifdef SUPPORT_UCP +if (common->use_ucp) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + JUMPHERE(jump); + } +else +#endif + { +#ifndef COMPILE_PCRE8 + /* TMP2 may be destroyed by peek_char. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#elif defined SUPPORT_UTF + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = NULL; + if (common->utf) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); + OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +#ifndef COMPILE_PCRE8 + JUMPHERE(jump); +#elif defined SUPPORT_UTF + if (jump != NULL) + JUMPHERE(jump); +#endif /* COMPILE_PCRE8 */ + } +JUMPHERE(skipread); + +OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +} + +static void check_anynewline(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); +#ifdef COMPILE_PCRE8 + } +#endif +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_hspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); +COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); +#ifdef COMPILE_PCRE8 + } +#endif +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +static void check_vspace(compiler_common *common) +{ +/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ +DEFINE_COMPILER; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); +OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 +#ifdef COMPILE_PCRE8 +if (common->utf) + { +#endif + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); +#ifdef COMPILE_PCRE8 + } +#endif +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define CHAR1 STR_END +#define CHAR2 STACK_TOP + +static void do_casefulcmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +label = LABEL(); +OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); +OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_C_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#define LCC_TABLE STACK_LIMIT + +static void do_caselesscmp(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0); +OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +label = LABEL(); +OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); +OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); +#ifndef COMPILE_PCRE8 +jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); +#ifndef COMPILE_PCRE8 +JUMPHERE(jump); +jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255); +#endif +OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); +#ifndef COMPILE_PCRE8 +JUMPHERE(jump); +#endif +jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +JUMPTO(SLJIT_C_NOT_ZERO, label); + +JUMPHERE(jump); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0); +OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); +} + +#undef LCC_TABLE +#undef CHAR1 +#undef CHAR2 + +#if defined SUPPORT_UTF && defined SUPPORT_UCP + +static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) +{ +/* This function would be ineffective to do in JIT level. */ +int c1, c2; +const pcre_uchar *src2 = args->uchar_ptr; +const pcre_uchar *end2 = args->end; + +while (src1 < end1) + { + if (src2 >= end2) + return (pcre_uchar*)1; + GETCHARINC(c1, src1); + GETCHARINC(c2, src2); + if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; + } +return src2; +} + +#endif /* SUPPORT_UTF && SUPPORT_UCP */ + +static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, + compare_context* context, jump_list **backtracks) +{ +DEFINE_COMPILER; +unsigned int othercasebit = 0; +pcre_uchar *othercasechar = NULL; +#ifdef SUPPORT_UTF +int utflength; +#endif + +if (caseless && char_has_othercase(common, cc)) + { + othercasebit = char_get_othercase_bit(common, cc); + SLJIT_ASSERT(othercasebit); + /* Extracting bit difference info. */ +#ifdef COMPILE_PCRE8 + othercasechar = cc + (othercasebit >> 8); + othercasebit &= 0xff; +#else +#ifdef COMPILE_PCRE16 + othercasechar = cc + (othercasebit >> 9); + if ((othercasebit & 0x100) != 0) + othercasebit = (othercasebit & 0xff) << 8; + else + othercasebit &= 0xff; +#endif +#endif + } + +if (context->sourcereg == -1) + { +#ifdef COMPILE_PCRE8 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#else +#ifdef COMPILE_PCRE16 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif +#endif /* COMPILE_PCRE8 */ + context->sourcereg = TMP2; + } + +#ifdef SUPPORT_UTF +utflength = 1; +if (common->utf && HAS_EXTRALEN(*cc)) + utflength += GET_EXTRALEN(*cc); + +do + { +#endif + + context->length -= IN_UCHARS(1); +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + + /* Unaligned read is supported. */ + if (othercasebit != 0 && othercasechar == cc) + { + context->c.asuchars[context->ucharptr] = *cc | othercasebit; + context->oc.asuchars[context->ucharptr] = othercasebit; + } + else + { + context->c.asuchars[context->ucharptr] = *cc; + context->oc.asuchars[context->ucharptr] = 0; + } + context->ucharptr++; + +#ifdef COMPILE_PCRE8 + if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) +#else + if (context->ucharptr >= 2 || context->length == 0) +#endif + { + if (context->length >= 4) + OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#ifdef COMPILE_PCRE8 + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 1) + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#else + else if (context->length >= 2) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + switch(context->ucharptr) + { + case 4 / sizeof(pcre_uchar): + if (context->oc.asint != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); + break; + + case 2 / sizeof(pcre_uchar): + if (context->oc.asushort != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); + break; + +#ifdef COMPILE_PCRE8 + case 1: + if (context->oc.asbyte != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); + break; +#endif + + default: + SLJIT_ASSERT_STOP(); + break; + } + context->ucharptr = 0; + } + +#else + + /* Unaligned read is unsupported. */ +#ifdef COMPILE_PCRE8 + if (context->length > 0) + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#else + if (context->length > 0) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + if (othercasebit != 0 && othercasechar == cc) + { + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); + +#endif + + cc++; +#ifdef SUPPORT_UTF + utflength--; + } +while (utflength > 0); +#endif + +return cc; +} + +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + +#define SET_TYPE_OFFSET(value) \ + if ((value) != typeoffset) \ + { \ + if ((value) > typeoffset) \ + OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ + else \ + OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ + } \ + typeoffset = (value); + +#define SET_CHAR_OFFSET(value) \ + if ((value) != charoffset) \ + { \ + if ((value) > charoffset) \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \ + else \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \ + } \ + charoffset = (value); + +static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; +unsigned int c; +int compares; +struct sljit_jump *jump = NULL; +pcre_uchar *ccbegin; +#ifdef SUPPORT_UCP +BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; +BOOL charsaved = FALSE; +int typereg = TMP1, scriptreg = TMP1; +unsigned int typeoffset; +#endif +int invertcmp, numberofcmps; +unsigned int charoffset; + +/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ +detect_partial_match(common, backtracks); +read_char(common); + +if ((*cc++ & XCL_MAP) != 0) + { + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); +#ifndef COMPILE_PCRE8 + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#elif defined SUPPORT_UTF + if (common->utf) + jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); +#endif + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); + +#ifndef COMPILE_PCRE8 + JUMPHERE(jump); +#elif defined SUPPORT_UTF + if (common->utf) + JUMPHERE(jump); +#endif + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +#ifdef SUPPORT_UCP + charsaved = TRUE; +#endif + cc += 32 / sizeof(pcre_uchar); + } + +/* Scanning the necessary info. */ +ccbegin = cc; +compares = 0; +while (*cc != XCL_END) + { + compares++; + if (*cc == XCL_SINGLE) + { + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif +#ifdef SUPPORT_UCP + needschar = TRUE; +#endif + } + else if (*cc == XCL_RANGE) + { + cc += 2; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + cc++; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif +#ifdef SUPPORT_UCP + needschar = TRUE; +#endif + } +#ifdef SUPPORT_UCP + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + switch(*cc) + { + case PT_ANY: + break; + + case PT_LAMP: + case PT_GC: + case PT_PC: + case PT_ALNUM: + needstype = TRUE; + break; + + case PT_SC: + needsscript = TRUE; + break; + + case PT_SPACE: + case PT_PXSPACE: + case PT_WORD: + needstype = TRUE; + needschar = TRUE; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + cc += 2; + } +#endif + } + +#ifdef SUPPORT_UCP +/* Simple register allocation. TMP1 is preferred if possible. */ +if (needstype || needsscript) + { + if (needschar && !charsaved) + OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + if (needschar) + { + if (needstype) + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + typereg = RETURN_ADDR; + } + + if (needsscript) + scriptreg = TMP3; + OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + } + else if (needstype && needsscript) + scriptreg = TMP3; + /* In all other cases only one of them was specified, and that can goes to TMP1. */ + + if (needsscript) + { + if (scriptreg == TMP1) + { + OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); + } + else + { + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); + } + } + } +#endif + +/* Generating code. */ +cc = ccbegin; +charoffset = 0; +numberofcmps = 0; +#ifdef SUPPORT_UCP +typeoffset = 0; +#endif + +while (*cc != XCL_END) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + jump = NULL; + + if (*cc == XCL_SINGLE) + { + cc ++; +#ifdef SUPPORT_UTF + if (common->utf) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); + numberofcmps = 0; + } + } + else if (*cc == XCL_RANGE) + { + cc ++; +#ifdef SUPPORT_UTF + if (common->utf) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + SET_CHAR_OFFSET(c); +#ifdef SUPPORT_UTF + if (common->utf) + { + GETCHARINC(c, cc); + } + else +#endif + c = *cc++; + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset); + numberofcmps = 0; + } + } +#ifdef SUPPORT_UCP + else + { + if (*cc == XCL_NOTPROP) + invertcmp ^= 0x1; + cc++; + switch(*cc) + { + case PT_ANY: + if (list != backtracks) + { + if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) + continue; + } + else if (cc[-1] == XCL_NOTPROP) + continue; + jump = JUMP(SLJIT_JUMP); + break; + + case PT_LAMP: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_GC: + c = PRIV(ucp_typerange)[(int)cc[1] * 2]; + SET_TYPE_OFFSET(c); + jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); + break; + + case PT_PC: + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); + break; + + case PT_SC: + jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); + break; + + case PT_SPACE: + case PT_PXSPACE: + if (*cc == PT_SPACE) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset); + } + SET_CHAR_OFFSET(9); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); + if (*cc == PT_SPACE) + JUMPHERE(jump); + + SET_TYPE_OFFSET(ucp_Zl); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + + case PT_WORD: + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + /* ... fall through */ + + case PT_ALNUM: + SET_TYPE_OFFSET(ucp_Ll); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); + COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); + SET_TYPE_OFFSET(ucp_Nd); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); + jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); + break; + } + cc += 2; + } +#endif + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + +if (found != NULL) + set_jumps(found, LABEL()); +} + +#undef SET_TYPE_OFFSET +#undef SET_CHAR_OFFSET + +#endif + +static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +int length; +unsigned int c, oc, bit; +compare_context context; +struct sljit_jump *jump[4]; +#ifdef SUPPORT_UTF +struct sljit_label *label; +#ifdef SUPPORT_UCP +pcre_uchar propdata[5]; +#endif +#endif + +switch(type) + { + case OP_SOD: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_SOM: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + + case OP_NOT_DIGIT: + case OP_DIGIT: + detect_partial_match(common, backtracks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + detect_partial_match(common, backtracks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); + add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + detect_partial_match(common, backtracks); + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); + add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); + return cc; + + case OP_ANY: + detect_partial_match(common, backtracks); + read_char(common); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + if (common->mode != JIT_PARTIAL_HARD_COMPILE) + jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + else + jump[1] = check_str_end(common); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); + if (jump[1] != NULL) + JUMPHERE(jump[1]); + JUMPHERE(jump[0]); + } + else + check_newlinechar(common, common->nltype, backtracks, TRUE); + return cc; + + case OP_ALLANY: + detect_partial_match(common, backtracks); +#ifdef SUPPORT_UTF + if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#ifdef COMPILE_PCRE8 + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#endif /* COMPILE_PCRE16 */ +#endif /* COMPILE_PCRE8 */ + JUMPHERE(jump[0]); + return cc; + } +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + + case OP_ANYBYTE: + detect_partial_match(common, backtracks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + case OP_NOTPROP: + case OP_PROP: + propdata[0] = 0; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + compile_xclass_trypath(common, propdata, backtracks); + return cc + 2; +#endif +#endif + + case OP_ANYNL: + detect_partial_match(common, backtracks); + read_char(common); + jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + /* We don't need to handle soft partial matching case. */ + if (common->mode != JIT_PARTIAL_HARD_COMPILE) + jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + else + jump[1] = check_str_end(common); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[3] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + JUMPHERE(jump[1]); + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + return cc; + + case OP_NOT_HSPACE: + case OP_HSPACE: + detect_partial_match(common, backtracks); + read_char(common); + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + + case OP_NOT_VSPACE: + case OP_VSPACE: + detect_partial_match(common, backtracks); + read_char(common); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); + return cc; + +#ifdef SUPPORT_UCP + case OP_EXTUNI: + detect_partial_match(common, backtracks); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); + + label = LABEL(); + jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(jump[0]); + if (common->mode == JIT_PARTIAL_HARD_COMPILE) + { + jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); + /* Since we successfully read a char above, partial matching must occure. */ + check_partial(common, TRUE); + JUMPHERE(jump[0]); + } + return cc; +#endif + + case OP_EODN: + /* Requires rather complex checks. */ + jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } + else + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_C_GREATER); + add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); + /* Equal. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); + read_char(common); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + check_partial(common, FALSE); + return cc; + + case OP_EOD: + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + return cc; + + case OP_CIRC: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + return cc; + + case OP_CIRCM: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + skip_char_back(common); + read_char(common); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_DOLL: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + + if (!common->endonly) + compile_char1_trypath(common, OP_EODN, cc, backtracks); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + } + return cc; + + case OP_DOLLM: + jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + check_partial(common, FALSE); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); + /* STR_PTR = STR_END - IN_UCHARS(1) */ + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char(common); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_CHAR: + case OP_CHARI: + length = 1; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); +#endif + if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + + context.length = IN_UCHARS(length); + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); + } + detect_partial_match(common, backtracks); + read_char(common); +#ifdef SUPPORT_UTF + if (common->utf) + { + GETCHAR(c, cc); + } + else +#endif + c = *cc; + if (type == OP_CHAR || !char_has_othercase(common, cc)) + { + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + return cc + length; + } + oc = char_othercase(common, c); + bit = c ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + return cc + length; + } + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); + return cc + length; + + case OP_NOT: + case OP_NOTI: + detect_partial_match(common, backtracks); + length = 1; +#ifdef SUPPORT_UTF + if (common->utf) + { +#ifdef COMPILE_PCRE8 + c = *cc; + if (c < 128) + { + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); + } + /* Skip the variable-length character. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc + 1; + } + else +#endif /* COMPILE_PCRE8 */ + { + GETCHARLEN(c, cc, length); + read_char(common); + } + } + else +#endif /* SUPPORT_UTF */ + { + read_char(common); + c = *cc; + } + + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + oc = char_othercase(common, c); + bit = c ^ oc; + if (ispowerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + } + else + { + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + } + } + return cc + length; + + case OP_CLASS: + case OP_NCLASS: + detect_partial_match(common, backtracks); + read_char(common); +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + jump[0] = NULL; +#ifdef COMPILE_PCRE8 + /* This check only affects 8 bit mode. In other modes, we + always need to compare the value with 255. */ + if (common->utf) +#endif /* COMPILE_PCRE8 */ + { + jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } + } +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + if (jump[0] != NULL) + JUMPHERE(jump[0]); +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ + return cc + 32 / sizeof(pcre_uchar); + +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 + case OP_XCLASS: + compile_xclass_trypath(common, cc + LINK_SIZE, backtracks); + return cc + GET(cc, 0) - 1; +#endif + + case OP_REVERSE: + length = GET(cc, 0); + if (length == 0) + return cc + LINK_SIZE; + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +#ifdef SUPPORT_UTF + if (common->utf) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); + label = LABEL(); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); + skip_char_back(common); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_C_NOT_ZERO, label); + } + else +#endif + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); + } + check_start_used_ptr(common); + return cc + LINK_SIZE; + } +SLJIT_ASSERT_STOP(); +return cc; +} + +static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) +{ +/* This function consumes at least one input character. */ +/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ +DEFINE_COMPILER; +pcre_uchar *ccbegin = cc; +compare_context context; +int size; + +context.length = 0; +do + { + if (cc >= ccend) + break; + + if (*cc == OP_CHAR) + { + size = 1; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); +#endif + } + else if (*cc == OP_CHARI) + { + size = 1; +#ifdef SUPPORT_UTF + if (common->utf) + { + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + else if (HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); + } + else +#endif + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + } + else + size = 0; + + cc += 1 + size; + context.length += IN_UCHARS(size); + } +while (size > 0 && context.length <= 128); + +cc = ccbegin; +if (context.length > 0) + { + /* We have a fixed-length byte sequence. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); + add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); + + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); + return cc; + } + +/* A non-fixed length character will be checked if length == 0. */ +return compile_char1_trypath(common, *cc, cc + 1, backtracks); +} + +static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1) << 1; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); +if (!common->jscript_compat) + { + if (backtracks == NULL) + { + /* OVECTOR(1) contains the "string begin - 1" constant. */ + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); + return JUMP(SLJIT_C_NOT_ZERO); + } + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + } +return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); +} + +/* Forward definitions. */ +static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); +static void compile_backtrackpath(compiler_common *, struct backtrack_common *); + +#define PUSH_BACKTRACK(size, ccstart, error) \ + do \ + { \ + backtrack = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return error; \ + memset(backtrack, 0, size); \ + backtrack->prev = parent->top; \ + backtrack->cc = (ccstart); \ + parent->top = backtrack; \ + } \ + while (0) + +#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ + do \ + { \ + backtrack = sljit_alloc_memory(compiler, (size)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + memset(backtrack, 0, size); \ + backtrack->prev = parent->top; \ + backtrack->cc = (ccstart); \ + parent->top = backtrack; \ + } \ + while (0) + +#define BACKTRACK_AS(type) ((type *)backtrack) + +static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1) << 1; +struct sljit_jump *jump = NULL; +struct sljit_jump *partial; +struct sljit_jump *nopartial; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); +/* OVECTOR(1) contains the "string begin - 1" constant. */ +if (withchecks && !common->jscript_compat) + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + +#if defined SUPPORT_UTF && defined SUPPORT_UCP +if (common->utf && *cc == OP_REFI) + { + SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + if (withchecks) + jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); + + /* Needed to save important temporary registers. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); + nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); + check_partial(common, FALSE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(nopartial); + } + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + } +else +#endif /* SUPPORT_UTF && SUPPORT_UCP */ + { + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); + if (withchecks) + jump = JUMP(SLJIT_C_ZERO); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, partial); + + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + + if (common->mode != JIT_COMPILE) + { + nopartial = JUMP(SLJIT_JUMP); + JUMPHERE(partial); + /* TMP2 -= STR_END - STR_PTR */ + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); + partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + JUMPHERE(partial); + check_partial(common, FALSE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(nopartial); + } + } + +if (jump != NULL) + { + if (emptyfail) + add_jump(compiler, backtracks, jump); + else + JUMPHERE(jump); + } +return cc + 1 + IMM2_SIZE; +} + +static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar type; +struct sljit_label *label; +struct sljit_jump *zerolength; +struct sljit_jump *jump = NULL; +pcre_uchar *ccbegin = cc; +int min = 0, max = 0; +BOOL minimize; + +PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); + +type = cc[1 + IMM2_SIZE]; +minimize = (type & 0x1) != 0; +switch(type) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + min = 0; + max = 0; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + max = 0; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRQUERY: + case OP_CRMINQUERY: + min = 0; + max = 1; + cc += 1 + IMM2_SIZE + 1; + break; + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(cc, 1 + IMM2_SIZE + 1); + max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE); + cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE; + break; + default: + SLJIT_ASSERT_STOP(); + break; + } + +if (!minimize) + { + if (min == 0) + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + /* Temporary release of STR_PTR. */ + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + zerolength = compile_ref_checks(common, ccbegin, NULL); + /* Restore if not zero length. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + else + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); + } + + if (min > 1 || max > 1) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); + + label = LABEL(); + compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); + + if (min > 1 || max > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + if (min > 1) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); + if (max > 1) + { + jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + JUMPHERE(jump); + } + } + + if (max == 0) + { + /* Includes min > 1 case as well. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + } + + JUMPHERE(zerolength); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); + + decrease_call_count(common); + return cc; + } + +allocate_stack(common, 2); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); +if (type != OP_CRMINSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + +if (min == 0) + { + zerolength = compile_ref_checks(common, ccbegin, NULL); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + jump = JUMP(SLJIT_JUMP); + } +else + zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); + +BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); +if (max > 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); + +compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +if (min > 1) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath); + } +else if (max > 0) + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + +if (jump != NULL) + JUMPHERE(jump); +JUMPHERE(zerolength); + +decrease_call_count(common); +return cc; +} + +static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +recurse_entry *entry = common->entries; +recurse_entry *prev = NULL; +int start = GET(cc, 1); + +PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); +while (entry != NULL) + { + if (entry->start == start) + break; + prev = entry; + entry = entry->next; + } + +if (entry == NULL) + { + entry = sljit_alloc_memory(compiler, sizeof(recurse_entry)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + entry->next = NULL; + entry->entry = NULL; + entry->calls = NULL; + entry->start = start; + + if (prev != NULL) + prev->next = entry; + else + common->entries = entry; + } + +if (common->has_set_som && common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + allocate_stack(common, 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + } +else if (common->has_set_som || common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } + +if (entry->entry == NULL) + add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); +else + JUMPTO(SLJIT_FAST_CALL, entry->entry); +/* Leave if the match is failed. */ +add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); +return cc + 1 + LINK_SIZE; +} + +static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) +{ +DEFINE_COMPILER; +int framesize; +int localptr; +backtrack_common altbacktrack; +pcre_uchar *ccbegin; +pcre_uchar opcode; +pcre_uchar bra = OP_BRA; +jump_list *tmp = NULL; +jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; +jump_list **found; +/* Saving previous accept variables. */ +struct sljit_label *save_leavelabel = common->leavelabel; +struct sljit_label *save_acceptlabel = common->acceptlabel; +jump_list *save_leave = common->leave; +jump_list *save_accept = common->accept; +struct sljit_jump *jump; +struct sljit_jump *brajump = NULL; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + SLJIT_ASSERT(!conditional); + bra = *cc; + cc++; + } +localptr = PRIV_DATA(cc); +SLJIT_ASSERT(localptr != 0); +framesize = get_framesize(common, cc, FALSE); +backtrack->framesize = framesize; +backtrack->localptr = localptr; +opcode = *cc; +SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); +found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; +ccbegin = cc; +cc += GET(cc, 1); + +if (bra == OP_BRAMINZERO) + { + /* This is a braminzero backtrack path. */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (framesize < 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } +else + { + allocate_stack(common, framesize + 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, framesize + 1, 2, FALSE); + } + +memset(&altbacktrack, 0, sizeof(backtrack_common)); +common->leavelabel = NULL; +common->leave = NULL; +while (1) + { + common->acceptlabel = NULL; + common->accept = NULL; + altbacktrack.top = NULL; + altbacktrack.topbacktracks = NULL; + + if (*ccbegin == OP_ALT) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + altbacktrack.cc = ccbegin; + compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->leavelabel = save_leavelabel; + common->acceptlabel = save_acceptlabel; + common->leave = save_leave; + common->accept = save_accept; + return NULL; + } + common->acceptlabel = LABEL(); + if (common->accept != NULL) + set_jumps(common->accept, common->acceptlabel); + + /* Reset stack. */ + if (framesize < 0) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + else { + if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); + } + else + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + } + + if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) + { + /* We know that STR_PTR was stored on the top of the stack. */ + if (conditional) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (bra == OP_BRAZERO) + { + if (framesize < 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else if (framesize >= 0) + { + /* For OP_BRA and OP_BRAMINZERO. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + } + } + add_jump(compiler, found, JUMP(SLJIT_JUMP)); + + compile_backtrackpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->leavelabel = save_leavelabel; + common->acceptlabel = save_acceptlabel; + common->leave = save_leave; + common->accept = save_accept; + return NULL; + } + set_jumps(altbacktrack.topbacktracks, LABEL()); + + if (*cc != OP_ALT) + break; + + ccbegin = cc; + cc += GET(cc, 1); + } +/* None of them matched. */ +if (common->leave != NULL) + set_jumps(common->leave, LABEL()); + +if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) + { + /* Assert is failed. */ + if (conditional || bra == OP_BRAZERO) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + if (framesize < 0) + { + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + else + free_stack(common, 1); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* The topmost item should be 0. */ + if (bra == OP_BRAZERO) + { + free_stack(common, framesize + 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + jump = JUMP(SLJIT_JUMP); + if (bra != OP_BRAZERO) + add_jump(compiler, target, jump); + + /* Assert is successful. */ + set_jumps(tmp, LABEL()); + if (framesize < 0) + { + /* We know that STR_PTR was stored on the top of the stack. */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + /* Keep the STR_PTR on the top of the stack. */ + if (bra == OP_BRAZERO) + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + else if (bra == OP_BRAMINZERO) + { + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + else + { + if (bra == OP_BRA) + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); + } + else + { + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); + } + } + + if (bra == OP_BRAZERO) + { + backtrack->trypath = LABEL(); + sljit_set_label(jump, backtrack->trypath); + } + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->trypath); + JUMPHERE(brajump); + if (framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + } + set_jumps(backtrack->common.topbacktracks, LABEL()); + } + } +else + { + /* AssertNot is successful. */ + if (framesize < 0) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra != OP_BRA) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + else + free_stack(common, 1); + } + else + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* The topmost item should be 0. */ + if (bra != OP_BRA) + { + free_stack(common, framesize + 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + else + free_stack(common, framesize + 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + + if (bra == OP_BRAZERO) + backtrack->trypath = LABEL(); + else if (bra == OP_BRAMINZERO) + { + JUMPTO(SLJIT_JUMP, backtrack->trypath); + JUMPHERE(brajump); + } + + if (bra != OP_BRA) + { + SLJIT_ASSERT(found == &backtrack->common.topbacktracks); + set_jumps(backtrack->common.topbacktracks, LABEL()); + backtrack->common.topbacktracks = NULL; + } + } + +common->leavelabel = save_leavelabel; +common->acceptlabel = save_acceptlabel; +common->leave = save_leave; +common->accept = save_accept; +return cc + 1 + LINK_SIZE; +} + +static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table) +{ +int condition = FALSE; +pcre_uchar *slotA = name_table; +pcre_uchar *slotB; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w no_capture; +int i; + +locals += refno & 0xff; +refno >>= 8; +no_capture = locals[1]; + +for (i = 0; i < name_count; i++) + { + if (GET2(slotA, 0) == refno) break; + slotA += name_entry_size; + } + +if (i < name_count) + { + /* Found a name for the number - there can be only one; duplicate names + for different numbers are allowed, but not vice versa. First scan down + for duplicates. */ + + slotB = slotA; + while (slotB > name_table) + { + slotB -= name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = locals[GET2(slotB, 0) << 1] != no_capture; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + if (!condition) + { + slotB = slotA; + for (i++; i < name_count; i++) + { + slotB += name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = locals[GET2(slotB, 0) << 1] != no_capture; + if (condition) break; + } + else break; + } + } + } +return condition; +} + +static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table) +{ +int condition = FALSE; +pcre_uchar *slotA = name_table; +pcre_uchar *slotB; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)]; +int i; + +for (i = 0; i < name_count; i++) + { + if (GET2(slotA, 0) == recno) break; + slotA += name_entry_size; + } + +if (i < name_count) + { + /* Found a name for the number - there can be only one; duplicate + names for different numbers are allowed, but not vice versa. First + scan down for duplicates. */ + + slotB = slotA; + while (slotB > name_table) + { + slotB -= name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = GET2(slotB, 0) == group_num; + if (condition) break; + } + else break; + } + + /* Scan up for duplicates */ + if (!condition) + { + slotB = slotA; + for (i++; i < name_count; i++) + { + slotB += name_entry_size; + if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) + { + condition = GET2(slotB, 0) == group_num; + if (condition) break; + } + else break; + } + } + } +return condition; +} + +/* + Handling bracketed expressions is probably the most complex part. + + Stack layout naming characters: + S - Push the current STR_PTR + 0 - Push a 0 (NULL) + A - Push the current STR_PTR. Needed for restoring the STR_PTR + before the next alternative. Not pushed if there are no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. + L - Push the previous local (pointed by localptr) to the stack + () - opional values stored on the stack + ()* - optonal, can be stored multiple times + + The following list shows the regular expression templates, their PCRE byte codes + and stack layout supported by pcre-sljit. + + (?:) OP_BRA | OP_KET A M + () OP_CBRA | OP_KET C M + (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )* + OP_SBRA | OP_KETRMAX 0 L M S ( L M S )* + (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )* + OP_SBRA | OP_KETRMIN 0 L M S ( L M S )* + ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )* + ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )* + OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )* + (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 ) + (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 ) + ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 ) + ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 ) + (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )* + OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )* + (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )* + OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )* + ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )* + OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )* + ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )* + OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )* + + + Stack layout naming characters: + A - Push the alternative index (starting from 0) on the stack. + Not pushed if there is no alternatives. + M - Any values pushed by the current alternative. Can be empty, or anything. + + The next list shows the possible content of a bracket: + (|) OP_*BRA | OP_ALT ... M A + (?()|) OP_*COND | OP_ALT M A + (?>|) OP_ONCE | OP_ALT ... [stack trace] M A + (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A + Or nothing, if trace is unnecessary +*/ + +static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode; +int localptr = 0; +int offset = 0; +int stacksize; +pcre_uchar *ccbegin; +pcre_uchar *trypath; +pcre_uchar bra = OP_BRA; +pcre_uchar ket; +assert_backtrack *assert; +BOOL has_alternatives; +struct sljit_jump *jump; +struct sljit_jump *skip; +struct sljit_label *rmaxlabel = NULL; +struct sljit_jump *braminzerojump = NULL; + +PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + opcode = *cc; + } + +opcode = *cc; +ccbegin = cc; +trypath = ccbegin + 1 + LINK_SIZE; + +if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) + { + /* Drop this bracket_backtrack. */ + parent->top = backtrack->prev; + return bracketend(cc); + } + +ket = *(bracketend(cc) - 1 - LINK_SIZE); +SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); +SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); +cc += GET(cc, 1); + +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE; + if (*trypath == OP_NRREF) + { + stacksize = GET2(trypath, 1); + if (common->currententry == NULL || stacksize == RREF_ANY) + has_alternatives = FALSE; + else if (common->currententry->start == 0) + has_alternatives = stacksize != 0; + else + has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + } + } + +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Capturing brackets has a pre-allocated space. */ + offset = GET2(ccbegin, 1 + LINK_SIZE); + localptr = OVECTOR_PRIV(offset); + offset <<= 1; + BACKTRACK_AS(bracket_backtrack)->localptr = localptr; + trypath += IMM2_SIZE; + } +else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Other brackets simply allocate the next entry. */ + localptr = PRIV_DATA(ccbegin); + SLJIT_ASSERT(localptr != 0); + BACKTRACK_AS(bracket_backtrack)->localptr = localptr; + if (opcode == OP_ONCE) + BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); + } + +/* Instructions before the first alternative. */ +stacksize = 0; +if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + stacksize++; +if (bra == OP_BRAZERO) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (bra == OP_BRAZERO) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + +if (bra == OP_BRAMINZERO) + { + /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (ket != OP_KETRMIN) + { + free_stack(common, 1); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + else + { + if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* Nothing stored during the first run. */ + skip = JUMP(SLJIT_JUMP); + JUMPHERE(jump); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) + { + /* When we come from outside, localptr contains the previous STR_PTR. */ + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + } + else + { + /* Except when the whole stack frame must be saved. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w)); + } + JUMPHERE(skip); + } + else + { + jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPHERE(jump); + } + } + } + +if (ket == OP_KETRMIN) + BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); + +if (ket == OP_KETRMAX) + { + rmaxlabel = LABEL(); + if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) + BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel; + } + +/* Handling capturing brackets and alternatives. */ +if (opcode == OP_ONCE) + { + if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) + { + /* Neither capturing brackets nor recursions are not found in the block. */ + if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + else if (ket == OP_KETRMAX || has_alternatives) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + } + else + { + if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) + { + allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); + } + else + { + allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); + } + } + } +else if (opcode == OP_CBRA || opcode == OP_SCBRA) + { + /* Saving the previous values. */ + allocate_stack(common, 3); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + /* Saving the previous value. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + } +else if (has_alternatives) + { + /* Pushing the starting string pointer. */ + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + +/* Generating code for the first alternative. */ +if (opcode == OP_COND || opcode == OP_SCOND) + { + if (*trypath == OP_CREF) + { + SLJIT_ASSERT(has_alternatives); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), + CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + trypath += 1 + IMM2_SIZE; + } + else if (*trypath == OP_NCREF) + { + SLJIT_ASSERT(has_alternatives); + stacksize = GET2(trypath, 1); + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); + + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w))); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + + JUMPHERE(jump); + trypath += 1 + IMM2_SIZE; + } + else if (*trypath == OP_RREF || *trypath == OP_NRREF) + { + /* Never has other case. */ + BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; + + stacksize = GET2(trypath, 1); + if (common->currententry == NULL) + stacksize = 0; + else if (stacksize == RREF_ANY) + stacksize = 1; + else if (common->currententry->start == 0) + stacksize = stacksize == 0; + else + stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + + if (*trypath == OP_RREF || stacksize || common->currententry == NULL) + { + SLJIT_ASSERT(!has_alternatives); + if (stacksize != 0) + trypath += 1 + IMM2_SIZE; + else + { + if (*cc == OP_ALT) + { + trypath = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } + else + trypath = cc; + } + } + else + { + SLJIT_ASSERT(has_alternatives); + + stacksize = GET2(trypath, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); + sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + trypath += 1 + IMM2_SIZE; + } + } + else + { + SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT); + /* Similar code as PUSH_BACKTRACK macro. */ + assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + memset(assert, 0, sizeof(assert_backtrack)); + assert->common.cc = trypath; + BACKTRACK_AS(bracket_backtrack)->u.assert = assert; + trypath = compile_assert_trypath(common, trypath, assert, TRUE); + } + } + +compile_trypath(common, trypath, cc, backtrack); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + +if (opcode == OP_ONCE) + { + if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + /* TMP2 which is set here used by OP_KETRMAX below. */ + if (ket == OP_KETRMAX) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (ket == OP_KETRMIN) + { + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); + } + } + else + { + stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w)); + if (ket == OP_KETRMAX) + { + /* TMP2 which is set here used by OP_KETRMAX below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + } + } + +stacksize = 0; +if (ket != OP_KET || bra != OP_BRA) + stacksize++; +if (has_alternatives && opcode != OP_ONCE) + stacksize++; + +if (stacksize > 0) + allocate_stack(common, stacksize); + +stacksize = 0; +if (ket != OP_KET) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + stacksize++; + } +else if (bra != OP_BRA) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + +if (has_alternatives) + { + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + if (ket != OP_KETRMAX) + BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); + } + +/* Must be after the trypath label. */ +if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); + } + +if (ket == OP_KETRMAX) + { + if (opcode == OP_ONCE || opcode >= OP_SBRA) + { + if (has_alternatives) + BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE) + { + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); + /* Drop STR_PTR for greedy plus quantifier. */ + if (bra != OP_BRAZERO) + free_stack(common, 1); + } + else + /* TMP2 must contain the starting STR_PTR. */ + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel); + } + else + JUMPTO(SLJIT_JUMP, rmaxlabel); + BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); + } + +if (bra == OP_BRAZERO) + BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL(); + +if (bra == OP_BRAMINZERO) + { + /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ + JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath); + if (braminzerojump != NULL) + { + JUMPHERE(braminzerojump); + /* We need to release the end pointer to perform the + backtrack for the zero-length iteration. When + framesize is < 0, OP_ONCE will do the release itself. */ + if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + else if (ket == OP_KETRMIN && opcode != OP_ONCE) + free_stack(common, 1); + } + /* Continue to the normal backtrack. */ + } + +if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) + decrease_call_count(common); + +/* Skip the other alternatives. */ +while (*cc == OP_ALT) + cc += GET(cc, 1); +cc += 1 + LINK_SIZE; +return cc; +} + +static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode; +int localptr; +int cbraprivptr = 0; +int framesize; +int stacksize; +int offset = 0; +BOOL zero = FALSE; +pcre_uchar *ccbegin = NULL; +int stack; +struct sljit_label *loop = NULL; +struct jump_list *emptymatch = NULL; + +PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); +if (*cc == OP_BRAPOSZERO) + { + zero = TRUE; + cc++; + } + +opcode = *cc; +localptr = PRIV_DATA(cc); +SLJIT_ASSERT(localptr != 0); +BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr; +switch(opcode) + { + case OP_BRAPOS: + case OP_SBRAPOS: + ccbegin = cc + 1 + LINK_SIZE; + break; + + case OP_CBRAPOS: + case OP_SCBRAPOS: + offset = GET2(cc, 1 + LINK_SIZE); + cbraprivptr = OVECTOR_PRIV(offset); + offset <<= 1; + ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +framesize = get_framesize(common, cc, FALSE); +BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; +if (framesize < 0) + { + stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; + if (!zero) + stacksize++; + BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; + allocate_stack(common, stacksize); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); + + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + } + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); + } +else + { + stacksize = framesize + 1; + if (!zero) + stacksize++; + if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + stacksize++; + BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; + allocate_stack(common, stacksize); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); + stack = 0; + if (!zero) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); + stack++; + } + if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); + stack++; + } + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); + init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); + } + +if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + +loop = LABEL(); +while (*cc != OP_KETRPOS) + { + backtrack->top = NULL; + backtrack->topbacktracks = NULL; + cc += GET(cc, 1); + + compile_trypath(common, ccbegin, cc, backtrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + + if (framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + } + else + { + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + } + else + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w)); + if (opcode == OP_SBRAPOS) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0); + } + + if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) + add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); + + if (!zero) + { + if (framesize < 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + } + JUMPTO(SLJIT_JUMP, loop); + flush_stubs(common); + + compile_backtrackpath(common, backtrack->top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return NULL; + set_jumps(backtrack->topbacktracks, LABEL()); + + if (framesize < 0) + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + else + { + if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) + { + /* Last alternative. */ + if (*cc == OP_KETRPOS) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); + } + } + + if (*cc == OP_KETRPOS) + break; + ccbegin = cc + 1 + LINK_SIZE; + } + +backtrack->topbacktracks = NULL; +if (!zero) + { + if (framesize < 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); + else /* TMP2 is set to [localptr] above. */ + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); + } + +/* None of them matched. */ +set_jumps(emptymatch, LABEL()); +decrease_call_count(common); +return cc + 1 + LINK_SIZE; +} + +static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end) +{ +int class_len; + +*opcode = *cc; +if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) + { + cc++; + *type = OP_CHAR; + } +else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI) + { + cc++; + *type = OP_CHARI; + *opcode -= OP_STARI - OP_STAR; + } +else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO) + { + cc++; + *type = OP_NOT; + *opcode -= OP_NOTSTAR - OP_STAR; + } +else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI) + { + cc++; + *type = OP_NOTI; + *opcode -= OP_NOTSTARI - OP_STAR; + } +else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) + { + cc++; + *opcode -= OP_TYPESTAR - OP_STAR; + *type = 0; + } +else + { + SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); + *type = *opcode; + cc++; + class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); + *opcode = cc[class_len - 1]; + if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) + { + *opcode -= OP_CRSTAR - OP_STAR; + if (end != NULL) + *end = cc + class_len; + } + else + { + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE); + *arg1 = GET2(cc, (class_len + IMM2_SIZE)); + *arg2 = GET2(cc, class_len); + + if (*arg2 == 0) + { + SLJIT_ASSERT(*arg1 != 0); + *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO; + } + if (*arg1 == *arg2) + *opcode = OP_EXACT; + + if (end != NULL) + *end = cc + class_len + 2 * IMM2_SIZE; + } + return cc; + } + +if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) + { + *arg1 = GET2(cc, 0); + cc += IMM2_SIZE; + } + +if (*type == 0) + { + *type = *cc; + if (end != NULL) + *end = next_opcode(common, cc); + cc++; + return cc; + } + +if (end != NULL) + { + *end = cc + 1; +#ifdef SUPPORT_UTF + if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); +#endif + } +return cc; +} + +static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; +pcre_uchar opcode; +pcre_uchar type; +int arg1 = -1, arg2 = -1; +pcre_uchar* end; +jump_list *nomatch = NULL; +struct sljit_jump *jump = NULL; +struct sljit_label *label; + +PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); + +switch(opcode) + { + case OP_STAR: + case OP_PLUS: + case OP_UPTO: + case OP_CRRANGE: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + if (opcode == OP_STAR || opcode == OP_UPTO) + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + } + else + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } + if (opcode == OP_UPTO || opcode == OP_CRRANGE) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); + + label = LABEL(); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + if (opcode == OP_UPTO || opcode == OP_CRRANGE) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + if (opcode == OP_CRRANGE && arg2 > 0) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label); + if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0)) + jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + } + + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + if (jump != NULL) + JUMPHERE(jump); + } + else + { + if (opcode == OP_PLUS) + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + label = LABEL(); + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) + { + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + JUMPTO(SLJIT_JUMP, label); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + } + set_jumps(nomatch, LABEL()); + if (opcode == OP_CRRANGE) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); + break; + + case OP_MINSTAR: + case OP_MINPLUS: + if (opcode == OP_MINPLUS) + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); + break; + + case OP_MINUPTO: + case OP_CRMINRANGE: + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); + if (opcode == OP_CRMINRANGE) + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); + break; + + case OP_QUERY: + case OP_MINQUERY: + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode == OP_QUERY) + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); + break; + + case OP_EXACT: + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); + label = LABEL(); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + break; + + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSUPTO: + if (opcode != OP_POSSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + label = LABEL(); + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + if (opcode != OP_POSUPTO) + { + if (opcode == OP_POSPLUS) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2); + JUMPTO(SLJIT_JUMP, label); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); + } + set_jumps(nomatch, LABEL()); + if (opcode == OP_POSPLUS) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + break; + + case OP_POSQUERY: + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + set_jumps(nomatch, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + +decrease_call_count(common); +return end; +} + +static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; + +PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); + +if (*cc == OP_FAIL) + { + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + return cc + 1; + } + +if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL) + { + /* No need to check notempty conditions. */ + if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->acceptlabel); + return cc + 1; + } + +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0))); +else + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); +add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); +else + CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +if (common->acceptlabel == NULL) + add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); +else + CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); +add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); +return cc + 1; +} + +static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc) +{ +DEFINE_COMPILER; +int offset = GET2(cc, 1); + +/* Data will be discarded anyway... */ +if (common->currententry != NULL) + return cc + 1 + IMM2_SIZE; + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); +offset <<= 1; +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); +return cc + 1 + IMM2_SIZE; +} + +static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack; + +while (cc < ccend) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_DIGIT: + case OP_DIGIT: + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + case OP_ANY: + case OP_ALLANY: + case OP_ANYBYTE: + case OP_NOTPROP: + case OP_PROP: + case OP_ANYNL: + case OP_NOT_HSPACE: + case OP_HSPACE: + case OP_NOT_VSPACE: + case OP_VSPACE: + case OP_EXTUNI: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_NOT: + case OP_NOTI: + case OP_REVERSE: + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + + case OP_SET_SOM: + PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + cc++; + break; + + case OP_CHAR: + case OP_CHARI: + if (common->mode == JIT_COMPILE) + cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + else + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + cc = compile_iterator_trypath(common, cc, parent); + break; + + case OP_CLASS: + case OP_NCLASS: + if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) + cc = compile_iterator_trypath(common, cc, parent); + else + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 + case OP_XCLASS: + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) + cc = compile_iterator_trypath(common, cc, parent); + else + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; +#endif + + case OP_REF: + case OP_REFI: + if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) + cc = compile_ref_iterator_trypath(common, cc, parent); + else + cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + break; + + case OP_RECURSE: + cc = compile_recurse_trypath(common, cc, parent); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); + cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + break; + + case OP_BRAMINZERO: + PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); + cc = bracketend(cc + 1); + if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) + { + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + } + else + { + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); + } + BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL(); + if (cc[1] > OP_ASSERTBACK_NOT) + decrease_call_count(common); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + cc = compile_bracket_trypath(common, cc, parent); + break; + + case OP_BRAZERO: + if (cc[1] > OP_ASSERTBACK_NOT) + cc = compile_bracket_trypath(common, cc, parent); + else + { + PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); + cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + } + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + cc = compile_bracketpos_trypath(common, cc, parent); + break; + + case OP_MARK: + PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); + SLJIT_ASSERT(common->mark_ptr != 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); + allocate_stack(common, 1); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); + cc += 1 + 2 + cc[1]; + break; + + case OP_COMMIT: + PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); + cc += 1; + break; + + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + cc = compile_fail_accept_trypath(common, cc, parent); + break; + + case OP_CLOSE: + cc = compile_close_trypath(common, cc); + break; + + case OP_SKIPZERO: + cc = bracketend(cc + 1); + break; + + default: + SLJIT_ASSERT_STOP(); + return; + } + if (cc == NULL) + return; + } +SLJIT_ASSERT(cc == ccend); +} + +#undef PUSH_BACKTRACK +#undef PUSH_BACKTRACK_NOVALUE +#undef BACKTRACK_AS + +#define COMPILE_BACKTRACKPATH(current) \ + do \ + { \ + compile_backtrackpath(common, (current)); \ + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ + return; \ + } \ + while (0) + +#define CURRENT_AS(type) ((type *)current) + +static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +pcre_uchar *cc = current->cc; +pcre_uchar opcode; +pcre_uchar type; +int arg1 = -1, arg2 = -1; +struct sljit_label *label = NULL; +struct sljit_jump *jump = NULL; +jump_list *jumplist = NULL; + +cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); + +switch(opcode) + { + case OP_STAR: + case OP_PLUS: + case OP_UPTO: + case OP_CRRANGE: + if (type == OP_ANYNL || type == OP_EXTUNI) + { + set_jumps(current->topbacktracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); + } + else + { + if (opcode <= OP_PLUS || opcode == OP_UPTO) + arg2 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + skip_char_back(common); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); + if (opcode == OP_CRRANGE) + set_jumps(current->topbacktracks, LABEL()); + JUMPHERE(jump); + free_stack(common, 2); + if (opcode == OP_PLUS) + set_jumps(current->topbacktracks, LABEL()); + } + break; + + case OP_MINSTAR: + case OP_MINPLUS: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + compile_char1_trypath(common, type, cc, &jumplist); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); + set_jumps(jumplist, LABEL()); + free_stack(common, 1); + if (opcode == OP_MINPLUS) + set_jumps(current->topbacktracks, LABEL()); + break; + + case OP_MINUPTO: + case OP_CRMINRANGE: + if (opcode == OP_CRMINRANGE) + { + label = LABEL(); + set_jumps(current->topbacktracks, label); + } + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + compile_char1_trypath(common, type, cc, &jumplist); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + + if (opcode == OP_CRMINRANGE) + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); + + if (opcode == OP_CRMINRANGE && arg1 == 0) + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); + else + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath); + + set_jumps(jumplist, LABEL()); + free_stack(common, 2); + break; + + case OP_QUERY: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topbacktracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); + JUMPHERE(jump); + free_stack(common, 1); + break; + + case OP_MINQUERY: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_trypath(common, type, cc, &jumplist); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); + set_jumps(jumplist, LABEL()); + JUMPHERE(jump); + free_stack(common, 1); + break; + + case OP_EXACT: + case OP_POSPLUS: + set_jumps(current->topbacktracks, LABEL()); + break; + + case OP_POSSTAR: + case OP_POSQUERY: + case OP_POSUPTO: + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } +} + +static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +pcre_uchar *cc = current->cc; +pcre_uchar type; + +type = cc[1 + IMM2_SIZE]; +if ((type & 0x1) == 0) + { + set_jumps(current->topbacktracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); + return; + } + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); +CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); +set_jumps(current->topbacktracks, LABEL()); +free_stack(common, 2); +} + +static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; + +set_jumps(current->topbacktracks, LABEL()); + +if (common->has_set_som && common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); + } +else if (common->has_set_som || common->mark_ptr != 0) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); + } +} + +static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +pcre_uchar *cc = current->cc; +pcre_uchar bra = OP_BRA; +struct sljit_jump *brajump = NULL; + +SLJIT_ASSERT(*cc != OP_BRAMINZERO); +if (*cc == OP_BRAZERO) + { + bra = *cc; + cc++; + } + +if (bra == OP_BRAZERO) + { + SLJIT_ASSERT(current->topbacktracks == NULL); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + +if (CURRENT_AS(assert_backtrack)->framesize < 0) + { + set_jumps(current->topbacktracks, LABEL()); + + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); + free_stack(common, 1); + } + return; + } + +if (bra == OP_BRAZERO) + { + if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); + free_stack(common, 1); + return; + } + free_stack(common, 1); + brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + } + +if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w)); + + set_jumps(current->topbacktracks, LABEL()); + } +else + set_jumps(current->topbacktracks, LABEL()); + +if (bra == OP_BRAZERO) + { + /* We know there is enough place on the stack. */ + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath); + JUMPHERE(brajump); + } +} + +static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +int opcode; +int offset = 0; +int localptr = CURRENT_AS(bracket_backtrack)->localptr; +int stacksize; +int count; +pcre_uchar *cc = current->cc; +pcre_uchar *ccbegin; +pcre_uchar *ccprev; +jump_list *jumplist = NULL; +jump_list *jumplistitem = NULL; +pcre_uchar bra = OP_BRA; +pcre_uchar ket; +assert_backtrack *assert; +BOOL has_alternatives; +struct sljit_jump *brazero = NULL; +struct sljit_jump *once = NULL; +struct sljit_jump *cond = NULL; +struct sljit_label *rminlabel = NULL; + +if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) + { + bra = *cc; + cc++; + } + +opcode = *cc; +ccbegin = cc; +ket = *(bracketend(ccbegin) - 1 - LINK_SIZE); +cc += GET(cc, 1); +has_alternatives = *cc == OP_ALT; +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; +if (opcode == OP_CBRA || opcode == OP_SCBRA) + offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; +if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) + opcode = OP_SCOND; +if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) + opcode = OP_ONCE; + +if (ket == OP_KETRMAX) + { + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } + } +else if (ket == OP_KETRMIN) + { + if (bra != OP_BRAMINZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (opcode >= OP_SBRA || opcode == OP_ONCE) + { + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath); + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath); + } + if (opcode != OP_ONCE) + free_stack(common, 1); + } + else + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath); + } + rminlabel = LABEL(); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); + } + +if (SLJIT_UNLIKELY(opcode == OP_ONCE)) + { + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + } + once = JUMP(SLJIT_JUMP); + } +else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + if (has_alternatives) + { + /* Always exactly one alternative. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + + jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); + if (SLJIT_UNLIKELY(!jumplistitem)) + return; + jumplist = jumplistitem; + jumplistitem->next = NULL; + jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1); + } + } +else if (*cc == OP_ALT) + { + /* Build a jump list. Get the last successfully matched branch index. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + count = 1; + do + { + /* Append as the last item. */ + if (jumplist != NULL) + { + jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list)); + jumplistitem = jumplistitem->next; + } + else + { + jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list)); + jumplist = jumplistitem; + } + + if (SLJIT_UNLIKELY(!jumplistitem)) + return; + + jumplistitem->next = NULL; + jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++); + cc += GET(cc, 1); + } + while (*cc == OP_ALT); + + cc = ccbegin + GET(ccbegin, 1); + } + +COMPILE_BACKTRACKPATH(current->top); +if (current->topbacktracks) + set_jumps(current->topbacktracks, LABEL()); + +if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) + { + /* Conditional block always has at most one alternative. */ + if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) + { + SLJIT_ASSERT(has_alternatives); + assert = CURRENT_AS(bracket_backtrack)->u.assert; + if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); + } + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); + } + else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) + { + SLJIT_ASSERT(has_alternatives); + cond = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); + } + else + SLJIT_ASSERT(!has_alternatives); + } + +if (has_alternatives) + { + count = 1; + do + { + current->top = NULL; + current->topbacktracks = NULL; + current->nextbacktracks = NULL; + if (*cc == OP_ALT) + { + ccprev = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + if (opcode != OP_COND && opcode != OP_SCOND) + { + if (localptr != 0 && opcode != OP_ONCE) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + compile_trypath(common, ccprev, cc, current); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + return; + } + + /* Instructions after the current alternative is succesfully matched. */ + /* There is a similar code in compile_bracket_trypath. */ + if (opcode == OP_ONCE) + { + if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + /* TMP2 which is set here used by OP_KETRMAX below. */ + if (ket == OP_KETRMAX) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); + else if (ket == OP_KETRMIN) + { + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); + } + } + else + { + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w)); + if (ket == OP_KETRMAX) + { + /* TMP2 which is set here used by OP_KETRMAX below. */ + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + } + } + } + + stacksize = 0; + if (opcode != OP_ONCE) + stacksize++; + if (ket != OP_KET || bra != OP_BRA) + stacksize++; + + if (stacksize > 0) { + if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + allocate_stack(common, stacksize); + else + { + /* We know we have place at least for one item on the top of the stack. */ + SLJIT_ASSERT(stacksize == 1); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); + } + } + + stacksize = 0; + if (ket != OP_KET || bra != OP_BRA) + { + if (ket != OP_KET) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + stacksize++; + } + + if (opcode != OP_ONCE) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); + + if (offset != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); + } + + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath); + + if (opcode != OP_ONCE) + { + SLJIT_ASSERT(jumplist); + JUMPHERE(jumplist->jump); + jumplist = jumplist->next; + } + + COMPILE_BACKTRACKPATH(current->top); + if (current->topbacktracks) + set_jumps(current->topbacktracks, LABEL()); + SLJIT_ASSERT(!current->nextbacktracks); + } + while (*cc == OP_ALT); + SLJIT_ASSERT(!jumplist); + + if (cond != NULL) + { + SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); + assert = CURRENT_AS(bracket_backtrack)->u.assert; + if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) + + { + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); + } + JUMPHERE(cond); + } + + /* Free the STR_PTR. */ + if (localptr == 0) + free_stack(common, 1); + } + +if (offset != 0) + { + /* Using both tmp register is better for instruction scheduling. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); + } +else if (opcode == OP_SBRA || opcode == OP_SCOND) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + } +else if (opcode == OP_ONCE) + { + cc = ccbegin + GET(ccbegin, 1); + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + { + /* Reset head and drop saved frame. */ + stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; + free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize); + } + else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) + { + /* The STR_PTR must be released. */ + free_stack(common, 1); + } + + JUMPHERE(once); + /* Restore previous localptr */ + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w)); + else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* See the comment below. */ + free_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); + } + } + +if (ket == OP_KETRMAX) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra != OP_BRAZERO) + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath); + if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); + JUMPHERE(brazero); + free_stack(common, 1); + } + } +else if (ket == OP_KETRMIN) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + /* OP_ONCE removes everything in case of a backtrack, so we don't + need to explicitly release the STR_PTR. The extra release would + affect badly the free_stack(2) above. */ + if (opcode != OP_ONCE) + free_stack(common, 1); + CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel); + if (opcode == OP_ONCE) + free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); + else if (bra == OP_BRAMINZERO) + free_stack(common, 1); + } +else if (bra == OP_BRAZERO) + { + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); + JUMPHERE(brazero); + } +} + +static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +int offset; +struct sljit_jump *jump; + +if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) + { + if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) + { + offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + } + set_jumps(current->topbacktracks, LABEL()); + free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); + return; + } + +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr); +add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + +if (current->topbacktracks) + { + jump = JUMP(SLJIT_JUMP); + set_jumps(current->topbacktracks, LABEL()); + /* Drop the stack frame. */ + free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); + JUMPHERE(jump); + } +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w)); +} + +static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +assert_backtrack backtrack; + +current->top = NULL; +current->topbacktracks = NULL; +current->nextbacktracks = NULL; +if (current->cc[1] > OP_ASSERTBACK_NOT) + { + /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */ + compile_bracket_trypath(common, current->cc, current); + compile_bracket_backtrackpath(common, current->top); + } +else + { + memset(&backtrack, 0, sizeof(backtrack)); + backtrack.common.cc = current->cc; + backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath; + /* Manual call of compile_assert_trypath. */ + compile_assert_trypath(common, current->cc, &backtrack, FALSE); + } +SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); +} + +static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; + +while (current) + { + if (current->nextbacktracks != NULL) + set_jumps(current->nextbacktracks, LABEL()); + switch(*current->cc) + { + case OP_SET_SOM: + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0); + break; + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEEXACT: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + case OP_TYPEPOSQUERY: + case OP_TYPEPOSUPTO: + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: +#endif + compile_iterator_backtrackpath(common, current); + break; + + case OP_REF: + case OP_REFI: + compile_ref_iterator_backtrackpath(common, current); + break; + + case OP_RECURSE: + compile_recurse_backtrackpath(common, current); + break; + + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + compile_assert_backtrackpath(common, current); + break; + + case OP_ONCE: + case OP_ONCE_NC: + case OP_BRA: + case OP_CBRA: + case OP_COND: + case OP_SBRA: + case OP_SCBRA: + case OP_SCOND: + compile_bracket_backtrackpath(common, current); + break; + + case OP_BRAZERO: + if (current->cc[1] > OP_ASSERTBACK_NOT) + compile_bracket_backtrackpath(common, current); + else + compile_assert_backtrackpath(common, current); + break; + + case OP_BRAPOS: + case OP_CBRAPOS: + case OP_SBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOSZERO: + compile_bracketpos_backtrackpath(common, current); + break; + + case OP_BRAMINZERO: + compile_braminzero_backtrackpath(common, current); + break; + + case OP_MARK: + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + free_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); + break; + + case OP_COMMIT: + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); + if (common->leavelabel == NULL) + add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); + else + JUMPTO(SLJIT_JUMP, common->leavelabel); + break; + + case OP_FAIL: + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + set_jumps(current->topbacktracks, LABEL()); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + current = current->prev; + } +} + +static SLJIT_INLINE void compile_recurse(compiler_common *common) +{ +DEFINE_COMPILER; +pcre_uchar *cc = common->start + common->currententry->start; +pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); +pcre_uchar *ccend = bracketend(cc); +int localsize = get_localsize(common, ccbegin, ccend); +int framesize = get_framesize(common, cc, TRUE); +int alternativesize; +BOOL needsframe; +backtrack_common altbacktrack; +struct sljit_label *save_leavelabel = common->leavelabel; +jump_list *save_leave = common->leave; +struct sljit_jump *jump; + +SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); +needsframe = framesize >= 0; +if (!needsframe) + framesize = 0; +alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; + +SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); +common->currententry->entry = LABEL(); +set_jumps(common->currententry->calls, common->currententry->entry); + +sljit_emit_fast_enter(compiler, TMP2, 0); +allocate_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); +copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0); +if (needsframe) + init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); + +if (alternativesize > 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + +memset(&altbacktrack, 0, sizeof(backtrack_common)); +common->leavelabel = NULL; +common->acceptlabel = NULL; +common->leave = NULL; +common->accept = NULL; +altbacktrack.cc = ccbegin; +cc += GET(cc, 1); +while (1) + { + altbacktrack.top = NULL; + altbacktrack.topbacktracks = NULL; + + if (altbacktrack.cc != ccbegin) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + + compile_trypath(common, altbacktrack.cc, cc, &altbacktrack); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->leavelabel = save_leavelabel; + common->leave = save_leave; + return; + } + + add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); + + compile_backtrackpath(common, altbacktrack.top); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + common->leavelabel = save_leavelabel; + common->leave = save_leave; + return; + } + set_jumps(altbacktrack.topbacktracks, LABEL()); + + if (*cc != OP_ALT) + break; + + altbacktrack.cc = cc + 1 + LINK_SIZE; + cc += GET(cc, 1); + } +/* None of them matched. */ +if (common->leave != NULL) + set_jumps(common->leave, LABEL()); + +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_JUMP); + +set_jumps(common->accept, LABEL()); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); +if (needsframe) + { + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); + } +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); + +JUMPHERE(jump); +copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize); +free_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); +OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); +sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); + +common->leavelabel = save_leavelabel; +common->leave = save_leave; +} + +#undef COMPILE_BACKTRACKPATH +#undef CURRENT_AS + +void +PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) +{ +struct sljit_compiler *compiler; +backtrack_common rootbacktrack; +compiler_common common_data; +compiler_common *common = &common_data; +const pcre_uint8 *tables = re->tables; +pcre_study_data *study; +int localsize; +pcre_uchar *ccend; +executable_functions *functions; +void *executable_func; +sljit_uw executable_size; +struct sljit_label *mainloop = NULL; +struct sljit_label *empty_match_found; +struct sljit_label *empty_match_backtrack; +struct sljit_jump *jump; +struct sljit_jump *reqbyte_notfound = NULL; +struct sljit_jump *empty_match; + +SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); +study = extra->study_data; + +if (!tables) + tables = PRIV(default_tables); + +memset(&rootbacktrack, 0, sizeof(backtrack_common)); +memset(common, 0, sizeof(compiler_common)); +rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; + +common->start = rootbacktrack.cc; +common->fcc = tables + fcc_offset; +common->lcc = (sljit_w)(tables + lcc_offset); +common->mode = mode; +common->nltype = NLTYPE_FIXED; +switch(re->options & PCRE_NEWLINE_BITS) + { + case 0: + /* Compile-time default */ + switch (NEWLINE) + { + case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; + case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + default: common->newline = NEWLINE; break; + } + break; + case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; + case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; + case PCRE_NEWLINE_CR+ + PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; + case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; + case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + default: return; + } +if ((re->options & PCRE_BSR_ANYCRLF) != 0) + common->bsr_nltype = NLTYPE_ANYCRLF; +else if ((re->options & PCRE_BSR_UNICODE) != 0) + common->bsr_nltype = NLTYPE_ANY; +else + { +#ifdef BSR_ANYCRLF + common->bsr_nltype = NLTYPE_ANYCRLF; +#else + common->bsr_nltype = NLTYPE_ANY; +#endif + } +common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; +common->ctypes = (sljit_w)(tables + ctypes_offset); +common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); +common->name_count = re->name_count; +common->name_entry_size = re->name_entry_size; +common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; +#ifdef SUPPORT_UTF +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +common->utf = (re->options & PCRE_UTF8) != 0; +#ifdef SUPPORT_UCP +common->use_ucp = (re->options & PCRE_UCP) != 0; +#endif +#endif /* SUPPORT_UTF */ +ccend = bracketend(rootbacktrack.cc); + +/* Calculate the local space size on the stack. */ +common->ovector_start = CALL_LIMIT + sizeof(sljit_w); + +SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); +localsize = get_localspace(common, rootbacktrack.cc, ccend); +if (localsize < 0) + return; + +/* Checking flags and updating ovector_start. */ +if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + common->req_char_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + } +if (mode != JIT_COMPILE) + { + common->start_used_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + if (mode == JIT_PARTIAL_SOFT_COMPILE) + { + common->hit_start = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + } + } +if ((re->options & PCRE_FIRSTLINE) != 0) + { + common->first_line_end = common->ovector_start; + common->ovector_start += sizeof(sljit_w); + } + +/* Aligning ovector to even number of sljit words. */ +if ((common->ovector_start & sizeof(sljit_w)) != 0) + common->ovector_start += sizeof(sljit_w); + +SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); +common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); +localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); +if (localsize > SLJIT_MAX_LOCAL_SIZE) + return; +common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); +if (!common->localptrs) + return; +memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); +set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); + +compiler = sljit_create_compiler(); +if (!compiler) + { + SLJIT_FREE(common->localptrs); + return; + } +common->compiler = compiler; + +/* Main pcre_jit_exec entry. */ +sljit_emit_enter(compiler, 1, 5, 5, localsize); + +/* Register init. */ +reset_ovector(common, (re->top_bracket + 1) * 2); +if (common->req_char_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); + +OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); + +if (mode == JIT_PARTIAL_SOFT_COMPILE) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); + +/* Main part of the matching */ +if ((re->options & PCRE_ANCHORED) == 0) + { + mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); + /* Forward search if possible. */ + if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + if ((re->flags & PCRE_FIRSTSET) != 0) + fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); + else if ((re->flags & PCRE_STARTLINE) != 0) + fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); + else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) + fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); + } + } +if (common->req_char_ptr != 0) + reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); + +/* Store the current STR_PTR in OVECTOR(0). */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); +/* Copy the limit of allowed recursions. */ +OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); +if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); +/* Copy the beginning of the string. */ +if (mode == JIT_PARTIAL_SOFT_COMPILE) + { + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + JUMPHERE(jump); + } +else if (mode == JIT_PARTIAL_HARD_COMPILE) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); + +compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + +empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); +empty_match_found = LABEL(); + +common->acceptlabel = LABEL(); +if (common->accept != NULL) + set_jumps(common->accept, common->acceptlabel); + +/* This means we have a match. Update the ovector. */ +copy_ovector(common, re->top_bracket + 1); +common->leavelabel = LABEL(); +if (common->leave != NULL) + set_jumps(common->leave, common->leavelabel); +sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); + +if (mode != JIT_COMPILE) + { + common->partialmatchlabel = LABEL(); + set_jumps(common->partialmatch, common->partialmatchlabel); + return_with_partial_match(common, common->leavelabel); + } + +empty_match_backtrack = LABEL(); +compile_backtrackpath(common, rootbacktrack.top); +if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + +SLJIT_ASSERT(rootbacktrack.prev == NULL); + +if (mode == JIT_PARTIAL_SOFT_COMPILE) + { + /* Update hit_start only in the first time. */ + jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); + JUMPHERE(jump); + } + +/* Check we have remaining characters. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); + +if ((re->options & PCRE_ANCHORED) == 0) + { + if ((re->options & PCRE_FIRSTLINE) == 0) + { + if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); + } + else + CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); + } + else + { + SLJIT_ASSERT(common->first_line_end != 0); + if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); + JUMPTO(SLJIT_C_ZERO, mainloop); + } + else + CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop); + } + } + +/* No more remaining characters. */ +if (reqbyte_notfound != NULL) + JUMPHERE(reqbyte_notfound); + +if (mode == JIT_PARTIAL_SOFT_COMPILE) + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); + +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); +JUMPTO(SLJIT_JUMP, common->leavelabel); + +flush_stubs(common); + +JUMPHERE(empty_match); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); +CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); +CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); +CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); +JUMPTO(SLJIT_JUMP, empty_match_backtrack); + +common->currententry = common->entries; +while (common->currententry != NULL) + { + /* Might add new entries. */ + compile_recurse(common); + if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) + { + sljit_free_compiler(compiler); + SLJIT_FREE(common->localptrs); + return; + } + flush_stubs(common); + common->currententry = common->currententry->next; + } + +/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ +/* This is a (really) rare case. */ +set_jumps(common->stackalloc, LABEL()); +/* RETURN_ADDR is not a saved register. */ +sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0); +OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); + +sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); +jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); +OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); +sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); + +/* Allocation failed. */ +JUMPHERE(jump); +/* We break the return address cache here, but this is a really rare case. */ +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); +JUMPTO(SLJIT_JUMP, common->leavelabel); + +/* Call limit reached. */ +set_jumps(common->calllimit, LABEL()); +OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); +JUMPTO(SLJIT_JUMP, common->leavelabel); + +if (common->revertframes != NULL) + { + set_jumps(common->revertframes, LABEL()); + do_revertframes(common); + } +if (common->wordboundary != NULL) + { + set_jumps(common->wordboundary, LABEL()); + check_wordboundary(common); + } +if (common->anynewline != NULL) + { + set_jumps(common->anynewline, LABEL()); + check_anynewline(common); + } +if (common->hspace != NULL) + { + set_jumps(common->hspace, LABEL()); + check_hspace(common); + } +if (common->vspace != NULL) + { + set_jumps(common->vspace, LABEL()); + check_vspace(common); + } +if (common->casefulcmp != NULL) + { + set_jumps(common->casefulcmp, LABEL()); + do_casefulcmp(common); + } +if (common->caselesscmp != NULL) + { + set_jumps(common->caselesscmp, LABEL()); + do_caselesscmp(common); + } +#ifdef SUPPORT_UTF +if (common->utfreadchar != NULL) + { + set_jumps(common->utfreadchar, LABEL()); + do_utfreadchar(common); + } +#ifdef COMPILE_PCRE8 +if (common->utfreadtype8 != NULL) + { + set_jumps(common->utfreadtype8, LABEL()); + do_utfreadtype8(common); + } +#endif +#endif /* COMPILE_PCRE8 */ +#ifdef SUPPORT_UCP +if (common->getucd != NULL) + { + set_jumps(common->getucd, LABEL()); + do_getucd(common); + } +#endif + +SLJIT_FREE(common->localptrs); +executable_func = sljit_generate_code(compiler); +executable_size = sljit_get_generated_code_size(compiler); +sljit_free_compiler(compiler); +if (executable_func == NULL) + return; + +/* Reuse the function descriptor if possible. */ +if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) + functions = (executable_functions *)extra->executable_jit; +else + { + functions = SLJIT_MALLOC(sizeof(executable_functions)); + if (functions == NULL) + { + /* This case is highly unlikely since we just recently + freed a lot of memory. Although not impossible. */ + sljit_free_code(executable_func); + return; + } + memset(functions, 0, sizeof(executable_functions)); + extra->executable_jit = functions; + extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; + } + +functions->executable_funcs[mode] = executable_func; +functions->executable_sizes[mode] = executable_size; +} + +static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) +{ +union { + void* executable_func; + jit_function call_executable_func; +} convert_executable_func; +pcre_uint8 local_area[LOCAL_SPACE_SIZE]; +struct sljit_stack local_stack; + +local_stack.top = (sljit_w)&local_area; +local_stack.base = local_stack.top; +local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; +local_stack.max_limit = local_stack.limit; +arguments->stack = &local_stack; +convert_executable_func.executable_func = executable_func; +return convert_executable_func.call_executable_func(arguments); +} + +int +PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, + int length, int start_offset, int options, int *offsets, int offsetcount) +{ +executable_functions *functions = (executable_functions *)extra_data->executable_jit; +union { + void* executable_func; + jit_function call_executable_func; +} convert_executable_func; +jit_arguments arguments; +int maxoffsetcount; +int retval; +int mode = JIT_COMPILE; + +if ((options & PCRE_PARTIAL_HARD) != 0) + mode = JIT_PARTIAL_HARD_COMPILE; +else if ((options & PCRE_PARTIAL_SOFT) != 0) + mode = JIT_PARTIAL_SOFT_COMPILE; + +if (functions->executable_funcs[mode] == NULL) + return PCRE_ERROR_NULL; + +/* Sanity checks should be handled by pcre_exec. */ +arguments.stack = NULL; +arguments.str = subject + start_offset; +arguments.begin = subject; +arguments.end = subject + length; +arguments.mark_ptr = NULL; +/* JIT decreases this value less frequently than the interpreter. */ +arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; +arguments.notbol = (options & PCRE_NOTBOL) != 0; +arguments.noteol = (options & PCRE_NOTEOL) != 0; +arguments.notempty = (options & PCRE_NOTEMPTY) != 0; +arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; +arguments.offsets = offsets; + +/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of +the output vector for storing captured strings, with the remainder used as +workspace. We don't need the workspace here. For compatibility, we limit the +number of captured strings in the same way as pcre_exec(), so that the user +gets the same result with and without JIT. */ + +if (offsetcount != 2) + offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; +maxoffsetcount = (re->top_bracket + 1) * 2; +if (offsetcount > maxoffsetcount) + offsetcount = maxoffsetcount; +arguments.offsetcount = offsetcount; + +if (functions->callback) + arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); +else + arguments.stack = (struct sljit_stack *)functions->userdata; + +if (arguments.stack == NULL) + retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); +else + { + convert_executable_func.executable_func = functions->executable_funcs[mode]; + retval = convert_executable_func.call_executable_func(&arguments); + } + +if (retval * 2 > offsetcount) + retval = 0; +if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) + *(extra_data->mark) = arguments.mark_ptr; + +return retval; +} + +void +PRIV(jit_free)(void *executable_funcs) +{ +int i; +executable_functions *functions = (executable_functions *)executable_funcs; +for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) + { + if (functions->executable_funcs[i] != NULL) + sljit_free_code(functions->executable_funcs[i]); + } +SLJIT_FREE(functions); +} + +int +PRIV(jit_get_size)(void *executable_funcs) +{ +int i; +sljit_uw size = 0; +sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; +for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) + size += executable_sizes[i]; +return (int)size; +} + +const char* +PRIV(jit_get_target)(void) +{ +return sljit_get_platform_name(); +} + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +#else +PCRE_EXP_DECL pcre16_jit_stack * +pcre16_jit_stack_alloc(int startsize, int maxsize) +#endif +{ +if (startsize < 1 || maxsize < 1) + return NULL; +if (startsize > maxsize) + startsize = maxsize; +startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); +maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); +return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); +} + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +#else +PCRE_EXP_DECL void +pcre16_jit_stack_free(pcre16_jit_stack *stack) +#endif +{ +sljit_free_stack((struct sljit_stack *)stack); +} + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +#else +PCRE_EXP_DECL void +pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) +#endif +{ +executable_functions *functions; +if (extra != NULL && + (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + { + functions = (executable_functions *)extra->executable_jit; + functions->callback = callback; + functions->userdata = userdata; + } +} + +#else /* SUPPORT_JIT */ + +/* These are dummy functions to avoid linking errors when JIT support is not +being compiled. */ + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL pcre_jit_stack * +pcre_jit_stack_alloc(int startsize, int maxsize) +#else +PCRE_EXP_DECL pcre16_jit_stack * +pcre16_jit_stack_alloc(int startsize, int maxsize) +#endif +{ +(void)startsize; +(void)maxsize; +return NULL; +} + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_jit_stack_free(pcre_jit_stack *stack) +#else +PCRE_EXP_DECL void +pcre16_jit_stack_free(pcre16_jit_stack *stack) +#endif +{ +(void)stack; +} + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DECL void +pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) +#else +PCRE_EXP_DECL void +pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) +#endif +{ +(void)extra; +(void)callback; +(void)userdata; +} + +#endif + +/* End of pcre_jit_compile.c */ diff -Nru pcre3-8.12/pcre_jit_test.c pcre3-8.31/pcre_jit_test.c --- pcre3-8.12/pcre_jit_test.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre_jit_test.c 2012-06-17 16:04:44.000000000 +0000 @@ -0,0 +1,1279 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Main Library written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + + This JIT compiler regression test program was written by Zoltan Herczeg + Copyright (c) 2010-2012 + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "pcre.h" + +#define PCRE_BUG 0x80000000 + +/* + Letter characters: + \xe6\x92\xad = 0x64ad = 25773 (kanji) + Non-letter characters: + \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark) + \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888 + \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character) + \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character) + Newlines: + \xc2\x85 = 0x85 = 133 (NExt Line = NEL) + \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator) + Othercase pairs: + \xc3\xa9 = 0xe9 = 233 (e') + \xc3\x89 = 0xc9 = 201 (E') + \xc3\xa1 = 0xe1 = 225 (a') + \xc3\x81 = 0xc1 = 193 (A') + \xc8\xba = 0x23a = 570 + \xe2\xb1\xa5 = 0x2c65 = 11365 + \xe1\xbd\xb8 = 0x1f78 = 8056 + \xe1\xbf\xb8 = 0x1ff8 = 8184 + \xf0\x90\x90\x80 = 0x10400 = 66560 + \xf0\x90\x90\xa8 = 0x10428 = 66600 + Mark property: + \xcc\x8d = 0x30d = 781 + Special: + \xdf\xbf = 0x7ff = 2047 (highest 2 byte character) + \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character) + \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character) + \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character) + \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character) +*/ + +static int regression_tests(void); + +int main(void) +{ + int jit = 0; +#ifdef SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_JIT, &jit); +#else + pcre16_config(PCRE_CONFIG_JIT, &jit); +#endif + if (!jit) { + printf("JIT must be enabled to run pcre_jit_test\n"); + return 1; + } + return regression_tests(); +} + +/* --------------------------------------------------------------------------------------- */ + +#if !(defined SUPPORT_PCRE8) && !(defined SUPPORT_PCRE16) +#error SUPPORT_PCRE8 or SUPPORT_PCRE16 must be defined +#endif + +#define MUA (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF) +#define MUAP (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) +#define CMUA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF) +#define CMUAP (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) +#define MA (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF) +#define MAP (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF | PCRE_UCP) +#define CMA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF) + +#define OFFSET_MASK 0x00ffff +#define F_NO8 0x010000 +#define F_NO16 0x020000 +#define F_NOMATCH 0x040000 +#define F_DIFF 0x080000 +#define F_FORCECONV 0x100000 +#define F_PROPERTY 0x200000 + +struct regression_test_case { + int flags; + int start_offset; + const char *pattern; + const char *input; +}; + +static struct regression_test_case regression_test_cases[] = { + /* Constant strings. */ + { MUA, 0, "AbC", "AbAbC" }, + { MUA, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" }, + { CMUA, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" }, + { MA, 0, "[^a]", "aAbB" }, + { CMA, 0, "[^m]", "mMnN" }, + { MA, 0, "a[^b][^#]", "abacd" }, + { CMA, 0, "A[^B][^E]", "abacd" }, + { CMUA, 0, "[^x][^#]", "XxBll" }, + { MUA, 0, "[^a]", "aaa\xc3\xa1#Ab" }, + { CMUA, 0, "[^A]", "aA\xe6\x92\xad" }, + { MUA, 0, "\\W(\\W)?\\w", "\r\n+bc" }, + { MUA, 0, "\\W(\\W)?\\w", "\n\r+bc" }, + { MUA, 0, "\\W(\\W)?\\w", "\r\r+bc" }, + { MUA, 0, "\\W(\\W)?\\w", "\n\n+bc" }, + { MUA, 0, "[axd]", "sAXd" }, + { CMUA, 0, "[axd]", "sAXd" }, + { CMUA, 0 | F_NOMATCH, "[^axd]", "DxA" }, + { MUA, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" }, + { MUA, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, + { CMUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, + { MUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, + { MUA, 0, "[^a]", "\xc2\x80[]" }, + { CMUA, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, + { CMA, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, + { PCRE_CASELESS, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, + { PCRE_CASELESS, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, + { PCRE_CASELESS, 0, "a1", "Aa1" }, + { MA, 0, "\\Ca", "cda" }, + { CMA, 0, "\\Ca", "CDA" }, + { MA, 0 | F_NOMATCH, "\\Cx", "cda" }, + { CMA, 0 | F_NOMATCH, "\\Cx", "CDA" }, + { CMUAP, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUAP, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUAP, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" }, + { CMUAP, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + + /* Assertions. */ + { MUA, 0, "\\b[^A]", "A_B#" }, + { MA, 0 | F_NOMATCH, "\\b\\W", "\n*" }, + { MUA, 0, "\\B[^,]\\b[^s]\\b", "#X" }, + { MAP, 0, "\\B", "_\xa1" }, + { MAP, 0, "\\b_\\b[,A]\\B", "_," }, + { MUAP, 0, "\\b", "\xe6\x92\xad!" }, + { MUAP, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" }, + { MUAP, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" }, + { MUAP, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, + { MUA, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" }, + { CMUAP, 0, "\\By", "\xf0\x90\x90\xa8y" }, + { MA, 0 | F_NOMATCH, "\\R^", "\n" }, + { MA, 1 | F_NOMATCH, "^", "\n" }, + { 0, 0, "^ab", "ab" }, + { 0, 0 | F_NOMATCH, "^ab", "aab" }, + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "^a", "\r\raa\n\naa\r\naa" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" }, + { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^-", "a--b--\x85--" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xe2\x80\xa8--" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xc2\x85--" }, + { 0, 0, "ab$", "ab" }, + { 0, 0 | F_NOMATCH, "ab$", "abab\n\n" }, + { PCRE_DOLLAR_ENDONLY, 0 | F_NOMATCH, "ab$", "abab\r\n" }, + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "a$", "\r\raa\n\naa\r\naa" }, + { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aaa" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "#$", "#\xc2\x85###\r#" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "#$", "#\xe2\x80\xa9" }, + { PCRE_NOTBOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "^a", "aa\naa" }, + { PCRE_NOTBOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^a", "aa\naa" }, + { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\naa" }, + { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\r\n" }, + { PCRE_UTF8 | PCRE_DOLLAR_ENDONLY | PCRE_NEWLINE_ANY, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" }, + { PCRE_NOTEOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aa\naa" }, + { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa" }, + { PCRE_NEWLINE_CR | PCRE_UTF8, 0, "a\\Z", "aaa\r" }, + { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa\n" }, + { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r" }, + { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, + { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r\n" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" }, + { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xc2\x85" }, + { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" }, + { MA, 0, "\\Aa", "aaa" }, + { MA, 1 | F_NOMATCH, "\\Aa", "aaa" }, + { MA, 1, "\\Ga", "aaa" }, + { MA, 1 | F_NOMATCH, "\\Ga", "aba" }, + { MA, 0, "a\\z", "aaa" }, + { MA, 0 | F_NOMATCH, "a\\z", "aab" }, + + /* Brackets. */ + { MUA, 0, "(ab|bb|cd)", "bacde" }, + { MUA, 0, "(?:ab|a)(bc|c)", "ababc" }, + { MUA, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" }, + { CMUA, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" }, + { MUA, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" }, + { MUA, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" }, + + /* Greedy and non-greedy ? operators. */ + { MUA, 0, "(?:a)?a", "laab" }, + { CMUA, 0, "(A)?A", "llaab" }, + { MUA, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */ + { MUA, 0, "(a)?a", "manm" }, + { CMUA, 0, "(a|b)?\?d((?:e)?)", "ABABdx" }, + { MUA, 0, "(a|b)?\?d((?:e)?)", "abcde" }, + { MUA, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" }, + + /* Greedy and non-greedy + operators */ + { MUA, 0, "(aa)+aa", "aaaaaaa" }, + { MUA, 0, "(aa)+?aa", "aaaaaaa" }, + { MUA, 0, "(?:aba|ab|a)+l", "ababamababal" }, + { MUA, 0, "(?:aba|ab|a)+?l", "ababamababal" }, + { MUA, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, + { MUA, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" }, + { MUA, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" }, + + /* Greedy and non-greedy * operators */ + { CMUA, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" }, + { MUA, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" }, + { MUA, 0, "(aa|ab)*ab", "aaabaaab" }, + { CMUA, 0, "(aa|Ab)*?aB", "aaabaaab" }, + { MUA, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" }, + { MUA, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" }, + { MA, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" }, + { MA, 0, "((?:a|)*){0}a", "a" }, + + /* Combining ? + * operators */ + { MUA, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" }, + { MUA, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" }, + { MUA, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" }, + { MUA, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" }, + { MUA, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" }, + + /* Single character iterators. */ + { MUA, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" }, + { MUA, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" }, + { MUA, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" }, + { MUA, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" }, + { MUA, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" }, + { MUA, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" }, + { MUA, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" }, + { MUA, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" }, + { MUA, 0, "(ba{2})+c", "baabaaabacbaabaac" }, + { MUA, 0, "(a*+bc++)+", "aaabbcaaabcccab" }, + { MUA, 0, "(a?+[^b])+", "babaacacb" }, + { MUA, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" }, + { CMUA, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" }, + { CMUA, 0, "[c-f]+k", "DemmFke" }, + { MUA, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" }, + { MUA, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" }, + { CMUA, 0, "[ace]{3,7}", "AcbDAcEEcEd" }, + { CMUA, 0, "[ace]{3,7}?", "AcbDAcEEcEd" }, + { CMUA, 0, "[ace]{3,}", "AcbDAcEEcEd" }, + { CMUA, 0, "[ace]{3,}?", "AcbDAcEEcEd" }, + { MUA, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" }, + { CMUA, 0, "[ace]{5}?", "AcCebDAcEEcEd" }, + { MUA, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" }, + { MUA, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" }, + { MUA, 0, "\\b\\w+\\B", "x,a_cd" }, + { MUAP, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" }, + { CMUA, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" }, + { CMUAP, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CMUA, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" }, + { CMUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, + { MUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, + { MUA, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" }, + + /* Basic character sets. */ + { MUA, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " }, + { MUA, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" }, + { MUA, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" }, + { MUA, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" }, + { MUA, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" }, + { MUA, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" }, + + /* Unicode properties. */ + { MUAP, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" }, + { MUAP, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" }, + { MUAP, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, + { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, + { MUAP, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" }, + { MUAP, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" }, + { MUAP, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" }, + { CMUAP, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" }, + { MUAP, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" }, + { MUAP, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" }, + { MUA, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" }, + { CMUAP, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" }, + { MUAP, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" }, + { MUAP, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" }, + { PCRE_UCP, 0, "[a-b\\s]{2,5}[^a]", "AB baaa" }, + + /* Possible empty brackets. */ + { MUA, 0, "(?:|ab||bc|a)+d", "abcxabcabd" }, + { MUA, 0, "(|ab||bc|a)+d", "abcxabcabd" }, + { MUA, 0, "(?:|ab||bc|a)*d", "abcxabcabd" }, + { MUA, 0, "(|ab||bc|a)*d", "abcxabcabd" }, + { MUA, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" }, + { MUA, 0, "(|ab||bc|a)+?d", "abcxabcabd" }, + { MUA, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" }, + { MUA, 0, "(|ab||bc|a)*?d", "abcxabcabd" }, + { MUA, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" }, + { MUA, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" }, + + /* Start offset. */ + { MUA, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" }, + { MUA, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, + { MUA, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" }, + { MUA, 1, "(\\w\\W\\w)+", "ab#d" }, + + /* Newline. */ + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, + { PCRE_MULTILINE | PCRE_NEWLINE_CR, 0, "\\W{0,2}[^#]{3}", "\r\n#....." }, + { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{1,3}[^#]", "\r\n##...." }, + + /* Any character except newline or any newline. */ + { PCRE_NEWLINE_CRLF, 0, ".", "\r" }, + { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" }, + { PCRE_NEWLINE_ANYCRLF, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" }, + { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" }, + { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" }, + { PCRE_NEWLINE_ANY, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" }, + { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.+)#", "#\rMn\xc2\x85#\n###" }, + { PCRE_BSR_ANYCRLF, 0, "\\R", "\r" }, + { PCRE_BSR_ANYCRLF, 0, "\\R", "\x85#\r\n#" }, + { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\xe2\x80\xa8#c" }, + { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\r\nc" }, + { PCRE_NEWLINE_CRLF | PCRE_BSR_UNICODE | PCRE_UTF8, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" }, + { MUA, 0 | F_NOMATCH, "\\R+", "ab" }, + { MUA, 0, "\\R+", "ab\r\n\r" }, + { MUA, 0, "\\R*", "ab\r\n\r" }, + { MUA, 0, "\\R*", "\r\n\r" }, + { MUA, 0, "\\R{2,4}", "\r\nab\r\r" }, + { MUA, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" }, + { MUA, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" }, + { MUA, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" }, + { MUA, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" }, + { MUA, 0, "\\R+\\R\\R", "\r\r\r" }, + { MUA, 0, "\\R*\\R\\R", "\n\r" }, + { MUA, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" }, + { MUA, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" }, + + /* Atomic groups (no fallback from "next" direction). */ + { MUA, 0 | F_NOMATCH, "(?>ab)ab", "bab" }, + { MUA, 0 | F_NOMATCH, "(?>(ab))ab", "bab" }, + { MUA, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op", + "bababcdedefgheijijklmlmnop" }, + { MUA, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" }, + { MUA, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" }, + { MUA, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" }, + { MUA, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" }, + { MUA, 0, "((?>a|)+?)b", "aaacaaab" }, + { MUA, 0, "(?>x|)*$", "aaa" }, + { MUA, 0, "(?>(x)|)*$", "aaa" }, + { MUA, 0, "(?>x|())*$", "aaa" }, + { MUA, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" }, + { MUA, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" }, + { MUA, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" }, + { MUA, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" }, + { MUA, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" }, + { MUA, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" }, + { MUA, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" }, + { MUA, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" }, + { MUA, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" }, + { MUA, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" }, + { MUA, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" }, + { MUA, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" }, + { MUA, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" }, + { MUA, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" }, + { CMA, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" }, + { MUA, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, + { MUA, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" }, + { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" }, + { MUA, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" }, + { MUA, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" }, + { MUA, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" }, + { MUA, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" }, + { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" }, + { MUA, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" }, + { MUA, 0, "(c(ab)?+ab)+", "cabcababcab" }, + { MUA, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, + + /* Possessive quantifiers. */ + { MUA, 0, "(?:a|b)++m", "mababbaaxababbaam" }, + { MUA, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, + { MUA, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, + { MUA, 0, "(a|b)++m", "mababbaaxababbaam" }, + { MUA, 0, "(a|b)*+m", "mababbaaxababbaam" }, + { MUA, 0, "(a|b)*+m", "ababbaaxababbaam" }, + { MUA, 0, "(a|b(*ACCEPT))++m", "maaxab" }, + { MUA, 0, "(?:b*)++m", "bxbbxbbbxm" }, + { MUA, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, + { MUA, 0, "(?:b*)*+m", "bxbbxbbbxm" }, + { MUA, 0, "(?:b*)*+m", "bxbbxbbbxbbm" }, + { MUA, 0, "(b*)++m", "bxbbxbbbxm" }, + { MUA, 0, "(b*)++m", "bxbbxbbbxbbm" }, + { MUA, 0, "(b*)*+m", "bxbbxbbbxm" }, + { MUA, 0, "(b*)*+m", "bxbbxbbbxbbm" }, + { MUA, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, + { MUA, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, + { MUA, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, + { MUA, 0, "(a|(b))++m", "mababbaaxababbaam" }, + { MUA, 0, "((a)|b)*+m", "mababbaaxababbaam" }, + { MUA, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, + { MUA, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, + { MUA, 0, "(?:(b*))++m", "bxbbxbbbxm" }, + { MUA, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, + { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxm" }, + { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" }, + { MUA, 0, "((b*))++m", "bxbbxbbbxm" }, + { MUA, 0, "((b*))++m", "bxbbxbbbxbbm" }, + { MUA, 0, "((b*))*+m", "bxbbxbbbxm" }, + { MUA, 0, "((b*))*+m", "bxbbxbbbxbbm" }, + { MUA, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" }, + { MUA, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" }, + { MUA, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" }, + { MUA, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, + { MUA, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" }, + + /* Back references. */ + { MUA, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" }, + { CMUA, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" }, + { CMA, 0, "(a{2,4})\\1", "AaAaaAaA" }, + { MUA, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" }, + { MUA, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" }, + { MUA, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, + { MUA, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" }, + { MUA, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" }, + { MUA, 0, "(?:(aa)|b)\\1?b", "bb" }, + { CMUA, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" }, + { MUA, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" }, + { CMUA, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" }, + { MUA, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, + { CMA, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" }, + { MUA, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" }, + { MUA, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" }, + { MA, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" }, + { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, + { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." }, + { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" }, + { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" }, + { PCRE_UCP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." }, + { CMUAP, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" }, + + /* Assertions. */ + { MUA, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" }, + { MUA, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" }, + { MUA, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" }, + { MUA, 0, "(?<=aaa|aa|a)a", "aaa" }, + { MUA, 2, "(?<=aaa|aa|a)a", "aaa" }, + { MA, 0, "(?<=aaa|aa|a)a", "aaa" }, + { MA, 2, "(?<=aaa|aa|a)a", "aaa" }, + { MUA, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" }, + { MUA, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" }, + { MUA, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" }, + { MUA, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" }, + { MUA, 0, "((?(?=(a))a)+k)", "bbak" }, + { MUA, 0, "((?(?=a)a)+k)", "bbak" }, + { MUA, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" }, + { MUA, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" }, + { MUA, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" }, + { MUA, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" }, + { MUA, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" }, + { MUA, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, + { MUA, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" }, + { MUA, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" }, + { MUA, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" }, + { MUA, 0, "((?!a)?(?!([^a]))?)+$", "acbab" }, + { MUA, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" }, + + /* Not empty, ACCEPT, FAIL */ + { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" }, + { MUA | PCRE_NOTEMPTY, 0, "a*", "bcaad" }, + { MUA | PCRE_NOTEMPTY, 0, "a*?", "bcaad" }, + { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*", "bcaad" }, + { MUA, 0, "a(*ACCEPT)b", "ab" }, + { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" }, + { MUA | PCRE_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" }, + { MUA | PCRE_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" }, + { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" }, + { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" }, + { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" }, + { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" }, + { MUA | PCRE_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" }, + { MUA, 0, "((a(*ACCEPT)b))", "ab" }, + { MUA, 0, "(a(*FAIL)a|a)", "aaa" }, + { MUA, 0, "(?=ab(*ACCEPT)b)a", "ab" }, + { MUA, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" }, + { MUA, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" }, + { MUA | PCRE_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" }, + + /* Conditional blocks. */ + { MUA, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, + { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" }, + { MUA, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, + { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" }, + { MUA, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" }, + { MUA, 0, "(?(?=a)ab)", "a" }, + { MUA, 0, "(?(?a)?(?Pb)?(?(Name)c|d)*l", "bc ddd abccabccl" }, + { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" }, + { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" }, + + /* Set start of match. */ + { MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, + { MUA, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, + { MUA, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, + { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" }, + { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" }, + + /* First line. */ + { MUA | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" }, + { MUA | PCRE_FIRSTLINE, 0, "(?<=a)", "a" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[^a][^b]", "ab" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "a", "\na" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[abc]", "\na" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^a", "\na" }, + { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^(?<=\n)", "\na" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\xc2\x85#" }, + { PCRE_MULTILINE | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\x85#" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}", "\r\na" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, ".", "\r" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, "a", "\ra" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH, "ba", "bbb\r\nba" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" }, + { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 1, ".", "\r\n" }, + + /* Recurse. */ + { MUA, 0, "(a)(?1)", "aa" }, + { MUA, 0, "((a))(?1)", "aa" }, + { MUA, 0, "(b|a)(?1)", "aa" }, + { MUA, 0, "(b|(a))(?1)", "aa" }, + { MUA, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" }, + { MUA, 0, "((a)(b)(?:a*))(?1)", "abab" }, + { MUA, 0, "((a+)c(?2))b(?1)", "aacaabaca" }, + { MUA, 0, "((?2)b|(a)){2}(?1)", "aabab" }, + { MUA, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" }, + { MUA, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" }, + { MUA, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" }, + { MUA, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" }, + { MUA, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" }, + { MUA, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" }, + { MUA, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" }, + { MUA, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" }, + { MUA, 0, "b|<(?R)*>", "<" }, + { MUA, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" }, + { MUA, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" }, + { MUA, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" }, + { MUA, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" }, + { MUA, 0, "(a)((?(R1)a|b))(?2)", "ababba" }, + { MUA, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" }, + { MUA, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" }, + { MUA, 0, "(?Pa(?(R&Name)a|b))(?1)", "aab abb abaa" }, + + /* 16 bit specific tests. */ + { CMA, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" }, + { CMA, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CMA, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" }, + { CMA, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" }, + { CMA, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" }, + { CMA, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" }, + { CMA, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" }, + { CMA, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" }, + { CMA, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" }, + { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" }, + { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" }, + { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" }, + { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" }, + { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" }, + { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" }, + { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" }, + { MA, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, + { MA, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" }, + { CMA, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" }, + { CMA, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" }, + { CMA, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" }, + { CMA, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" }, + { CMA | PCRE_EXTENDED, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" }, + { CMA, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" }, + { CMA, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" }, + { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" }, + { PCRE_BSR_UNICODE, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" }, + { 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" }, + { 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" }, + { 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" }, + { 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" }, + + /* Partial matching. */ + { MUA | PCRE_PARTIAL_SOFT, 0, "ab", "a" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "ab|a", "a" }, + { MUA | PCRE_PARTIAL_HARD, 0, "ab|a", "a" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "\\b#", "a" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "(?<=a)b", "a" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" }, + { MUA | PCRE_PARTIAL_SOFT, 0, "a\\B", "a" }, + { MUA | PCRE_PARTIAL_HARD, 0, "a\\b", "a" }, + + /* (*MARK) verb. */ + { MUA, 0, "a(*MARK:aa)a", "ababaa" }, + { MUA, 0 | F_NOMATCH, "a(*:aa)a", "abab" }, + { MUA, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" }, + { MUA, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" }, + { MUA, 0, "(?>a(*:aa))b|ac", "ac" }, + { MUA, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" }, + { MUA, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" }, + { MUA, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" }, + { MUA, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, + { MUA, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" }, + { MUA, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" }, + { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" }, + { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" }, + { MUA, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" }, + + /* (*COMMIT) verb. */ + { MUA, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" }, + { MUA, 0, "aa(*COMMIT)b", "xaxaab" }, + { MUA, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" }, + { MUA, 0, "(?=a(*COMMIT)b|ac)ac|(*:m)(a)c", "ac" }, + { MUA, 0, "(?!a(*COMMIT)(*:msg)b)a(c)|cd", "acd" }, + + /* Deep recursion. */ + { MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, + { MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " }, + { MUA, 0, "((a?)+)+b", "aaaaaaaaaaaa b" }, + + /* Deep recursion: Stack limit reached. */ + { MA, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" }, + { MA, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { MA, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { MA, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + { MA, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, + + { 0, 0, NULL, NULL } +}; + +static const unsigned char *tables(int mode) +{ + /* The purpose of this function to allow valgrind + for reporting invalid reads and writes. */ + static unsigned char *tables_copy; + const char *errorptr; + int erroroffset; + unsigned char *default_tables; +#ifdef SUPPORT_PCRE8 + pcre *regex; + char null_str[1] = { 0 }; +#else + pcre16 *regex; + PCRE_UCHAR16 null_str[1] = { 0 }; +#endif + + if (mode) { + if (tables_copy) + free(tables_copy); + tables_copy = NULL; + return NULL; + } + + if (tables_copy) + return tables_copy; + + default_tables = NULL; +#ifdef SUPPORT_PCRE8 + regex = pcre_compile(null_str, 0, &errorptr, &erroroffset, NULL); + if (regex) { + pcre_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); + pcre_free(regex); + } +#else + regex = pcre16_compile(null_str, 0, &errorptr, &erroroffset, NULL); + if (regex) { + pcre16_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables); + pcre16_free(regex); + } +#endif + /* Shouldn't ever happen. */ + if (!default_tables) + return NULL; + + /* Unfortunately this value cannot get from pcre_fullinfo. + Since this is a test program, this is acceptable at the moment. */ + tables_copy = (unsigned char *)malloc(1088); + if (!tables_copy) + return NULL; + + memcpy(tables_copy, default_tables, 1088); + return tables_copy; +} + +#ifdef SUPPORT_PCRE8 +static pcre_jit_stack* callback8(void *arg) +{ + return (pcre_jit_stack *)arg; +} +#endif + +#ifdef SUPPORT_PCRE16 +static pcre16_jit_stack* callback16(void *arg) +{ + return (pcre16_jit_stack *)arg; +} +#endif + +#ifdef SUPPORT_PCRE8 +static void setstack8(pcre_extra *extra) +{ + static pcre_jit_stack *stack; + + if (!extra) { + if (stack) + pcre_jit_stack_free(stack); + stack = NULL; + return; + } + + if (!stack) + stack = pcre_jit_stack_alloc(1, 1024 * 1024); + /* Extra can be NULL. */ + pcre_assign_jit_stack(extra, callback8, stack); +} +#endif /* SUPPORT_PCRE8 */ + +#ifdef SUPPORT_PCRE16 +static void setstack16(pcre16_extra *extra) +{ + static pcre16_jit_stack *stack; + + if (!extra) { + if (stack) + pcre16_jit_stack_free(stack); + stack = NULL; + return; + } + + if (!stack) + stack = pcre16_jit_stack_alloc(1, 1024 * 1024); + /* Extra can be NULL. */ + pcre16_assign_jit_stack(extra, callback16, stack); +} +#endif /* SUPPORT_PCRE8 */ + +#ifdef SUPPORT_PCRE16 + +static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *offsetmap, int max_length) +{ + unsigned char *iptr = (unsigned char*)input; + unsigned short *optr = (unsigned short *)output; + unsigned int c; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + c = 0; + if (offsetmap) + *offsetmap++ = (int)(iptr - (unsigned char*)input); + + if (!(*iptr & 0x80)) + c = *iptr++; + else if (!(*iptr & 0x20)) { + c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f); + iptr += 2; + } else if (!(*iptr & 0x10)) { + c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f); + iptr += 3; + } else if (!(*iptr & 0x08)) { + c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f); + iptr += 4; + } + + if (c < 65536) { + *optr++ = c; + max_length--; + } else if (max_length <= 2) { + *optr = '\0'; + return (int)(optr - (unsigned short *)output); + } else { + c -= 0x10000; + *optr++ = 0xd800 | ((c >> 10) & 0x3ff); + *optr++ = 0xdc00 | (c & 0x3ff); + max_length -= 2; + if (offsetmap) + offsetmap++; + } + } + if (offsetmap) + *offsetmap = (int)(iptr - (unsigned char*)input); + *optr = '\0'; + return (int)(optr - (unsigned short *)output); +} + +static int copy_char8_to_char16(const char *input, PCRE_UCHAR16 *output, int max_length) +{ + unsigned char *iptr = (unsigned char*)input; + unsigned short *optr = (unsigned short *)output; + + if (max_length == 0) + return 0; + + while (*iptr && max_length > 1) { + *optr++ = *iptr++; + max_length--; + } + *optr = '\0'; + return (int)(optr - (unsigned short *)output); +} + +#define REGTEST_MAX_LENGTH 4096 +static PCRE_UCHAR16 regtest_buf[REGTEST_MAX_LENGTH]; +static int regtest_offsetmap[REGTEST_MAX_LENGTH]; + +#endif /* SUPPORT_PCRE16 */ + +static int check_ascii(const char *input) +{ + const unsigned char *ptr = (unsigned char *)input; + while (*ptr) { + if (*ptr > 127) + return 0; + ptr++; + } + return 1; +} + +static int regression_tests(void) +{ + struct regression_test_case *current = regression_test_cases; + const char *error; + char *cpu_info; + int i, err_offs; + int is_successful, is_ascii_pattern, is_ascii_input; + int total = 0; + int successful = 0; + int successful_row = 0; + int counter = 0; + int study_mode; +#ifdef SUPPORT_PCRE8 + pcre *re8; + pcre_extra *extra8; + pcre_extra dummy_extra8; + int ovector8_1[32]; + int ovector8_2[32]; + int return_value8_1, return_value8_2; + unsigned char *mark8_1, *mark8_2; + int utf8 = 0, ucp8 = 0; + int disabled_flags8 = 0; +#endif +#ifdef SUPPORT_PCRE16 + pcre16 *re16; + pcre16_extra *extra16; + pcre16_extra dummy_extra16; + int ovector16_1[32]; + int ovector16_2[32]; + int return_value16_1, return_value16_2; + PCRE_UCHAR16 *mark16_1, *mark16_2; + int utf16 = 0, ucp16 = 0; + int disabled_flags16 = 0; + int length16; +#endif + + /* This test compares the behaviour of interpreter and JIT. Although disabling + utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is + still considered successful from pcre_jit_test point of view. */ + +#ifdef SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_JITTARGET, &cpu_info); +#else + pcre16_config(PCRE_CONFIG_JITTARGET, &cpu_info); +#endif + + printf("Running JIT regression tests\n"); + printf(" target CPU of SLJIT compiler: %s\n", cpu_info); + +#ifdef SUPPORT_PCRE8 + pcre_config(PCRE_CONFIG_UTF8, &utf8); + pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp8); + if (!utf8) + disabled_flags8 |= PCRE_UTF8; + if (!ucp8) + disabled_flags8 |= PCRE_UCP; + printf(" in 8 bit mode with utf8 %s and ucp %s:\n", utf8 ? "enabled" : "disabled", ucp8 ? "enabled" : "disabled"); +#endif +#ifdef SUPPORT_PCRE16 + pcre16_config(PCRE_CONFIG_UTF16, &utf16); + pcre16_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp16); + if (!utf16) + disabled_flags16 |= PCRE_UTF8; + if (!ucp16) + disabled_flags16 |= PCRE_UCP; + printf(" in 16 bit mode with utf16 %s and ucp %s:\n", utf16 ? "enabled" : "disabled", ucp16 ? "enabled" : "disabled"); +#endif + + while (current->pattern) { + /* printf("\nPattern: %s :\n", current->pattern); */ + total++; + if (current->start_offset & F_PROPERTY) { + is_ascii_pattern = 0; + is_ascii_input = 0; + } else { + is_ascii_pattern = check_ascii(current->pattern); + is_ascii_input = check_ascii(current->input); + } + + if (current->flags & PCRE_PARTIAL_SOFT) + study_mode = PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE; + else if (current->flags & PCRE_PARTIAL_HARD) + study_mode = PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE; + else + study_mode = PCRE_STUDY_JIT_COMPILE; + error = NULL; +#ifdef SUPPORT_PCRE8 + re8 = NULL; + if (!(current->start_offset & F_NO8)) + re8 = pcre_compile(current->pattern, + current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags8), + &error, &err_offs, tables(0)); + + extra8 = NULL; + if (re8) { + error = NULL; + extra8 = pcre_study(re8, study_mode, &error); + if (!extra8) { + printf("\n8 bit: Cannot study pattern: %s\n", current->pattern); + pcre_free(re8); + re8 = NULL; + } + if (!(extra8->flags & PCRE_EXTRA_EXECUTABLE_JIT)) { + printf("\n8 bit: JIT compiler does not support: %s\n", current->pattern); + pcre_free_study(extra8); + pcre_free(re8); + re8 = NULL; + } + extra8->flags |= PCRE_EXTRA_MARK; + } else if (((utf8 && ucp8) || is_ascii_pattern) && !(current->start_offset & F_NO8)) + printf("\n8 bit: Cannot compile pattern: %s\n", current->pattern); +#endif +#ifdef SUPPORT_PCRE16 + if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV)) + convert_utf8_to_utf16(current->pattern, regtest_buf, NULL, REGTEST_MAX_LENGTH); + else + copy_char8_to_char16(current->pattern, regtest_buf, REGTEST_MAX_LENGTH); + + re16 = NULL; + if (!(current->start_offset & F_NO16)) + re16 = pcre16_compile(regtest_buf, + current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags16), + &error, &err_offs, tables(0)); + + extra16 = NULL; + if (re16) { + error = NULL; + extra16 = pcre16_study(re16, study_mode, &error); + if (!extra16) { + printf("\n16 bit: Cannot study pattern: %s\n", current->pattern); + pcre16_free(re16); + re16 = NULL; + } + if (!(extra16->flags & PCRE_EXTRA_EXECUTABLE_JIT)) { + printf("\n16 bit: JIT compiler does not support: %s\n", current->pattern); + pcre16_free_study(extra16); + pcre16_free(re16); + re16 = NULL; + } + extra16->flags |= PCRE_EXTRA_MARK; + } else if (((utf16 && ucp16) || is_ascii_pattern) && !(current->start_offset & F_NO16)) + printf("\n16 bit: Cannot compile pattern: %s\n", current->pattern); +#endif + + counter++; + if ((counter & 0x3) != 0) { +#ifdef SUPPORT_PCRE8 + setstack8(NULL); +#endif +#ifdef SUPPORT_PCRE16 + setstack16(NULL); +#endif + } + +#ifdef SUPPORT_PCRE8 + return_value8_1 = -1000; + return_value8_2 = -1000; + for (i = 0; i < 32; ++i) + ovector8_1[i] = -2; + for (i = 0; i < 32; ++i) + ovector8_2[i] = -2; + if (re8) { + mark8_1 = NULL; + mark8_2 = NULL; + setstack8(extra8); + extra8->mark = &mark8_1; + return_value8_1 = pcre_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_1, 32); + memset(&dummy_extra8, 0, sizeof(pcre_extra)); + dummy_extra8.flags = PCRE_EXTRA_MARK; + dummy_extra8.mark = &mark8_2; + return_value8_2 = pcre_exec(re8, &dummy_extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_2, 32); + } +#endif + +#ifdef SUPPORT_PCRE16 + return_value16_1 = -1000; + return_value16_2 = -1000; + for (i = 0; i < 32; ++i) + ovector16_1[i] = -2; + for (i = 0; i < 32; ++i) + ovector16_2[i] = -2; + if (re16) { + mark16_1 = NULL; + mark16_2 = NULL; + setstack16(extra16); + if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV)) + length16 = convert_utf8_to_utf16(current->input, regtest_buf, regtest_offsetmap, REGTEST_MAX_LENGTH); + else + length16 = copy_char8_to_char16(current->input, regtest_buf, REGTEST_MAX_LENGTH); + extra16->mark = &mark16_1; + return_value16_1 = pcre16_exec(re16, extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_1, 32); + memset(&dummy_extra16, 0, sizeof(pcre16_extra)); + dummy_extra16.flags = PCRE_EXTRA_MARK; + dummy_extra16.mark = &mark16_2; + return_value16_2 = pcre16_exec(re16, &dummy_extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK, + current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_2, 32); + } +#endif + + /* printf("[%d-%d|%d-%d|%d-%d]%s", return_value8_1, return_value16_1, ovector8_1[0], ovector8_1[1], ovector16_1[0], ovector16_1[1], (current->flags & PCRE_CASELESS) ? "C" : ""); */ + + /* If F_DIFF is set, just run the test, but do not compare the results. + Segfaults can still be captured. */ + + is_successful = 1; + if (!(current->start_offset & F_DIFF)) { +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + if (utf8 == utf16 && !(current->start_offset & F_FORCECONV)) { + /* All results must be the same. */ + if (return_value8_1 != return_value8_2 || return_value8_1 != return_value16_1 || return_value8_1 != return_value16_2) { + printf("\n8 and 16 bit: Return value differs(%d:%d:%d:%d): [%d] '%s' @ '%s'\n", + return_value8_1, return_value8_2, return_value16_1, return_value16_2, + total, current->pattern, current->input); + is_successful = 0; + } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) { + if (return_value8_1 == PCRE_ERROR_PARTIAL) { + return_value8_1 = 2; + return_value16_1 = 2; + } else { + return_value8_1 *= 2; + return_value16_1 *= 2; + } + + /* Transform back the results. */ + if (current->flags & PCRE_UTF8) { + for (i = 0; i < return_value8_1; ++i) { + if (ovector16_1[i] >= 0) + ovector16_1[i] = regtest_offsetmap[ovector16_1[i]]; + if (ovector16_2[i] >= 0) + ovector16_2[i] = regtest_offsetmap[ovector16_2[i]]; + } + } + + for (i = 0; i < return_value8_1; ++i) + if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) { + printf("\n8 and 16 bit: Ovector[%d] value differs(%d:%d:%d:%d): [%d] '%s' @ '%s' \n", + i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i], + total, current->pattern, current->input); + is_successful = 0; + } + } + } else { +#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */ + /* Only the 8 bit and 16 bit results must be equal. */ +#ifdef SUPPORT_PCRE8 + if (return_value8_1 != return_value8_2) { + printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value8_1, return_value8_2, total, current->pattern, current->input); + is_successful = 0; + } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) { + if (return_value8_1 == PCRE_ERROR_PARTIAL) + return_value8_1 = 2; + else + return_value8_1 *= 2; + + for (i = 0; i < return_value8_1; ++i) + if (ovector8_1[i] != ovector8_2[i]) { + printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, ovector8_1[i], ovector8_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + +#ifdef SUPPORT_PCRE16 + if (return_value16_1 != return_value16_2) { + printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n", + return_value16_1, return_value16_2, total, current->pattern, current->input); + is_successful = 0; + } else if (return_value16_1 >= 0 || return_value16_1 == PCRE_ERROR_PARTIAL) { + if (return_value16_1 == PCRE_ERROR_PARTIAL) + return_value16_1 = 2; + else + return_value16_1 *= 2; + + for (i = 0; i < return_value16_1; ++i) + if (ovector16_1[i] != ovector16_2[i]) { + printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n", + i, ovector16_1[i], ovector16_2[i], total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + } +#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */ + } + + if (is_successful) { +#ifdef SUPPORT_PCRE8 + if (!(current->start_offset & F_NO8) && ((utf8 && ucp8) || is_ascii_input)) { + if (return_value8_1 < 0 && !(current->start_offset & F_NOMATCH)) { + printf("8 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value8_1 >= 0 && (current->start_offset & F_NOMATCH)) { + printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + } +#endif +#ifdef SUPPORT_PCRE16 + if (!(current->start_offset & F_NO16) && ((utf16 && ucp16) || is_ascii_input)) { + if (return_value16_1 < 0 && !(current->start_offset & F_NOMATCH)) { + printf("16 bit: Test should match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + + if (return_value16_1 >= 0 && (current->start_offset & F_NOMATCH)) { + printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } + } +#endif + } + + if (is_successful) { +#ifdef SUPPORT_PCRE8 + if (mark8_1 != mark8_2) { + printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } +#endif +#ifdef SUPPORT_PCRE16 + if (mark16_1 != mark16_2) { + printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n", + total, current->pattern, current->input); + is_successful = 0; + } +#endif + } + +#ifdef SUPPORT_PCRE8 + if (re8) { + pcre_free_study(extra8); + pcre_free(re8); + } +#endif +#ifdef SUPPORT_PCRE16 + if (re16) { + pcre16_free_study(extra16); + pcre16_free(re16); + } +#endif + + if (is_successful) { + successful++; + successful_row++; + printf("."); + if (successful_row >= 60) { + successful_row = 0; + printf("\n"); + } + } else + successful_row = 0; + + fflush(stdout); + current++; + } + tables(1); +#ifdef SUPPORT_PCRE8 + setstack8(NULL); +#endif +#ifdef SUPPORT_PCRE16 + setstack16(NULL); +#endif + + if (total == successful) { + printf("\nAll JIT regression tests are successfully passed.\n"); + return 0; + } else { + printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful); + return 1; + } +} + +/* End of pcre_jit_test.c */ diff -Nru pcre3-8.12/pcre_maketables.c pcre3-8.31/pcre_maketables.c --- pcre3-8.12/pcre_maketables.c 2008-01-20 19:59:12.000000000 +0000 +++ pcre3-8.31/pcre_maketables.c 2011-12-28 16:57:58.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -59,21 +59,26 @@ /* This function builds a set of character tables for use by PCRE and returns a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as -part of the library, the store is obtained via pcre_malloc(), but when compiled -inside dftables, use malloc(). +part of the library, the store is obtained via PUBL(malloc)(), but when +compiled inside dftables, use malloc(). Arguments: none Returns: pointer to the contiguous block of data */ +#ifdef COMPILE_PCRE8 const unsigned char * pcre_maketables(void) +#else +const unsigned char * +pcre16_maketables(void) +#endif { unsigned char *yield, *p; int i; #ifndef DFTABLES -yield = (unsigned char*)(pcre_malloc)(tables_length); +yield = (unsigned char*)(PUBL(malloc))(tables_length); #else yield = (unsigned char*)malloc(tables_length); #endif diff -Nru pcre3-8.12/pcre_newline.c pcre3-8.31/pcre_newline.c --- pcre3-8.12/pcre_newline.c 2009-03-28 17:06:38.000000000 +0000 +++ pcre3-8.31/pcre_newline.c 2011-12-28 16:57:58.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -67,16 +67,25 @@ type the newline type endptr pointer to the end of the string lenptr where to return the length - utf8 TRUE if in utf8 mode + utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL -_pcre_is_newline(USPTR ptr, int type, USPTR endptr, int *lenptr, BOOL utf8) +PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr, + BOOL utf) { int c; -if (utf8) { GETCHAR(c, ptr); } else c = *ptr; +(void)utf; +#ifdef SUPPORT_UTF +if (utf) + { + GETCHAR(c, ptr); + } +else +#endif /* SUPPORT_UTF */ + c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { @@ -95,9 +104,15 @@ case 0x000c: *lenptr = 1; return TRUE; /* FF */ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; return TRUE; /* CR */ - case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ +#ifdef COMPILE_PCRE8 + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else + case 0x0085: /* NEL */ + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } @@ -116,26 +131,27 @@ type the newline type startptr pointer to the start of the string lenptr where to return the length - utf8 TRUE if in utf8 mode + utf TRUE if in utf mode Returns: TRUE or FALSE */ BOOL -_pcre_was_newline(USPTR ptr, int type, USPTR startptr, int *lenptr, BOOL utf8) +PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr, + BOOL utf) { int c; +(void)utf; ptr--; -#ifdef SUPPORT_UTF8 -if (utf8) +#ifdef SUPPORT_UTF +if (utf) { BACKCHAR(ptr); GETCHAR(c, ptr); } -else c = *ptr; -#else /* no UTF-8 support */ -c = *ptr; -#endif /* SUPPORT_UTF8 */ +else +#endif /* SUPPORT_UTF */ + c = *ptr; if (type == NLTYPE_ANYCRLF) switch(c) { @@ -152,9 +168,15 @@ case 0x000b: /* VT */ case 0x000c: /* FF */ case 0x000d: *lenptr = 1; return TRUE; /* CR */ - case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */ +#ifdef COMPILE_PCRE8 + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else + case 0x0085: /* NEL */ + case 0x2028: /* LS */ + case 0x2029: *lenptr = 1; return TRUE; /* PS */ +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } diff -Nru pcre3-8.12/pcre_ord2utf8.c pcre3-8.31/pcre_ord2utf8.c --- pcre3-8.12/pcre_ord2utf8.c 2008-08-25 18:27:26.000000000 +0000 +++ pcre3-8.31/pcre_ord2utf8.c 2012-01-23 17:11:03.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -52,35 +52,45 @@ * Convert character value to UTF-8 * *************************************************/ -/* This function takes an integer value in the range 0 - 0x7fffffff -and encodes it as a UTF-8 character in 0 to 6 bytes. +/* This function takes an integer value in the range 0 - 0x10ffff +and encodes it as a UTF-8 character in 1 to 6 pcre_uchars. Arguments: cvalue the character value - buffer pointer to buffer for result - at least 6 bytes long + buffer pointer to buffer for result - at least 6 pcre_uchars long Returns: number of characters placed in the buffer */ int -_pcre_ord2utf8(int cvalue, uschar *buffer) +PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) { -#ifdef SUPPORT_UTF8 +#ifdef SUPPORT_UTF + register int i, j; -for (i = 0; i < _pcre_utf8_table1_size; i++) - if (cvalue <= _pcre_utf8_table1[i]) break; + +/* Checking invalid cvalue character, encoded as invalid UTF-16 character. +Should never happen in practice. */ +if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) + cvalue = 0xfffe; + +for (i = 0; i < PRIV(utf8_table1_size); i++) + if ((int)cvalue <= PRIV(utf8_table1)[i]) break; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } -*buffer = _pcre_utf8_table2[i] | cvalue; +*buffer = PRIV(utf8_table2)[i] | cvalue; return i + 1; + #else + (void)(cvalue); /* Keep compiler happy; this function won't ever be */ -(void)(buffer); /* called when SUPPORT_UTF8 is not defined. */ +(void)(buffer); /* called when SUPPORT_UTF is not defined. */ return 0; + #endif } diff -Nru pcre3-8.12/pcre_printint.c pcre3-8.31/pcre_printint.c --- pcre3-8.12/pcre_printint.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre_printint.c 2012-02-22 13:54:41.000000000 +0000 @@ -0,0 +1,710 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains a PCRE private debugging function for printing out the +internal form of a compiled regular expression, along with some supporting +local functions. This source file is used in two places: + +(1) It is #included by pcre_compile.c when it is compiled in debugging mode +(PCRE_DEBUG defined in pcre_internal.h). It is not included in production +compiles. In this case PCRE_INCLUDED is defined. + +(2) It is also compiled separately and linked with pcretest.c, which can be +asked to print out a compiled regex for debugging purposes. */ + +#ifndef PCRE_INCLUDED + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* For pcretest program. */ +#define PRIV(name) name + +/* We have to include pcre_internal.h because we need the internal info for +displaying the results of pcre_study() and we also need to know about the +internal macros, structures, and other internal data values; pcretest has +"inside information" compared to a program that strictly follows the PCRE API. + +Although pcre_internal.h does itself include pcre.h, we explicitly include it +here before pcre_internal.h so that the PCRE_EXP_xxx macros get set +appropriately for an application, not for building PCRE. */ + +#include "pcre.h" +#include "pcre_internal.h" + +/* These are the funtions that are contained within. It doesn't seem worth +having a separate .h file just for this. */ + +#endif /* PCRE_INCLUDED */ + +#ifdef PCRE_INCLUDED +static /* Keep the following function as private. */ +#endif +#ifdef COMPILE_PCRE8 +void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#else +void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#endif + +/* Macro that decides whether a character should be output as a literal or in +hexadecimal. We don't use isprint() because that can vary from system to system +(even without the use of locales) and we want the output always to be the same, +for testing purposes. */ + +#ifdef EBCDIC +#define PRINTABLE(c) ((c) >= 64 && (c) < 255) +#else +#define PRINTABLE(c) ((c) >= 32 && (c) < 127) +#endif + +/* The table of operator names. */ + +static const char *priv_OP_names[] = { OP_NAME_LIST }; + +/* This table of operator lengths is not actually used by the working code, +but its size is needed for a check that ensures it is the correct size for the +number of opcodes (thus catching update omissions). */ + +static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS }; + + + +/************************************************* +* Print single- or multi-byte character * +*************************************************/ + +static int +print_char(FILE *f, pcre_uchar *ptr, BOOL utf) +{ +int c = *ptr; + +#ifndef SUPPORT_UTF + +(void)utf; /* Avoid compiler warning */ +if (PRINTABLE(c)) fprintf(f, "%c", c); +else if (c <= 0xff) fprintf(f, "\\x%02x", c); +else fprintf(f, "\\x{%x}", c); +return 0; + +#else + +#ifdef COMPILE_PCRE8 + +if (!utf || (c & 0xc0) != 0xc0) + { + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); + return 0; + } +else + { + int i; + int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ + int s = 6*a; + c = (c & PRIV(utf8_table3)[a]) << s; + for (i = 1; i <= a; i++) + { + /* This is a check for malformed UTF-8; it should only occur if the sanity + check has been turned off. Rather than swallow random bytes, just stop if + we hit a bad one. Print it with \X instead of \x as an indication. */ + + if ((ptr[i] & 0xc0) != 0x80) + { + fprintf(f, "\\X{%x}", c); + return i - 1; + } + + /* The byte is OK */ + + s -= 6; + c |= (ptr[i] & 0x3f) << s; + } + fprintf(f, "\\x{%x}", c); + return a; + } + +#else + +#ifdef COMPILE_PCRE16 + +if (!utf || (c & 0xfc00) != 0xd800) + { + if (PRINTABLE(c)) fprintf(f, "%c", c); + else if (c <= 0xff) fprintf(f, "\\x%02x", c); + else fprintf(f, "\\x{%x}", c); + return 0; + } +else + { + /* This is a check for malformed UTF-16; it should only occur if the sanity + check has been turned off. Rather than swallow a low surrogate, just stop if + we hit a bad one. Print it with \X instead of \x as an indication. */ + + if ((ptr[1] & 0xfc00) != 0xdc00) + { + fprintf(f, "\\X{%x}", c); + return 0; + } + + c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000; + fprintf(f, "\\x{%x}", c); + return 1; + } + +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ + +#endif /* SUPPORT_UTF */ +} + +/************************************************* +* Print uchar string (regardless of utf) * +*************************************************/ + +static void +print_puchar(FILE *f, PCRE_PUCHAR ptr) +{ +while (*ptr != '\0') + { + register int c = *ptr++; + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); + } +} + +/************************************************* +* Find Unicode property name * +*************************************************/ + +static const char * +get_ucpname(int ptype, int pvalue) +{ +#ifdef SUPPORT_UCP +int i; +for (i = PRIV(utt_size) - 1; i >= 0; i--) + { + if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break; + } +return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??"; +#else +/* It gets harder and harder to shut off unwanted compiler warnings. */ +ptype = ptype * pvalue; +return (ptype == pvalue)? "??" : "??"; +#endif +} + + + +/************************************************* +* Print compiled regex * +*************************************************/ + +/* Make this function work for a regex with integers either byte order. +However, we assume that what we are passed is a compiled regex. The +print_lengths flag controls whether offsets and lengths of items are printed. +They can be turned off from pcretest so that automatic tests on bytecode can be +written that do not depend on the value of LINK_SIZE. */ + +#ifdef PCRE_INCLUDED +static /* Keep the following function as private. */ +#endif +#ifdef COMPILE_PCRE8 +void +pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) +#else +void +pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths) +#endif +{ +REAL_PCRE *re = (REAL_PCRE *)external_re; +pcre_uchar *codestart, *code; +BOOL utf; + +unsigned int options = re->options; +int offset = re->name_table_offset; +int count = re->name_count; +int size = re->name_entry_size; + +if (re->magic_number != MAGIC_NUMBER) + { + offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); + count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); + size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); + options = ((options << 24) & 0xff000000) | + ((options << 8) & 0x00ff0000) | + ((options >> 8) & 0x0000ff00) | + ((options >> 24) & 0x000000ff); + } + +code = codestart = (pcre_uchar *)re + offset + count * size; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +utf = (options & PCRE_UTF8) != 0; + +for(;;) + { + pcre_uchar *ccode; + const char *flag = " "; + int c; + int extra = 0; + + if (print_lengths) + fprintf(f, "%3d ", (int)(code - codestart)); + else + fprintf(f, " "); + + switch(*code) + { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors OP_names or OP_lengths, which are indexed + by opcode, are not the correct length. It seems to be the only way to do + such a check at compile time, as the sizeof() operator does not work in + the C preprocessor. */ + + case OP_TABLE_LENGTH: + case OP_TABLE_LENGTH + + ((sizeof(priv_OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && + (sizeof(priv_OP_lengths) == OP_TABLE_LENGTH)): + break; +/* ========================================================================== */ + + case OP_END: + fprintf(f, " %s\n", priv_OP_names[*code]); + fprintf(f, "------------------------------------------------------------------\n"); + return; + + case OP_CHAR: + fprintf(f, " "); + do + { + code++; + code += 1 + print_char(f, code, utf); + } + while (*code == OP_CHAR); + fprintf(f, "\n"); + continue; + + case OP_CHARI: + fprintf(f, " /i "); + do + { + code++; + code += 1 + print_char(f, code, utf); + } + while (*code == OP_CHARI); + fprintf(f, "\n"); + continue; + + case OP_CBRA: + case OP_CBRAPOS: + case OP_SCBRA: + case OP_SCBRAPOS: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE)); + break; + + case OP_BRA: + case OP_BRAPOS: + case OP_SBRA: + case OP_SBRAPOS: + case OP_KETRMAX: + case OP_KETRMIN: + case OP_KETRPOS: + case OP_ALT: + case OP_KET: + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ONCE: + case OP_ONCE_NC: + case OP_COND: + case OP_SCOND: + case OP_REVERSE: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s", priv_OP_names[*code]); + break; + + case OP_CLOSE: + fprintf(f, " %s %d", priv_OP_names[*code], GET2(code, 1)); + break; + + case OP_CREF: + case OP_NCREF: + fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]); + break; + + case OP_RREF: + c = GET2(code, 1); + if (c == RREF_ANY) + fprintf(f, " Cond recurse any"); + else + fprintf(f, " Cond recurse %d", c); + break; + + case OP_NRREF: + c = GET2(code, 1); + if (c == RREF_ANY) + fprintf(f, " Cond nrecurse any"); + else + fprintf(f, " Cond nrecurse %d", c); + break; + + case OP_DEF: + fprintf(f, " Cond def"); + break; + + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + flag = "/i"; + /* Fall through */ + case OP_STAR: + case OP_MINSTAR: + case OP_POSSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_POSQUERY: + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPOSSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSPLUS: + case OP_TYPEQUERY: + case OP_TYPEMINQUERY: + case OP_TYPEPOSQUERY: + fprintf(f, " %s ", flag); + if (*code >= OP_TYPESTAR) + { + fprintf(f, "%s", priv_OP_names[code[1]]); + if (code[1] == OP_PROP || code[1] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[2], code[3])); + extra = 2; + } + } + else extra = print_char(f, code+1, utf); + fprintf(f, "%s", priv_OP_names[*code]); + break; + + case OP_EXACTI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + flag = "/i"; + /* Fall through */ + case OP_EXACT: + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: + fprintf(f, " %s ", flag); + extra = print_char(f, code + 1 + IMM2_SIZE, utf); + fprintf(f, "{"); + if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?"); + else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+"); + break; + + case OP_TYPEEXACT: + case OP_TYPEUPTO: + case OP_TYPEMINUPTO: + case OP_TYPEPOSUPTO: + fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]); + if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) + { + fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1], + code[1 + IMM2_SIZE + 2])); + extra = 2; + } + fprintf(f, "{"); + if (*code != OP_TYPEEXACT) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); + else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); + break; + + case OP_NOTI: + flag = "/i"; + /* Fall through */ + case OP_NOT: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1, utf); + fprintf(f, "]"); + break; + + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPOSSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTPOSQUERYI: + flag = "/i"; + /* Fall through */ + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPOSSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTPOSQUERY: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1, utf); + fprintf(f, "]%s", priv_OP_names[*code]); + break; + + case OP_NOTEXACTI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTPOSUPTOI: + flag = "/i"; + /* Fall through */ + + case OP_NOTEXACT: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTPOSUPTO: + fprintf(f, " %s [^", flag); + extra = print_char(f, code + 1 + IMM2_SIZE, utf); + fprintf(f, "]{"); + if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,"); + fprintf(f, "%d}", GET2(code,1)); + if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); + else + if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); + break; + + case OP_RECURSE: + if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); + else fprintf(f, " "); + fprintf(f, "%s", priv_OP_names[*code]); + break; + + case OP_REFI: + flag = "/i"; + /* Fall through */ + case OP_REF: + fprintf(f, " %s \\%d", flag, GET2(code,1)); + ccode = code + priv_OP_lengths[*code]; + goto CLASS_REF_REPEAT; + + case OP_CALLOUT: + fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2), + GET(code, 2 + LINK_SIZE)); + break; + + case OP_PROP: + case OP_NOTPROP: + fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2])); + break; + + /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no + harm in having this code always here, and it makes it less messy without + all those #ifdefs. */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: + { + int i, min, max; + BOOL printmap; + pcre_uint8 *map; + + fprintf(f, " ["); + + if (*code == OP_XCLASS) + { + extra = GET(code, 1); + ccode = code + LINK_SIZE + 1; + printmap = (*ccode & XCL_MAP) != 0; + if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); + } + else + { + printmap = TRUE; + ccode = code + 1; + } + + /* Print a bit map */ + + if (printmap) + { + map = (pcre_uint8 *)ccode; + for (i = 0; i < 256; i++) + { + if ((map[i/8] & (1 << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((map[j/8] & (1 << (j&7))) == 0) break; + if (i == '-' || i == ']') fprintf(f, "\\"); + if (PRINTABLE(i)) fprintf(f, "%c", i); + else fprintf(f, "\\x%02x", i); + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == ']') fprintf(f, "\\"); + if (PRINTABLE(j)) fprintf(f, "%c", j); + else fprintf(f, "\\x%02x", j); + } + i = j; + } + } + ccode += 32 / sizeof(pcre_uchar); + } + + /* For an XCLASS there is always some additional data */ + + if (*code == OP_XCLASS) + { + int ch; + while ((ch = *ccode++) != XCL_END) + { + if (ch == XCL_PROP) + { + int ptype = *ccode++; + int pvalue = *ccode++; + fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); + } + else if (ch == XCL_NOTPROP) + { + int ptype = *ccode++; + int pvalue = *ccode++; + fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); + } + else + { + ccode += 1 + print_char(f, ccode, utf); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, utf); + } + } + } + } + + /* Indicate a non-UTF class which was created by negation */ + + fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); + + /* Handle repeats after a class or a back reference */ + + CLASS_REF_REPEAT: + switch(*ccode) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRQUERY: + case OP_CRMINQUERY: + fprintf(f, "%s", priv_OP_names[*ccode]); + extra += priv_OP_lengths[*ccode]; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + min = GET2(ccode,1); + max = GET2(ccode,1 + IMM2_SIZE); + if (max == 0) fprintf(f, "{%d,}", min); + else fprintf(f, "{%d,%d}", min, max); + if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); + extra += priv_OP_lengths[*ccode]; + break; + + /* Do nothing if it's not a repeat; this code stops picky compilers + warning about the lack of a default code path. */ + + default: + break; + } + } + break; + + case OP_MARK: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + fprintf(f, " %s ", priv_OP_names[*code]); + print_puchar(f, code + 2); + extra += code[1]; + break; + + case OP_THEN: + fprintf(f, " %s", priv_OP_names[*code]); + break; + + case OP_CIRCM: + case OP_DOLLM: + flag = "/m"; + /* Fall through */ + + /* Anything else is just an item with no data, but possibly a flag. */ + + default: + fprintf(f, " %s %s", flag, priv_OP_names[*code]); + break; + } + + code += priv_OP_lengths[*code] + extra; + fprintf(f, "\n"); + } +} + +/* End of pcre_printint.src */ diff -Nru pcre3-8.12/pcre_printint.src pcre3-8.31/pcre_printint.src --- pcre3-8.12/pcre_printint.src 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_printint.src 1970-01-01 00:00:00.000000000 +0000 @@ -1,572 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains a PCRE private debugging function for printing out the -internal form of a compiled regular expression, along with some supporting -local functions. This source file is used in two places: - -(1) It is #included by pcre_compile.c when it is compiled in debugging mode -(PCRE_DEBUG defined in pcre_internal.h). It is not included in production -compiles. - -(2) It is always #included by pcretest.c, which can be asked to print out a -compiled regex for debugging purposes. */ - - -/* Macro that decides whether a character should be output as a literal or in -hexadecimal. We don't use isprint() because that can vary from system to system -(even without the use of locales) and we want the output always to be the same, -for testing purposes. This macro is used in pcretest as well as in this file. */ - -#ifdef EBCDIC -#define PRINTABLE(c) ((c) >= 64 && (c) < 255) -#else -#define PRINTABLE(c) ((c) >= 32 && (c) < 127) -#endif - -/* The table of operator names. */ - -static const char *OP_names[] = { OP_NAME_LIST }; - - - -/************************************************* -* Print single- or multi-byte character * -*************************************************/ - -static int -print_char(FILE *f, uschar *ptr, BOOL utf8) -{ -int c = *ptr; - -#ifndef SUPPORT_UTF8 -utf8 = utf8; /* Avoid compiler warning */ -if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); -return 0; - -#else -if (!utf8 || (c & 0xc0) != 0xc0) - { - if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); - return 0; - } -else - { - int i; - int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ - int s = 6*a; - c = (c & _pcre_utf8_table3[a]) << s; - for (i = 1; i <= a; i++) - { - /* This is a check for malformed UTF-8; it should only occur if the sanity - check has been turned off. Rather than swallow random bytes, just stop if - we hit a bad one. Print it with \X instead of \x as an indication. */ - - if ((ptr[i] & 0xc0) != 0x80) - { - fprintf(f, "\\X{%x}", c); - return i - 1; - } - - /* The byte is OK */ - - s -= 6; - c |= (ptr[i] & 0x3f) << s; - } - if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); - return a; - } -#endif -} - - - -/************************************************* -* Find Unicode property name * -*************************************************/ - -static const char * -get_ucpname(int ptype, int pvalue) -{ -#ifdef SUPPORT_UCP -int i; -for (i = _pcre_utt_size - 1; i >= 0; i--) - { - if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break; - } -return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??"; -#else -/* It gets harder and harder to shut off unwanted compiler warnings. */ -ptype = ptype * pvalue; -return (ptype == pvalue)? "??" : "??"; -#endif -} - - - -/************************************************* -* Print compiled regex * -*************************************************/ - -/* Make this function work for a regex with integers either byte order. -However, we assume that what we are passed is a compiled regex. The -print_lengths flag controls whether offsets and lengths of items are printed. -They can be turned off from pcretest so that automatic tests on bytecode can be -written that do not depend on the value of LINK_SIZE. */ - -static void -pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) -{ -real_pcre *re = (real_pcre *)external_re; -uschar *codestart, *code; -BOOL utf8; - -unsigned int options = re->options; -int offset = re->name_table_offset; -int count = re->name_count; -int size = re->name_entry_size; - -if (re->magic_number != MAGIC_NUMBER) - { - offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); - count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); - size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); - options = ((options << 24) & 0xff000000) | - ((options << 8) & 0x00ff0000) | - ((options >> 8) & 0x0000ff00) | - ((options >> 24) & 0x000000ff); - } - -code = codestart = (uschar *)re + offset + count * size; -utf8 = (options & PCRE_UTF8) != 0; - -for(;;) - { - uschar *ccode; - int c; - int extra = 0; - - if (print_lengths) - fprintf(f, "%3d ", (int)(code - codestart)); - else - fprintf(f, " "); - - switch(*code) - { -/* ========================================================================== */ - /* These cases are never obeyed. This is a fudge that causes a compile- - time error if the vectors OP_names or _pcre_OP_lengths, which are indexed - by opcode, are not the correct length. It seems to be the only way to do - such a check at compile time, as the sizeof() operator does not work in - the C preprocessor. We do this while compiling pcretest, because that - #includes pcre_tables.c, which holds _pcre_OP_lengths. We can't do this - when building pcre_compile.c with PCRE_DEBUG set, because it doesn't then - know the size of _pcre_OP_lengths. */ - -#ifdef COMPILING_PCRETEST - case OP_TABLE_LENGTH: - case OP_TABLE_LENGTH + - ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && - (sizeof(_pcre_OP_lengths) == OP_TABLE_LENGTH)): - break; -#endif -/* ========================================================================== */ - - case OP_END: - fprintf(f, " %s\n", OP_names[*code]); - fprintf(f, "------------------------------------------------------------------\n"); - return; - - case OP_OPT: - fprintf(f, " %.2x %s", code[1], OP_names[*code]); - break; - - case OP_CHAR: - fprintf(f, " "); - do - { - code++; - code += 1 + print_char(f, code, utf8); - } - while (*code == OP_CHAR); - fprintf(f, "\n"); - continue; - - case OP_CHARNC: - fprintf(f, " NC "); - do - { - code++; - code += 1 + print_char(f, code, utf8); - } - while (*code == OP_CHARNC); - fprintf(f, "\n"); - continue; - - case OP_CBRA: - case OP_SCBRA: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE)); - break; - - case OP_BRA: - case OP_SBRA: - case OP_KETRMAX: - case OP_KETRMIN: - case OP_ALT: - case OP_KET: - case OP_ASSERT: - case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: - case OP_ONCE: - case OP_COND: - case OP_SCOND: - case OP_REVERSE: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_CLOSE: - fprintf(f, " %s %d", OP_names[*code], GET2(code, 1)); - break; - - case OP_CREF: - case OP_NCREF: - fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); - break; - - case OP_RREF: - c = GET2(code, 1); - if (c == RREF_ANY) - fprintf(f, " Cond recurse any"); - else - fprintf(f, " Cond recurse %d", c); - break; - - case OP_NRREF: - c = GET2(code, 1); - if (c == RREF_ANY) - fprintf(f, " Cond nrecurse any"); - else - fprintf(f, " Cond nrecurse %d", c); - break; - - case OP_DEF: - fprintf(f, " Cond def"); - break; - - case OP_STAR: - case OP_MINSTAR: - case OP_POSSTAR: - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - case OP_QUERY: - case OP_MINQUERY: - case OP_POSQUERY: - case OP_TYPESTAR: - case OP_TYPEMINSTAR: - case OP_TYPEPOSSTAR: - case OP_TYPEPLUS: - case OP_TYPEMINPLUS: - case OP_TYPEPOSPLUS: - case OP_TYPEQUERY: - case OP_TYPEMINQUERY: - case OP_TYPEPOSQUERY: - fprintf(f, " "); - if (*code >= OP_TYPESTAR) - { - fprintf(f, "%s", OP_names[code[1]]); - if (code[1] == OP_PROP || code[1] == OP_NOTPROP) - { - fprintf(f, " %s ", get_ucpname(code[2], code[3])); - extra = 2; - } - } - else extra = print_char(f, code+1, utf8); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_EXACT: - case OP_UPTO: - case OP_MINUPTO: - case OP_POSUPTO: - fprintf(f, " "); - extra = print_char(f, code+3, utf8); - fprintf(f, "{"); - if (*code != OP_EXACT) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_MINUPTO) fprintf(f, "?"); - else if (*code == OP_POSUPTO) fprintf(f, "+"); - break; - - case OP_TYPEEXACT: - case OP_TYPEUPTO: - case OP_TYPEMINUPTO: - case OP_TYPEPOSUPTO: - fprintf(f, " %s", OP_names[code[3]]); - if (code[3] == OP_PROP || code[3] == OP_NOTPROP) - { - fprintf(f, " %s ", get_ucpname(code[4], code[5])); - extra = 2; - } - fprintf(f, "{"); - if (*code != OP_TYPEEXACT) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); - else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+"); - break; - - case OP_NOT: - c = code[1]; - if (PRINTABLE(c)) fprintf(f, " [^%c]", c); - else fprintf(f, " [^\\x%02x]", c); - break; - - case OP_NOTSTAR: - case OP_NOTMINSTAR: - case OP_NOTPOSSTAR: - case OP_NOTPLUS: - case OP_NOTMINPLUS: - case OP_NOTPOSPLUS: - case OP_NOTQUERY: - case OP_NOTMINQUERY: - case OP_NOTPOSQUERY: - c = code[1]; - if (PRINTABLE(c)) fprintf(f, " [^%c]", c); - else fprintf(f, " [^\\x%02x]", c); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_NOTEXACT: - case OP_NOTUPTO: - case OP_NOTMINUPTO: - case OP_NOTPOSUPTO: - c = code[3]; - if (PRINTABLE(c)) fprintf(f, " [^%c]{", c); - else fprintf(f, " [^\\x%02x]{", c); - if (*code != OP_NOTEXACT) fprintf(f, "0,"); - fprintf(f, "%d}", GET2(code,1)); - if (*code == OP_NOTMINUPTO) fprintf(f, "?"); - else if (*code == OP_NOTPOSUPTO) fprintf(f, "+"); - break; - - case OP_RECURSE: - if (print_lengths) fprintf(f, "%3d ", GET(code, 1)); - else fprintf(f, " "); - fprintf(f, "%s", OP_names[*code]); - break; - - case OP_REF: - fprintf(f, " \\%d", GET2(code,1)); - ccode = code + _pcre_OP_lengths[*code]; - goto CLASS_REF_REPEAT; - - case OP_CALLOUT: - fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2), - GET(code, 2 + LINK_SIZE)); - break; - - case OP_PROP: - case OP_NOTPROP: - fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2])); - break; - - /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in - having this code always here, and it makes it less messy without all those - #ifdefs. */ - - case OP_CLASS: - case OP_NCLASS: - case OP_XCLASS: - { - int i, min, max; - BOOL printmap; - - fprintf(f, " ["); - - if (*code == OP_XCLASS) - { - extra = GET(code, 1); - ccode = code + LINK_SIZE + 1; - printmap = (*ccode & XCL_MAP) != 0; - if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); - } - else - { - printmap = TRUE; - ccode = code + 1; - } - - /* Print a bit map */ - - if (printmap) - { - for (i = 0; i < 256; i++) - { - if ((ccode[i/8] & (1 << (i&7))) != 0) - { - int j; - for (j = i+1; j < 256; j++) - if ((ccode[j/8] & (1 << (j&7))) == 0) break; - if (i == '-' || i == ']') fprintf(f, "\\"); - if (PRINTABLE(i)) fprintf(f, "%c", i); - else fprintf(f, "\\x%02x", i); - if (--j > i) - { - if (j != i + 1) fprintf(f, "-"); - if (j == '-' || j == ']') fprintf(f, "\\"); - if (PRINTABLE(j)) fprintf(f, "%c", j); - else fprintf(f, "\\x%02x", j); - } - i = j; - } - } - ccode += 32; - } - - /* For an XCLASS there is always some additional data */ - - if (*code == OP_XCLASS) - { - int ch; - while ((ch = *ccode++) != XCL_END) - { - if (ch == XCL_PROP) - { - int ptype = *ccode++; - int pvalue = *ccode++; - fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); - } - else if (ch == XCL_NOTPROP) - { - int ptype = *ccode++; - int pvalue = *ccode++; - fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); - } - else - { - ccode += 1 + print_char(f, ccode, TRUE); - if (ch == XCL_RANGE) - { - fprintf(f, "-"); - ccode += 1 + print_char(f, ccode, TRUE); - } - } - } - } - - /* Indicate a non-UTF8 class which was created by negation */ - - fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); - - /* Handle repeats after a class or a back reference */ - - CLASS_REF_REPEAT: - switch(*ccode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - fprintf(f, "%s", OP_names[*ccode]); - extra += _pcre_OP_lengths[*ccode]; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - min = GET2(ccode,1); - max = GET2(ccode,3); - if (max == 0) fprintf(f, "{%d,}", min); - else fprintf(f, "{%d,%d}", min, max); - if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); - extra += _pcre_OP_lengths[*ccode]; - break; - - /* Do nothing if it's not a repeat; this code stops picky compilers - warning about the lack of a default code path. */ - - default: - break; - } - } - break; - - case OP_MARK: - case OP_PRUNE_ARG: - case OP_SKIP_ARG: - fprintf(f, " %s %s", OP_names[*code], code + 2); - extra += code[1]; - break; - - case OP_THEN: - if (print_lengths) - fprintf(f, " %s %d", OP_names[*code], GET(code, 1)); - else - fprintf(f, " %s", OP_names[*code]); - break; - - case OP_THEN_ARG: - if (print_lengths) - fprintf(f, " %s %d %s", OP_names[*code], GET(code, 1), - code + 2 + LINK_SIZE); - else - fprintf(f, " %s %s", OP_names[*code], code + 2 + LINK_SIZE); - extra += code[1+LINK_SIZE]; - break; - - /* Anything else is just an item with no data*/ - - default: - fprintf(f, " %s", OP_names[*code]); - break; - } - - code += _pcre_OP_lengths[*code] + extra; - fprintf(f, "\n"); - } -} - -/* End of pcre_printint.src */ diff -Nru pcre3-8.12/pcre_refcount.c pcre3-8.31/pcre_refcount.c --- pcre3-8.12/pcre_refcount.c 2008-07-09 15:52:45.000000000 +0000 +++ pcre3-8.31/pcre_refcount.c 2012-01-06 12:50:34.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -68,11 +68,18 @@ a negative error number */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_refcount(pcre *argument_re, int adjust) +#else +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION +pcre16_refcount(pcre16 *argument_re, int adjust) +#endif { -real_pcre *re = (real_pcre *)argument_re; +REAL_PCRE *re = (REAL_PCRE *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; +if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; +if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; re->ref_count = (-adjust > re->ref_count)? 0 : (adjust + re->ref_count > 65535)? 65535 : re->ref_count + adjust; diff -Nru pcre3-8.12/pcre_scanner_unittest.cc pcre3-8.31/pcre_scanner_unittest.cc --- pcre3-8.12/pcre_scanner_unittest.cc 2010-06-01 11:44:28.000000000 +0000 +++ pcre3-8.31/pcre_scanner_unittest.cc 2011-05-01 08:16:45.000000000 +0000 @@ -37,6 +37,7 @@ #endif #include +#include /* for strchr */ #include #include diff -Nru pcre3-8.12/pcre_string_utils.c pcre3-8.31/pcre_string_utils.c --- pcre3-8.12/pcre_string_utils.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/pcre_string_utils.c 2011-12-28 16:57:56.000000000 +0000 @@ -0,0 +1,168 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 1997-2012 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + + +/* This module contains an internal function that is used to match an extended +class. It is used by both pcre_exec() and pcre_def_exec(). */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre_internal.h" + +#ifndef COMPILE_PCRE8 + +/************************************************* +* Compare string utilities * +*************************************************/ + +/* The following two functions compares two strings. Basically an strcmp +for non 8 bit characters. + +Arguments: + str1 first string + str2 second string + +Returns: 0 if both string are equal (like strcmp), 1 otherwise +*/ + +int +PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2) +{ +pcre_uchar c1; +pcre_uchar c2; + +while (*str1 != '\0' || *str2 != '\0') + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +int +PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2) +{ +const pcre_uint8 *ustr2 = (pcre_uint8 *)str2; +pcre_uchar c1; +pcre_uchar c2; + +while (*str1 != '\0' || *ustr2 != '\0') + { + c1 = *str1++; + c2 = (pcre_uchar)*ustr2++; + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +/* The following two functions compares two, fixed length +strings. Basically an strncmp for non 8 bit characters. + +Arguments: + str1 first string + str2 second string + num size of the string + +Returns: 0 if both string are equal (like strcmp), 1 otherwise +*/ + +int +PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num) +{ +pcre_uchar c1; +pcre_uchar c2; + +while (num-- > 0) + { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +int +PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num) +{ +const pcre_uint8 *ustr2 = (pcre_uint8 *)str2; +pcre_uchar c1; +pcre_uchar c2; + +while (num-- > 0) + { + c1 = *str1++; + c2 = (pcre_uchar)*ustr2++; + if (c1 != c2) + return ((c1 > c2) << 1) - 1; + } +/* Both length and characters must be equal. */ +return 0; +} + +/* The following function returns with the length of +a zero terminated string. Basically an strlen for non 8 bit characters. + +Arguments: + str string + +Returns: length of the string +*/ + +unsigned int +PRIV(strlen_uc)(const pcre_uchar *str) +{ +unsigned int len = 0; +while (*str++ != 0) + len++; +return len; +} + +#endif /* COMPILE_PCRE8 */ + +/* End of pcre_string_utils.c */ diff -Nru pcre3-8.12/pcre_study.c pcre3-8.31/pcre_study.c --- pcre3-8.12/pcre_study.c 2010-10-27 16:36:01.000000000 +0000 +++ pcre3-8.31/pcre_study.c 2012-07-06 08:51:36.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ /* Returns from set_start_bits() */ -enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE }; +enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN }; @@ -66,25 +66,30 @@ rather than bytes. Arguments: - code pointer to start of group (the bracket) - startcode pointer to start of the whole pattern - options the compiling options + code pointer to start of group (the bracket) + startcode pointer to start of the whole pattern + options the compiling options + int RECURSE depth Returns: the minimum length - -1 if \C was encountered + -1 if \C in UTF-8 mode or (*ACCEPT) was encountered -2 internal error (missing capturing bracket) + -3 internal error (opcode not listed) */ static int -find_minlength(const uschar *code, const uschar *startcode, int options) +find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options, + int recurse_depth) { int length = -1; -BOOL utf8 = (options & PCRE_UTF8) != 0; +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ +BOOL utf = (options & PCRE_UTF8) != 0; BOOL had_recurse = FALSE; register int branchlength = 0; -register uschar *cc = (uschar *)code + 1 + LINK_SIZE; +register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE; -if (*code == OP_CBRA || *code == OP_SCBRA) cc += 2; +if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ @@ -92,7 +97,7 @@ for (;;) { int d, min; - uschar *cs, *ce; + pcre_uchar *cs, *ce; register int op = *cc; switch (op) @@ -118,26 +123,40 @@ case OP_SCBRA: case OP_BRA: case OP_SBRA: + case OP_CBRAPOS: + case OP_SCBRAPOS: + case OP_BRAPOS: + case OP_SBRAPOS: case OP_ONCE: - d = find_minlength(cc, startcode, options); + case OP_ONCE_NC: + d = find_minlength(cc, startcode, options, recurse_depth); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; + /* ACCEPT makes things far too complicated; we have to give up. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + return -1; + /* Reached end of a branch; if it's a ket it is the end of a nested - call. If it's ALT it is an alternation in a nested call. If it is - END it's the end of the outer call. All can be handled by the same code. */ + call. If it's ALT it is an alternation in a nested call. If it is END it's + the end of the outer call. All can be handled by the same code. If an + ACCEPT was previously encountered, use the length that was in force at that + time, and pass back the shortest ACCEPT length. */ case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: case OP_END: if (length < 0 || (!had_recurse && branchlength < length)) length = branchlength; - if (*cc != OP_ALT) return length; + if (op != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; had_recurse = FALSE; @@ -160,25 +179,27 @@ case OP_RREF: case OP_NRREF: case OP_DEF: - case OP_OPT: case OP_CALLOUT: case OP_SOD: case OP_SOM: case OP_EOD: case OP_EODN: case OP_CIRC: + case OP_CIRCM: case OP_DOLL: + case OP_DOLLM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; break; /* Skip over a subpattern that has a {0} or {0,x} quantifier */ case OP_BRAZERO: case OP_BRAMINZERO: + case OP_BRAPOSZERO: case OP_SKIPZERO: - cc += _pcre_OP_lengths[*cc]; + cc += PRIV(OP_lengths)[*cc]; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; @@ -186,18 +207,25 @@ /* Handle literal characters and + repetitions */ case OP_CHAR: - case OP_CHARNC: + case OP_CHARI: case OP_NOT: + case OP_NOTI: case OP_PLUS: + case OP_PLUSI: case OP_MINPLUS: + case OP_MINPLUSI: case OP_POSPLUS: + case OP_POSPLUSI: case OP_NOTPLUS: + case OP_NOTPLUSI: case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: branchlength++; cc += 2; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -212,17 +240,20 @@ need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: + case OP_EXACTI: case OP_NOTEXACT: + case OP_NOTEXACTI: branchlength += GET2(cc,1); - cc += 4; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); - cc += (cc[3] == OP_PROP || cc[3] == OP_NOTPROP)? 6 : 4; + cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0); break; /* Handle single-char non-literal matchers */ @@ -249,18 +280,21 @@ cc++; break; - /* "Any newline" might match two characters */ + /* "Any newline" might match two characters, but it also might match just + one. */ case OP_ANYNL: - branchlength += 2; + branchlength += 1; cc++; break; - /* The single-byte matcher means we can't proceed in UTF-8 mode */ + /* The single-byte matcher means we can't proceed in UTF-8 mode. (In + non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever + appear, but leave the code, just in case.) */ case OP_ANYBYTE: -#ifdef SUPPORT_UTF8 - if (utf8) return -1; +#ifdef SUPPORT_UTF + if (utf) return -1; #endif branchlength++; cc++; @@ -276,27 +310,28 @@ case OP_TYPEPOSSTAR: case OP_TYPEPOSQUERY: if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2; - cc += _pcre_OP_lengths[op]; + cc += PRIV(OP_lengths)[op]; break; case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2; - cc += _pcre_OP_lengths[op]; + if (cc[1 + IMM2_SIZE] == OP_PROP + || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; + cc += PRIV(OP_lengths)[op]; break; /* Check a class for variable quantification */ -#ifdef SUPPORT_UTF8 +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: - cc += GET(cc, 1) - 33; + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: - cc += 33; + cc += PRIV(OP_lengths)[OP_CLASS]; switch (*cc) { @@ -315,7 +350,7 @@ case OP_CRRANGE: case OP_CRMINRANGE: branchlength += GET2(cc,1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -337,9 +372,10 @@ that case we must set the minimum length to zero. */ case OP_REF: + case OP_REFI: if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) { - ce = cs = (uschar *)_pcre_find_bracket(startcode, utf8, GET2(cc, 1)); + ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); if (cc > cs && cc < ce) @@ -347,10 +383,13 @@ d = 0; had_recurse = TRUE; } - else d = find_minlength(cs, startcode, options); + else + { + d = find_minlength(cs, startcode, options, recurse_depth); + } } else d = 0; - cc += 3; + cc += 1 + IMM2_SIZE; /* Handle repeated back references */ @@ -364,10 +403,16 @@ cc++; break; + case OP_CRPLUS: + case OP_CRMINPLUS: + min = 1; + cc++; + break; + case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(cc, 1); - cc += 5; + cc += 1 + 2 * IMM2_SIZE; break; default: @@ -378,39 +423,71 @@ branchlength += min * d; break; + /* We can easily detect direct recursion, but not mutual recursion. This is + caught by a recursion depth count. */ + case OP_RECURSE: - cs = ce = (uschar *)startcode + GET(cc, 1); - if (cs == NULL) return -2; + cs = ce = (pcre_uchar *)startcode + GET(cc, 1); do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) + if ((cc > cs && cc < ce) || recurse_depth > 10) had_recurse = TRUE; else - branchlength += find_minlength(cs, startcode, options); + { + branchlength += find_minlength(cs, startcode, options, recurse_depth + 1); + } cc += 1 + LINK_SIZE; break; /* Anything else does not or need not match a character. We can get the item's length from the table, but for those that can match zero occurrences - of a character, we must take special action for UTF-8 characters. */ + of a character, we must take special action for UTF-8 characters. As it + happens, the "NOT" versions of these opcodes are used at present only for + ASCII characters, so they could be omitted from this list. However, in + future that may change, so we include them here so as not to leave a + gotcha for a future maintainer. */ case OP_UPTO: + case OP_UPTOI: case OP_NOTUPTO: + case OP_NOTUPTOI: case OP_MINUPTO: + case OP_MINUPTOI: case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: case OP_POSUPTO: + case OP_POSUPTOI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_STAR: + case OP_STARI: + case OP_NOTSTAR: + case OP_NOTSTARI: case OP_MINSTAR: + case OP_MINSTARI: case OP_NOTMINSTAR: + case OP_NOTMINSTARI: case OP_POSSTAR: + case OP_POSSTARI: case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_QUERY: + case OP_QUERYI: + case OP_NOTQUERY: + case OP_NOTQUERYI: case OP_MINQUERY: + case OP_MINQUERYI: case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: case OP_POSQUERY: + case OP_POSQUERYI: case OP_NOTPOSQUERY: - cc += _pcre_OP_lengths[op]; -#ifdef SUPPORT_UTF8 - if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f]; + case OP_NOTPOSQUERYI: + + cc += PRIV(OP_lengths)[op]; +#ifdef SUPPORT_UTF + if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif break; @@ -419,20 +496,27 @@ case OP_MARK: case OP_PRUNE_ARG: case OP_SKIP_ARG: - cc += _pcre_OP_lengths[op] + cc[1]; + case OP_THEN_ARG: + cc += PRIV(OP_lengths)[op] + cc[1]; break; - case OP_THEN_ARG: - cc += _pcre_OP_lengths[op] + cc[1+LINK_SIZE]; + /* The remaining opcodes are just skipped over. */ + + case OP_CLOSE: + case OP_COMMIT: + case OP_FAIL: + case OP_PRUNE: + case OP_SET_SOM: + case OP_SKIP: + case OP_THEN: + cc += PRIV(OP_lengths)[op]; break; - /* For the record, these are the opcodes that are matched by "default": - OP_ACCEPT, OP_CLOSE, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_SET_SOM, OP_SKIP, - OP_THEN. */ + /* This should not occur: we list all opcodes explicitly so that when + new ones get added they are properly considered. */ default: - cc += _pcre_OP_lengths[op]; - break; + return -3; } } /* Control never gets here */ @@ -454,29 +538,30 @@ p points to the character caseless the caseless flag cd the block with char table pointers - utf8 TRUE for UTF-8 mode + utf TRUE for UTF-8 / UTF-16 mode Returns: pointer after the character */ -static const uschar * -set_table_bit(uschar *start_bits, const uschar *p, BOOL caseless, - compile_data *cd, BOOL utf8) +static const pcre_uchar * +set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless, + compile_data *cd, BOOL utf) { unsigned int c = *p; +#ifdef COMPILE_PCRE8 SET_BIT(c); -#ifdef SUPPORT_UTF8 -if (utf8 && c > 127) +#ifdef SUPPORT_UTF +if (utf && c > 127) { GETCHARINC(c, p); #ifdef SUPPORT_UCP if (caseless) { - uschar buff[8]; + pcre_uchar buff[6]; c = UCD_OTHERCASE(c); - (void)_pcre_ord2utf8(c, buff); + (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } #endif @@ -488,6 +573,36 @@ if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; +#endif + +#ifdef COMPILE_PCRE16 +if (c > 0xff) + { + c = 0xff; + caseless = FALSE; + } +SET_BIT(c); + +#ifdef SUPPORT_UTF +if (utf && c > 127) + { + GETCHARINC(c, p); +#ifdef SUPPORT_UCP + if (caseless) + { + c = UCD_OTHERCASE(c); + if (c > 0xff) + c = 0xff; + SET_BIT(c); + } +#endif + return p; + } +#endif + +if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); +return p + 1; +#endif } @@ -513,21 +628,23 @@ */ static void -set_type_bits(uschar *start_bits, int cbit_type, int table_limit, +set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type]; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit == 32) return; for (c = 128; c < 256; c++) { if ((cd->cbits[c/8] & (1 << (c&7))) != 0) { - uschar buff[8]; - (void)_pcre_ord2utf8(c, buff); + pcre_uchar buff[6]; + (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } } +#endif } @@ -553,12 +670,14 @@ */ static void -set_nottype_bits(uschar *start_bits, int cbit_type, int table_limit, +set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type]; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff; +#endif } @@ -578,22 +697,26 @@ Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 - caseless the current state of the caseless flag - utf8 TRUE if in UTF-8 mode + utf TRUE if in UTF-8 / UTF-16 mode cd the block with char table pointers Returns: SSB_FAIL => Failed to find any starting bytes SSB_DONE => Found mandatory starting bytes SSB_CONTINUE => Found optional starting bytes + SSB_UNKNOWN => Hit an unrecognized opcode */ static int -set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, - BOOL utf8, compile_data *cd) +set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf, + compile_data *cd) { register int c; int yield = SSB_DONE; -int table_limit = utf8? 16:32; +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +int table_limit = utf? 16:32; +#else +int table_limit = 32; +#endif #if 0 /* ========================================================================= */ @@ -614,19 +737,108 @@ do { - const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE; BOOL try_next = TRUE; + const pcre_uchar *tcode = code + 1 + LINK_SIZE; + + if (*code == OP_CBRA || *code == OP_SCBRA || + *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE; while (try_next) /* Loop for items in this branch */ { int rc; + switch(*tcode) { - /* Fail if we reach something we don't understand */ + /* If we reach something we don't understand, it means a new opcode has + been created that hasn't been added to this code. Hopefully this problem + will be discovered during testing. */ default: + return SSB_UNKNOWN; + + /* Fail for a valid opcode that implies no starting bits. */ + + case OP_ACCEPT: + case OP_ASSERT_ACCEPT: + case OP_ALLANY: + case OP_ANY: + case OP_ANYBYTE: + case OP_CIRC: + case OP_CIRCM: + case OP_CLOSE: + case OP_COMMIT: + case OP_COND: + case OP_CREF: + case OP_DEF: + case OP_DOLL: + case OP_DOLLM: + case OP_END: + case OP_EOD: + case OP_EODN: + case OP_EXTUNI: + case OP_FAIL: + case OP_MARK: + case OP_NCREF: + case OP_NOT: + case OP_NOTEXACT: + case OP_NOTEXACTI: + case OP_NOTI: + case OP_NOTMINPLUS: + case OP_NOTMINPLUSI: + case OP_NOTMINQUERY: + case OP_NOTMINQUERYI: + case OP_NOTMINSTAR: + case OP_NOTMINSTARI: + case OP_NOTMINUPTO: + case OP_NOTMINUPTOI: + case OP_NOTPLUS: + case OP_NOTPLUSI: + case OP_NOTPOSPLUS: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERY: + case OP_NOTPOSQUERYI: + case OP_NOTPOSSTAR: + case OP_NOTPOSSTARI: + case OP_NOTPOSUPTO: + case OP_NOTPOSUPTOI: + case OP_NOTPROP: + case OP_NOTQUERY: + case OP_NOTQUERYI: + case OP_NOTSTAR: + case OP_NOTSTARI: + case OP_NOTUPTO: + case OP_NOTUPTOI: + case OP_NOT_HSPACE: + case OP_NOT_VSPACE: + case OP_NRREF: + case OP_PROP: + case OP_PRUNE: + case OP_PRUNE_ARG: + case OP_RECURSE: + case OP_REF: + case OP_REFI: + case OP_REVERSE: + case OP_RREF: + case OP_SCOND: + case OP_SET_SOM: + case OP_SKIP: + case OP_SKIP_ARG: + case OP_SOD: + case OP_SOM: + case OP_THEN: + case OP_THEN_ARG: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: +#endif return SSB_FAIL; + /* We can ignore word boundary tests. */ + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + tcode++; + break; + /* If we hit a bracket or a positive lookahead assertion, recurse to set bits from within the subpattern. If it can't find anything, we have to give up. If it finds some mandatory character(s), we are done for this @@ -636,10 +848,15 @@ case OP_SBRA: case OP_CBRA: case OP_SCBRA: + case OP_BRAPOS: + case OP_SBRAPOS: + case OP_CBRAPOS: + case OP_SCBRAPOS: case OP_ONCE: + case OP_ONCE_NC: case OP_ASSERT: - rc = set_start_bits(tcode, start_bits, caseless, utf8, cd); - if (rc == SSB_FAIL) return SSB_FAIL; + rc = set_start_bits(tcode, start_bits, utf, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; if (rc == SSB_DONE) try_next = FALSE; else { do tcode += GET(tcode, 1); while (*tcode == OP_ALT); @@ -662,6 +879,7 @@ case OP_KET: case OP_KETRMAX: case OP_KETRMIN: + case OP_KETRPOS: return SSB_CONTINUE; /* Skip over callout */ @@ -679,19 +897,13 @@ tcode += 1 + LINK_SIZE; break; - /* Skip over an option setting, changing the caseless flag */ - - case OP_OPT: - caseless = (tcode[1] & PCRE_CASELESS) != 0; - tcode += 2; - break; - /* BRAZERO does the bracket, but carries on. */ case OP_BRAZERO: case OP_BRAMINZERO: - if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL) - return SSB_FAIL; + case OP_BRAPOSZERO: + rc = set_start_bits(++tcode, start_bits, utf, cd); + if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; /* ========================================================================= See the comment at the head of this function concerning the next line, which was an old fudge for the benefit of OS/2. @@ -717,7 +929,16 @@ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: - tcode = set_table_bit(start_bits, tcode + 1, caseless, cd, utf8); + tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); + break; + + case OP_STARI: + case OP_MINSTARI: + case OP_POSSTARI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_POSQUERYI: + tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); break; /* Single-char upto sets the bit and tries the next */ @@ -725,20 +946,36 @@ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: - tcode = set_table_bit(start_bits, tcode + 3, caseless, cd, utf8); + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf); break; - /* At least one single char sets the bit and stops */ + case OP_UPTOI: + case OP_MINUPTOI: + case OP_POSUPTOI: + tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf); + break; - case OP_EXACT: /* Fall through */ - tcode += 2; + /* At least one single char sets the bit and stops */ + case OP_EXACT: + tcode += IMM2_SIZE; + /* Fall through */ case OP_CHAR: - case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: - (void)set_table_bit(start_bits, tcode + 1, caseless, cd, utf8); + (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf); + try_next = FALSE; + break; + + case OP_EXACTI: + tcode += IMM2_SIZE; + /* Fall through */ + case OP_CHARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSPLUSI: + (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf); try_next = FALSE; break; @@ -751,14 +988,28 @@ case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif + } + else +#endif /* SUPPORT_UTF */ + { + SET_BIT(0xA0); +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0xA0); try_next = FALSE; break; @@ -768,12 +1019,26 @@ SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); + SET_BIT(0xFF); /* For characters > 255 */ +#endif + } + else +#endif /* SUPPORT_UTF */ + { + SET_BIT(0x85); +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0x85); try_next = FALSE; break; @@ -831,7 +1096,7 @@ break; case OP_TYPEEXACT: - tcode += 3; + tcode += 1 + IMM2_SIZE; break; /* Zero or more repeats of character types set the bits and then @@ -840,7 +1105,7 @@ case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += 2; /* Fall through */ + tcode += IMM2_SIZE; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -858,14 +1123,23 @@ case OP_HSPACE: SET_BIT(0x09); SET_BIT(0x20); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+00A0 */ SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xA0); + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0xA0); + else +#endif /* SUPPORT_UTF */ + SET_BIT(0xA0); break; case OP_ANYNL: @@ -874,12 +1148,21 @@ SET_BIT(0x0B); SET_BIT(0x0C); SET_BIT(0x0D); - if (utf8) +#ifdef SUPPORT_UTF + if (utf) { +#ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); + SET_BIT(0xFF); /* For characters > 255 */ +#endif } - else SET_BIT(0x85); + else +#endif /* SUPPORT_UTF */ + SET_BIT(0x85); break; case OP_NOT_DIGIT: @@ -926,18 +1209,23 @@ character with a value > 255. */ case OP_NCLASS: -#ifdef SUPPORT_UTF8 - if (utf8) +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) { start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } #endif +#ifdef COMPILE_PCRE16 + SET_BIT(0xFF); /* For characters > 255 */ +#endif /* Fall through */ case OP_CLASS: { + pcre_uint8 *map; tcode++; + map = (pcre_uint8 *)tcode; /* In UTF-8 mode, the bits in a bit map correspond to character values, not to byte values. However, the bit map we are constructing is @@ -945,13 +1233,13 @@ value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ -#ifdef SUPPORT_UTF8 - if (utf8) +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 + if (utf) { - for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; + for (c = 0; c < 16; c++) start_bits[c] |= map[c]; for (c = 128; c < 256; c++) { - if ((tcode[c/8] && (1 << (c&7))) != 0) + if ((map[c/8] && (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ @@ -959,18 +1247,17 @@ } } } - - /* In non-UTF-8 mode, the two bit maps are completely compatible. */ - else #endif { - for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; + /* In non-UTF-8 mode, the two bit maps are completely compatible. */ + for (c = 0; c < 32; c++) start_bits[c] |= map[c]; } - /* Advance past the bit map, and act on what follows */ + /* Advance past the bit map, and act on what follows. For a zero + minimum repeat, continue; otherwise stop processing. */ - tcode += 32; + tcode += 32 / sizeof(pcre_uchar); switch (*tcode) { case OP_CRSTAR: @@ -982,7 +1269,7 @@ case OP_CRRANGE: case OP_CRMINRANGE: - if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; + if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE; else try_next = FALSE; break; @@ -1004,12 +1291,14 @@ + + /************************************************* * Study a compiled expression * *************************************************/ /* This function is handed a compiled expression that it must study to produce -information that will speed up the matching. It returns a pcre_extra block +information that will speed up the matching. It returns a pcre[16]_extra block which then gets handed back to pcre_exec(). Arguments: @@ -1018,23 +1307,28 @@ errorptr points to where to place error messages; set NULL unless error -Returns: pointer to a pcre_extra block, with study_data filled in and the - appropriate flags set; +Returns: pointer to a pcre[16]_extra block, with study_data filled in and + the appropriate flags set; NULL on error or if no optimization possible */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION pcre_study(const pcre *external_re, int options, const char **errorptr) +#else +PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION +pcre16_study(const pcre16 *external_re, int options, const char **errorptr) +#endif { int min; BOOL bits_set = FALSE; -uschar start_bits[32]; -pcre_extra *extra; +pcre_uint8 start_bits[32]; +PUBL(extra) *extra = NULL; pcre_study_data *study; -const uschar *tables; -uschar *code; +const pcre_uint8 *tables; +pcre_uchar *code; compile_data compile_block; -const real_pcre *re = (const real_pcre *)external_re; +const REAL_PCRE *re = (const REAL_PCRE *)external_re; *errorptr = NULL; @@ -1044,13 +1338,23 @@ return NULL; } +if ((re->flags & PCRE_MODE) == 0) + { +#ifdef COMPILE_PCRE8 + *errorptr = "argument is compiled in 16 bit mode"; +#else + *errorptr = "argument is compiled in 8 bit mode"; +#endif + return NULL; + } + if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) { *errorptr = "unknown or incorrect option bit(s) set"; return NULL; } -code = (uschar *)re + re->name_table_offset + +code = (pcre_uchar *)re + re->name_table_offset + (re->name_count * re->name_entry_size); /* For an anchored pattern, or an unanchored pattern that has a first char, or @@ -1060,12 +1364,21 @@ if ((re->options & PCRE_ANCHORED) == 0 && (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0) { + int rc; + /* Set the character tables in the block that is passed around */ tables = re->tables; + +#ifdef COMPILE_PCRE8 if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); +#else + if (tables == NULL) + (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, + (void *)(&tables)); +#endif compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; @@ -1074,56 +1387,148 @@ /* See if we can find a fixed set of initial characters for the pattern. */ - memset(start_bits, 0, 32 * sizeof(uschar)); - bits_set = set_start_bits(code, start_bits, - (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0, - &compile_block) == SSB_DONE; + memset(start_bits, 0, 32 * sizeof(pcre_uint8)); + rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0, + &compile_block); + bits_set = rc == SSB_DONE; + if (rc == SSB_UNKNOWN) + { + *errorptr = "internal error: opcode not recognized"; + return NULL; + } } /* Find the minimum length of subject string. */ -min = find_minlength(code, code, re->options); +switch(min = find_minlength(code, code, re->options, 0)) + { + case -2: *errorptr = "internal error: missing capturing bracket"; return NULL; + case -3: *errorptr = "internal error: opcode not recognized"; return NULL; + default: break; + } -/* Return NULL if no optimization is possible. */ +/* If a set of starting bytes has been identified, or if the minimum length is +greater than zero, or if JIT optimization has been requested, get a +pcre[16]_extra block and a pcre_study_data block. The study data is put in the +latter, which is pointed to by the former, which may also get additional data +set later by the calling program. At the moment, the size of pcre_study_data +is fixed. We nevertheless save it in a field for returning via the +pcre_fullinfo() function so that if it becomes variable in the future, +we don't have to change that code. */ + +if (bits_set || min > 0 +#ifdef SUPPORT_JIT + || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0 +#endif + ) + { + extra = (PUBL(extra) *)(PUBL(malloc)) + (sizeof(PUBL(extra)) + sizeof(pcre_study_data)); + if (extra == NULL) + { + *errorptr = "failed to get memory"; + return NULL; + } -if (!bits_set && min < 0) return NULL; + study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra))); + extra->flags = PCRE_EXTRA_STUDY_DATA; + extra->study_data = study; + + study->size = sizeof(pcre_study_data); + study->flags = 0; + + /* Set the start bits always, to avoid unset memory errors if the + study data is written to a file, but set the flag only if any of the bits + are set, to save time looking when none are. */ -/* Get a pcre_extra block and a pcre_study_data block. The study data is put in -the latter, which is pointed to by the former, which may also get additional -data set later by the calling program. At the moment, the size of -pcre_study_data is fixed. We nevertheless save it in a field for returning via -the pcre_fullinfo() function so that if it becomes variable in the future, we -don't have to change that code. */ + if (bits_set) + { + study->flags |= PCRE_STUDY_MAPPED; + memcpy(study->start_bits, start_bits, sizeof(start_bits)); + } + else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8)); -extra = (pcre_extra *)(pcre_malloc) - (sizeof(pcre_extra) + sizeof(pcre_study_data)); +#ifdef PCRE_DEBUG + if (bits_set) + { + pcre_uint8 *ptr = start_bits; + int i; -if (extra == NULL) - { - *errorptr = "failed to get memory"; - return NULL; - } + printf("Start bits:\n"); + for (i = 0; i < 32; i++) + printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n"); + } +#endif -study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); -extra->flags = PCRE_EXTRA_STUDY_DATA; -extra->study_data = study; + /* Always set the minlength value in the block, because the JIT compiler + makes use of it. However, don't set the bit unless the length is greater than + zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time + checking the zero case. */ -study->size = sizeof(pcre_study_data); -study->flags = 0; + if (min > 0) + { + study->flags |= PCRE_STUDY_MINLEN; + study->minlength = min; + } + else study->minlength = 0; -if (bits_set) - { - study->flags |= PCRE_STUDY_MAPPED; - memcpy(study->start_bits, start_bits, sizeof(start_bits)); - } + /* If JIT support was compiled and requested, attempt the JIT compilation. + If no starting bytes were found, and the minimum length is zero, and JIT + compilation fails, abandon the extra block and return NULL. */ + +#ifdef SUPPORT_JIT + extra->executable_jit = NULL; + if ((options & PCRE_STUDY_JIT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE); + if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0) + PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE); -if (min >= 0) - { - study->flags |= PCRE_STUDY_MINLEN; - study->minlength = min; + if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0) + { +#ifdef COMPILE_PCRE8 + pcre_free_study(extra); +#endif +#ifdef COMPILE_PCRE16 + pcre16_free_study(extra); +#endif + extra = NULL; + } +#endif } return extra; } + +/************************************************* +* Free the study data * +*************************************************/ + +/* This function frees the memory that was obtained by pcre_study(). + +Argument: a pointer to the pcre[16]_extra block +Returns: nothing +*/ + +#ifdef COMPILE_PCRE8 +PCRE_EXP_DEFN void +pcre_free_study(pcre_extra *extra) +#else +PCRE_EXP_DEFN void +pcre16_free_study(pcre16_extra *extra) +#endif +{ +if (extra == NULL) + return; +#ifdef SUPPORT_JIT +if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && + extra->executable_jit != NULL) + PRIV(jit_free)(extra->executable_jit); +#endif +PUBL(free)(extra); +} + /* End of pcre_study.c */ diff -Nru pcre3-8.12/pcre_tables.c pcre3-8.31/pcre_tables.c --- pcre3-8.12/pcre_tables.c 2010-05-04 16:06:12.000000000 +0000 +++ pcre3-8.31/pcre_tables.c 2012-06-02 10:55:16.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ ----------------------------------------------------------------------------- */ +#ifndef PCRE_INCLUDED /* This module contains some fixed tables that are used by more than one of the PCRE code modules. The tables are also #included by the pcretest program, which @@ -50,11 +51,12 @@ #include "pcre_internal.h" +#endif /* PCRE_INCLUDED */ /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre_internal.h. */ -const uschar _pcre_OP_lengths[] = { OP_LENGTHS }; +const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS }; @@ -65,31 +67,38 @@ /* These are the breakpoints for different numbers of bytes in a UTF-8 character. */ -#ifdef SUPPORT_UTF8 +#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \ + || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16) -const int _pcre_utf8_table1[] = +/* These tables are also required by pcretest in 16 bit mode. */ + +const int PRIV(utf8_table1)[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; -const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int); +const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int); /* These are the indicator bits and the mask for the data bits to set in the first byte of a character, indexed by the number of additional bytes. */ -const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; -const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; +const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; +const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /* Table of the number of extra bytes, indexed by the first byte masked with 0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */ -const uschar _pcre_utf8_table4[] = { +const pcre_uint8 PRIV(utf8_table4)[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; +#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/ + +#ifdef SUPPORT_UTF + /* Table to translate from particular type value to the general value. */ -const int _pcre_ucp_gentype[] = { +const int PRIV(ucp_gentype)[] = { ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ @@ -100,6 +109,21 @@ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; +#ifdef SUPPORT_JIT +/* This table reverses PRIV(ucp_gentype). We can save the cost +of a memory load. */ + +const int PRIV(ucp_typerange)[] = { + ucp_Cc, ucp_Cs, + ucp_Ll, ucp_Lu, + ucp_Mc, ucp_Mn, + ucp_Nd, ucp_No, + ucp_Pc, ucp_Ps, + ucp_Sc, ucp_So, + ucp_Zl, ucp_Zs, +}; +#endif /* SUPPORT_JIT */ + /* The pcre_utt[] table below translates Unicode property names into type and code values. It is searched by binary chop, so must be in collating sequence of name. Originally, the table contained pointers to the name strings in the first @@ -110,7 +134,7 @@ data are unlikely. July 2008: There is now a script called maint/GenerateUtt.py that can be used -to generate this data instead of maintaining it entirely by hand. +to generate this data automatically instead of maintaining it by hand. The script was updated in March 2009 to generate a new EBCDIC-compliant version. Like all other character and string literals that are compared against @@ -123,8 +147,10 @@ #define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0" #define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0" +#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0" #define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0" #define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0" +#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0" #define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0" #define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0" #define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0" @@ -133,6 +159,7 @@ #define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0" #define STRING_Cc0 STR_C STR_c "\0" #define STRING_Cf0 STR_C STR_f "\0" +#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0" #define STRING_Cham0 STR_C STR_h STR_a STR_m "\0" #define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0" #define STRING_Cn0 STR_C STR_n "\0" @@ -186,9 +213,13 @@ #define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0" #define STRING_M0 STR_M "\0" #define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0" +#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0" #define STRING_Mc0 STR_M STR_c "\0" #define STRING_Me0 STR_M STR_e "\0" #define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0" +#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0" +#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" +#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0" #define STRING_Mn0 STR_M STR_n "\0" #define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0" #define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0" @@ -222,11 +253,13 @@ #define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0" #define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0" #define STRING_Sc0 STR_S STR_c "\0" +#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0" #define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0" #define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0" #define STRING_Sk0 STR_S STR_k "\0" #define STRING_Sm0 STR_S STR_m "\0" #define STRING_So0 STR_S STR_o "\0" +#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0" #define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0" #define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0" #define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0" @@ -235,6 +268,7 @@ #define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0" #define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0" #define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0" +#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0" #define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0" #define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0" #define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0" @@ -253,15 +287,17 @@ #define STRING_Zp0 STR_Z STR_p "\0" #define STRING_Zs0 STR_Z STR_s "\0" -const char _pcre_utt_names[] = +const char PRIV(utt_names)[] = STRING_Any0 STRING_Arabic0 STRING_Armenian0 STRING_Avestan0 STRING_Balinese0 STRING_Bamum0 + STRING_Batak0 STRING_Bengali0 STRING_Bopomofo0 + STRING_Brahmi0 STRING_Braille0 STRING_Buginese0 STRING_Buhid0 @@ -270,6 +306,7 @@ STRING_Carian0 STRING_Cc0 STRING_Cf0 + STRING_Chakma0 STRING_Cham0 STRING_Cherokee0 STRING_Cn0 @@ -323,9 +360,13 @@ STRING_Lydian0 STRING_M0 STRING_Malayalam0 + STRING_Mandaic0 STRING_Mc0 STRING_Me0 STRING_Meetei_Mayek0 + STRING_Meroitic_Cursive0 + STRING_Meroitic_Hieroglyphs0 + STRING_Miao0 STRING_Mn0 STRING_Mongolian0 STRING_Myanmar0 @@ -359,11 +400,13 @@ STRING_Samaritan0 STRING_Saurashtra0 STRING_Sc0 + STRING_Sharada0 STRING_Shavian0 STRING_Sinhala0 STRING_Sk0 STRING_Sm0 STRING_So0 + STRING_Sora_Sompeng0 STRING_Sundanese0 STRING_Syloti_Nagri0 STRING_Syriac0 @@ -372,6 +415,7 @@ STRING_Tai_Le0 STRING_Tai_Tham0 STRING_Tai_Viet0 + STRING_Takri0 STRING_Tamil0 STRING_Telugu0 STRING_Thaana0 @@ -390,146 +434,156 @@ STRING_Zp0 STRING_Zs0; -const ucp_type_table _pcre_utt[] = { +const ucp_type_table PRIV(utt)[] = { { 0, PT_ANY, 0 }, { 4, PT_SC, ucp_Arabic }, { 11, PT_SC, ucp_Armenian }, { 20, PT_SC, ucp_Avestan }, { 28, PT_SC, ucp_Balinese }, { 37, PT_SC, ucp_Bamum }, - { 43, PT_SC, ucp_Bengali }, - { 51, PT_SC, ucp_Bopomofo }, - { 60, PT_SC, ucp_Braille }, - { 68, PT_SC, ucp_Buginese }, - { 77, PT_SC, ucp_Buhid }, - { 83, PT_GC, ucp_C }, - { 85, PT_SC, ucp_Canadian_Aboriginal }, - { 105, PT_SC, ucp_Carian }, - { 112, PT_PC, ucp_Cc }, - { 115, PT_PC, ucp_Cf }, - { 118, PT_SC, ucp_Cham }, - { 123, PT_SC, ucp_Cherokee }, - { 132, PT_PC, ucp_Cn }, - { 135, PT_PC, ucp_Co }, - { 138, PT_SC, ucp_Common }, - { 145, PT_SC, ucp_Coptic }, - { 152, PT_PC, ucp_Cs }, - { 155, PT_SC, ucp_Cuneiform }, - { 165, PT_SC, ucp_Cypriot }, - { 173, PT_SC, ucp_Cyrillic }, - { 182, PT_SC, ucp_Deseret }, - { 190, PT_SC, ucp_Devanagari }, - { 201, PT_SC, ucp_Egyptian_Hieroglyphs }, - { 222, PT_SC, ucp_Ethiopic }, - { 231, PT_SC, ucp_Georgian }, - { 240, PT_SC, ucp_Glagolitic }, - { 251, PT_SC, ucp_Gothic }, - { 258, PT_SC, ucp_Greek }, - { 264, PT_SC, ucp_Gujarati }, - { 273, PT_SC, ucp_Gurmukhi }, - { 282, PT_SC, ucp_Han }, - { 286, PT_SC, ucp_Hangul }, - { 293, PT_SC, ucp_Hanunoo }, - { 301, PT_SC, ucp_Hebrew }, - { 308, PT_SC, ucp_Hiragana }, - { 317, PT_SC, ucp_Imperial_Aramaic }, - { 334, PT_SC, ucp_Inherited }, - { 344, PT_SC, ucp_Inscriptional_Pahlavi }, - { 366, PT_SC, ucp_Inscriptional_Parthian }, - { 389, PT_SC, ucp_Javanese }, - { 398, PT_SC, ucp_Kaithi }, - { 405, PT_SC, ucp_Kannada }, - { 413, PT_SC, ucp_Katakana }, - { 422, PT_SC, ucp_Kayah_Li }, - { 431, PT_SC, ucp_Kharoshthi }, - { 442, PT_SC, ucp_Khmer }, - { 448, PT_GC, ucp_L }, - { 450, PT_LAMP, 0 }, - { 453, PT_SC, ucp_Lao }, - { 457, PT_SC, ucp_Latin }, - { 463, PT_SC, ucp_Lepcha }, - { 470, PT_SC, ucp_Limbu }, - { 476, PT_SC, ucp_Linear_B }, - { 485, PT_SC, ucp_Lisu }, - { 490, PT_PC, ucp_Ll }, - { 493, PT_PC, ucp_Lm }, - { 496, PT_PC, ucp_Lo }, - { 499, PT_PC, ucp_Lt }, - { 502, PT_PC, ucp_Lu }, - { 505, PT_SC, ucp_Lycian }, - { 512, PT_SC, ucp_Lydian }, - { 519, PT_GC, ucp_M }, - { 521, PT_SC, ucp_Malayalam }, - { 531, PT_PC, ucp_Mc }, - { 534, PT_PC, ucp_Me }, - { 537, PT_SC, ucp_Meetei_Mayek }, - { 550, PT_PC, ucp_Mn }, - { 553, PT_SC, ucp_Mongolian }, - { 563, PT_SC, ucp_Myanmar }, - { 571, PT_GC, ucp_N }, - { 573, PT_PC, ucp_Nd }, - { 576, PT_SC, ucp_New_Tai_Lue }, - { 588, PT_SC, ucp_Nko }, - { 592, PT_PC, ucp_Nl }, - { 595, PT_PC, ucp_No }, - { 598, PT_SC, ucp_Ogham }, - { 604, PT_SC, ucp_Ol_Chiki }, - { 613, PT_SC, ucp_Old_Italic }, - { 624, PT_SC, ucp_Old_Persian }, - { 636, PT_SC, ucp_Old_South_Arabian }, - { 654, PT_SC, ucp_Old_Turkic }, - { 665, PT_SC, ucp_Oriya }, - { 671, PT_SC, ucp_Osmanya }, - { 679, PT_GC, ucp_P }, - { 681, PT_PC, ucp_Pc }, - { 684, PT_PC, ucp_Pd }, - { 687, PT_PC, ucp_Pe }, - { 690, PT_PC, ucp_Pf }, - { 693, PT_SC, ucp_Phags_Pa }, - { 702, PT_SC, ucp_Phoenician }, - { 713, PT_PC, ucp_Pi }, - { 716, PT_PC, ucp_Po }, - { 719, PT_PC, ucp_Ps }, - { 722, PT_SC, ucp_Rejang }, - { 729, PT_SC, ucp_Runic }, - { 735, PT_GC, ucp_S }, - { 737, PT_SC, ucp_Samaritan }, - { 747, PT_SC, ucp_Saurashtra }, - { 758, PT_PC, ucp_Sc }, - { 761, PT_SC, ucp_Shavian }, - { 769, PT_SC, ucp_Sinhala }, - { 777, PT_PC, ucp_Sk }, - { 780, PT_PC, ucp_Sm }, - { 783, PT_PC, ucp_So }, - { 786, PT_SC, ucp_Sundanese }, - { 796, PT_SC, ucp_Syloti_Nagri }, - { 809, PT_SC, ucp_Syriac }, - { 816, PT_SC, ucp_Tagalog }, - { 824, PT_SC, ucp_Tagbanwa }, - { 833, PT_SC, ucp_Tai_Le }, - { 840, PT_SC, ucp_Tai_Tham }, - { 849, PT_SC, ucp_Tai_Viet }, - { 858, PT_SC, ucp_Tamil }, - { 864, PT_SC, ucp_Telugu }, - { 871, PT_SC, ucp_Thaana }, - { 878, PT_SC, ucp_Thai }, - { 883, PT_SC, ucp_Tibetan }, - { 891, PT_SC, ucp_Tifinagh }, - { 900, PT_SC, ucp_Ugaritic }, - { 909, PT_SC, ucp_Vai }, - { 913, PT_ALNUM, 0 }, - { 917, PT_PXSPACE, 0 }, - { 921, PT_SPACE, 0 }, - { 925, PT_WORD, 0 }, - { 929, PT_SC, ucp_Yi }, - { 932, PT_GC, ucp_Z }, - { 934, PT_PC, ucp_Zl }, - { 937, PT_PC, ucp_Zp }, - { 940, PT_PC, ucp_Zs } + { 43, PT_SC, ucp_Batak }, + { 49, PT_SC, ucp_Bengali }, + { 57, PT_SC, ucp_Bopomofo }, + { 66, PT_SC, ucp_Brahmi }, + { 73, PT_SC, ucp_Braille }, + { 81, PT_SC, ucp_Buginese }, + { 90, PT_SC, ucp_Buhid }, + { 96, PT_GC, ucp_C }, + { 98, PT_SC, ucp_Canadian_Aboriginal }, + { 118, PT_SC, ucp_Carian }, + { 125, PT_PC, ucp_Cc }, + { 128, PT_PC, ucp_Cf }, + { 131, PT_SC, ucp_Chakma }, + { 138, PT_SC, ucp_Cham }, + { 143, PT_SC, ucp_Cherokee }, + { 152, PT_PC, ucp_Cn }, + { 155, PT_PC, ucp_Co }, + { 158, PT_SC, ucp_Common }, + { 165, PT_SC, ucp_Coptic }, + { 172, PT_PC, ucp_Cs }, + { 175, PT_SC, ucp_Cuneiform }, + { 185, PT_SC, ucp_Cypriot }, + { 193, PT_SC, ucp_Cyrillic }, + { 202, PT_SC, ucp_Deseret }, + { 210, PT_SC, ucp_Devanagari }, + { 221, PT_SC, ucp_Egyptian_Hieroglyphs }, + { 242, PT_SC, ucp_Ethiopic }, + { 251, PT_SC, ucp_Georgian }, + { 260, PT_SC, ucp_Glagolitic }, + { 271, PT_SC, ucp_Gothic }, + { 278, PT_SC, ucp_Greek }, + { 284, PT_SC, ucp_Gujarati }, + { 293, PT_SC, ucp_Gurmukhi }, + { 302, PT_SC, ucp_Han }, + { 306, PT_SC, ucp_Hangul }, + { 313, PT_SC, ucp_Hanunoo }, + { 321, PT_SC, ucp_Hebrew }, + { 328, PT_SC, ucp_Hiragana }, + { 337, PT_SC, ucp_Imperial_Aramaic }, + { 354, PT_SC, ucp_Inherited }, + { 364, PT_SC, ucp_Inscriptional_Pahlavi }, + { 386, PT_SC, ucp_Inscriptional_Parthian }, + { 409, PT_SC, ucp_Javanese }, + { 418, PT_SC, ucp_Kaithi }, + { 425, PT_SC, ucp_Kannada }, + { 433, PT_SC, ucp_Katakana }, + { 442, PT_SC, ucp_Kayah_Li }, + { 451, PT_SC, ucp_Kharoshthi }, + { 462, PT_SC, ucp_Khmer }, + { 468, PT_GC, ucp_L }, + { 470, PT_LAMP, 0 }, + { 473, PT_SC, ucp_Lao }, + { 477, PT_SC, ucp_Latin }, + { 483, PT_SC, ucp_Lepcha }, + { 490, PT_SC, ucp_Limbu }, + { 496, PT_SC, ucp_Linear_B }, + { 505, PT_SC, ucp_Lisu }, + { 510, PT_PC, ucp_Ll }, + { 513, PT_PC, ucp_Lm }, + { 516, PT_PC, ucp_Lo }, + { 519, PT_PC, ucp_Lt }, + { 522, PT_PC, ucp_Lu }, + { 525, PT_SC, ucp_Lycian }, + { 532, PT_SC, ucp_Lydian }, + { 539, PT_GC, ucp_M }, + { 541, PT_SC, ucp_Malayalam }, + { 551, PT_SC, ucp_Mandaic }, + { 559, PT_PC, ucp_Mc }, + { 562, PT_PC, ucp_Me }, + { 565, PT_SC, ucp_Meetei_Mayek }, + { 578, PT_SC, ucp_Meroitic_Cursive }, + { 595, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 616, PT_SC, ucp_Miao }, + { 621, PT_PC, ucp_Mn }, + { 624, PT_SC, ucp_Mongolian }, + { 634, PT_SC, ucp_Myanmar }, + { 642, PT_GC, ucp_N }, + { 644, PT_PC, ucp_Nd }, + { 647, PT_SC, ucp_New_Tai_Lue }, + { 659, PT_SC, ucp_Nko }, + { 663, PT_PC, ucp_Nl }, + { 666, PT_PC, ucp_No }, + { 669, PT_SC, ucp_Ogham }, + { 675, PT_SC, ucp_Ol_Chiki }, + { 684, PT_SC, ucp_Old_Italic }, + { 695, PT_SC, ucp_Old_Persian }, + { 707, PT_SC, ucp_Old_South_Arabian }, + { 725, PT_SC, ucp_Old_Turkic }, + { 736, PT_SC, ucp_Oriya }, + { 742, PT_SC, ucp_Osmanya }, + { 750, PT_GC, ucp_P }, + { 752, PT_PC, ucp_Pc }, + { 755, PT_PC, ucp_Pd }, + { 758, PT_PC, ucp_Pe }, + { 761, PT_PC, ucp_Pf }, + { 764, PT_SC, ucp_Phags_Pa }, + { 773, PT_SC, ucp_Phoenician }, + { 784, PT_PC, ucp_Pi }, + { 787, PT_PC, ucp_Po }, + { 790, PT_PC, ucp_Ps }, + { 793, PT_SC, ucp_Rejang }, + { 800, PT_SC, ucp_Runic }, + { 806, PT_GC, ucp_S }, + { 808, PT_SC, ucp_Samaritan }, + { 818, PT_SC, ucp_Saurashtra }, + { 829, PT_PC, ucp_Sc }, + { 832, PT_SC, ucp_Sharada }, + { 840, PT_SC, ucp_Shavian }, + { 848, PT_SC, ucp_Sinhala }, + { 856, PT_PC, ucp_Sk }, + { 859, PT_PC, ucp_Sm }, + { 862, PT_PC, ucp_So }, + { 865, PT_SC, ucp_Sora_Sompeng }, + { 878, PT_SC, ucp_Sundanese }, + { 888, PT_SC, ucp_Syloti_Nagri }, + { 901, PT_SC, ucp_Syriac }, + { 908, PT_SC, ucp_Tagalog }, + { 916, PT_SC, ucp_Tagbanwa }, + { 925, PT_SC, ucp_Tai_Le }, + { 932, PT_SC, ucp_Tai_Tham }, + { 941, PT_SC, ucp_Tai_Viet }, + { 950, PT_SC, ucp_Takri }, + { 956, PT_SC, ucp_Tamil }, + { 962, PT_SC, ucp_Telugu }, + { 969, PT_SC, ucp_Thaana }, + { 976, PT_SC, ucp_Thai }, + { 981, PT_SC, ucp_Tibetan }, + { 989, PT_SC, ucp_Tifinagh }, + { 998, PT_SC, ucp_Ugaritic }, + { 1007, PT_SC, ucp_Vai }, + { 1011, PT_ALNUM, 0 }, + { 1015, PT_PXSPACE, 0 }, + { 1019, PT_SPACE, 0 }, + { 1023, PT_WORD, 0 }, + { 1027, PT_SC, ucp_Yi }, + { 1030, PT_GC, ucp_Z }, + { 1032, PT_PC, ucp_Zl }, + { 1035, PT_PC, ucp_Zp }, + { 1038, PT_PC, ucp_Zs } }; -const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table); +const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); -#endif /* SUPPORT_UTF8 */ +#endif /* SUPPORT_UTF */ /* End of pcre_tables.c */ diff -Nru pcre3-8.12/pcre_try_flipped.c pcre3-8.31/pcre_try_flipped.c --- pcre3-8.12/pcre_try_flipped.c 2009-10-05 10:40:30.000000000 +0000 +++ pcre3-8.31/pcre_try_flipped.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - - -/* This module contains an internal function that tests a compiled pattern to -see if it was compiled with the opposite endianness. If so, it uses an -auxiliary local function to flip the appropriate bytes. */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre_internal.h" - - -/************************************************* -* Flip bytes in an integer * -*************************************************/ - -/* This function is called when the magic number in a regex doesn't match, in -order to flip its bytes to see if we are dealing with a pattern that was -compiled on a host of different endianness. If so, this function is used to -flip other byte values. - -Arguments: - value the number to flip - n the number of bytes to flip (assumed to be 2 or 4) - -Returns: the flipped value -*/ - -static unsigned long int -byteflip(unsigned long int value, int n) -{ -if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); -return ((value & 0x000000ff) << 24) | - ((value & 0x0000ff00) << 8) | - ((value & 0x00ff0000) >> 8) | - ((value & 0xff000000) >> 24); -} - - - -/************************************************* -* Test for a byte-flipped compiled regex * -*************************************************/ - -/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from -pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that -is, it was compiled on a system of opposite endianness. The function is called -only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped, -we flip all the relevant values into a different data block, and return it. - -Arguments: - re points to the regex - study points to study data, or NULL - internal_re points to a new regex block - internal_study points to a new study block - -Returns: the new block if is is indeed a byte-flipped regex - NULL if it is not -*/ - -real_pcre * -_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re, - const pcre_study_data *study, pcre_study_data *internal_study) -{ -if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER) - return NULL; - -*internal_re = *re; /* To copy other fields */ -internal_re->size = byteflip(re->size, sizeof(re->size)); -internal_re->options = byteflip(re->options, sizeof(re->options)); -internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags)); -internal_re->top_bracket = - (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket)); -internal_re->top_backref = - (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref)); -internal_re->first_byte = - (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte)); -internal_re->req_byte = - (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte)); -internal_re->name_table_offset = - (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset)); -internal_re->name_entry_size = - (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size)); -internal_re->name_count = - (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count)); - -if (study != NULL) - { - *internal_study = *study; /* To copy other fields */ - internal_study->size = byteflip(study->size, sizeof(study->size)); - internal_study->flags = byteflip(study->flags, sizeof(study->flags)); - internal_study->minlength = byteflip(study->minlength, - sizeof(study->minlength)); - } - -return internal_re; -} - -/* End of pcre_tryflipped.c */ diff -Nru pcre3-8.12/pcre_ucd.c pcre3-8.31/pcre_ucd.c --- pcre3-8.12/pcre_ucd.c 2010-03-01 16:11:00.000000000 +0000 +++ pcre3-8.31/pcre_ucd.c 2012-02-28 14:31:31.000000000 +0000 @@ -6,7 +6,7 @@ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 56880 bytes, block size: 128. */ +/* Total size: 62904 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built */ /* into PCRE. This module should not be referenced otherwise, so */ @@ -18,21 +18,21 @@ /* Instead, just supply small dummy tables. */ #ifndef SUPPORT_UCP -const ucd_record _pcre_ucd_records[] = {{0,0,0 }}; -const uschar _pcre_ucd_stage1[] = {0}; -const pcre_uint16 _pcre_ucd_stage2[] = {0}; +const ucd_record PRIV(ucd_records)[] = {{0,0,0 }}; +const pcre_uint8 PRIV(ucd_stage1)[] = {0}; +const pcre_uint16 PRIV(ucd_stage2)[] = {0}; #else /* When recompiling tables with a new Unicode version, please check types in the structure definition from pcre_internal.h: typedef struct { -uschar property_0; -uschar property_1; +pcre_uint8 property_0; +pcre_uint8 property_1; pcre_int32 property_2; } ucd_record; */ -const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */ +const ucd_record PRIV(ucd_records)[] = { /* 4536 bytes, record size 8 */ { 9, 0, 0, }, /* 0 */ { 9, 29, 0, }, /* 1 */ { 9, 21, 0, }, /* 2 */ @@ -47,38 +47,38 @@ { 9, 16, 0, }, /* 11 */ { 33, 5, -32, }, /* 12 */ { 9, 26, 0, }, /* 13 */ - { 33, 5, 0, }, /* 14 */ + { 33, 7, 0, }, /* 14 */ { 9, 20, 0, }, /* 15 */ { 9, 1, 0, }, /* 16 */ { 9, 15, 0, }, /* 17 */ { 9, 5, 743, }, /* 18 */ { 9, 19, 0, }, /* 19 */ - { 33, 5, 121, }, /* 20 */ - { 33, 9, 1, }, /* 21 */ - { 33, 5, -1, }, /* 22 */ - { 33, 9, -199, }, /* 23 */ - { 33, 5, -232, }, /* 24 */ - { 33, 9, -121, }, /* 25 */ - { 33, 5, -300, }, /* 26 */ - { 33, 5, 195, }, /* 27 */ - { 33, 9, 210, }, /* 28 */ - { 33, 9, 206, }, /* 29 */ - { 33, 9, 205, }, /* 30 */ - { 33, 9, 79, }, /* 31 */ - { 33, 9, 202, }, /* 32 */ - { 33, 9, 203, }, /* 33 */ - { 33, 9, 207, }, /* 34 */ - { 33, 5, 97, }, /* 35 */ - { 33, 9, 211, }, /* 36 */ - { 33, 9, 209, }, /* 37 */ - { 33, 5, 163, }, /* 38 */ - { 33, 9, 213, }, /* 39 */ - { 33, 5, 130, }, /* 40 */ - { 33, 9, 214, }, /* 41 */ - { 33, 9, 218, }, /* 42 */ - { 33, 9, 217, }, /* 43 */ - { 33, 9, 219, }, /* 44 */ - { 33, 7, 0, }, /* 45 */ + { 33, 5, 0, }, /* 20 */ + { 33, 5, 121, }, /* 21 */ + { 33, 9, 1, }, /* 22 */ + { 33, 5, -1, }, /* 23 */ + { 33, 9, -199, }, /* 24 */ + { 33, 5, -232, }, /* 25 */ + { 33, 9, -121, }, /* 26 */ + { 33, 5, -300, }, /* 27 */ + { 33, 5, 195, }, /* 28 */ + { 33, 9, 210, }, /* 29 */ + { 33, 9, 206, }, /* 30 */ + { 33, 9, 205, }, /* 31 */ + { 33, 9, 79, }, /* 32 */ + { 33, 9, 202, }, /* 33 */ + { 33, 9, 203, }, /* 34 */ + { 33, 9, 207, }, /* 35 */ + { 33, 5, 97, }, /* 36 */ + { 33, 9, 211, }, /* 37 */ + { 33, 9, 209, }, /* 38 */ + { 33, 5, 163, }, /* 39 */ + { 33, 9, 213, }, /* 40 */ + { 33, 5, 130, }, /* 41 */ + { 33, 9, 214, }, /* 42 */ + { 33, 9, 218, }, /* 43 */ + { 33, 9, 217, }, /* 44 */ + { 33, 9, 219, }, /* 45 */ { 33, 5, 56, }, /* 46 */ { 33, 9, 2, }, /* 47 */ { 33, 8, -1, }, /* 48 */ @@ -103,463 +103,512 @@ { 33, 5, -202, }, /* 67 */ { 33, 5, -203, }, /* 68 */ { 33, 5, -207, }, /* 69 */ - { 33, 5, -209, }, /* 70 */ - { 33, 5, -211, }, /* 71 */ - { 33, 5, 10743, }, /* 72 */ - { 33, 5, 10749, }, /* 73 */ - { 33, 5, -213, }, /* 74 */ - { 33, 5, -214, }, /* 75 */ - { 33, 5, 10727, }, /* 76 */ - { 33, 5, -218, }, /* 77 */ - { 33, 5, -69, }, /* 78 */ - { 33, 5, -217, }, /* 79 */ - { 33, 5, -71, }, /* 80 */ - { 33, 5, -219, }, /* 81 */ - { 33, 6, 0, }, /* 82 */ - { 9, 6, 0, }, /* 83 */ - { 27, 12, 0, }, /* 84 */ - { 27, 12, 84, }, /* 85 */ - { 19, 9, 1, }, /* 86 */ - { 19, 5, -1, }, /* 87 */ - { 19, 24, 0, }, /* 88 */ - { 9, 2, 0, }, /* 89 */ - { 19, 6, 0, }, /* 90 */ - { 19, 5, 130, }, /* 91 */ - { 19, 9, 38, }, /* 92 */ - { 19, 9, 37, }, /* 93 */ - { 19, 9, 64, }, /* 94 */ - { 19, 9, 63, }, /* 95 */ - { 19, 5, 0, }, /* 96 */ - { 19, 9, 32, }, /* 97 */ - { 19, 5, -38, }, /* 98 */ - { 19, 5, -37, }, /* 99 */ - { 19, 5, -32, }, /* 100 */ - { 19, 5, -31, }, /* 101 */ - { 19, 5, -64, }, /* 102 */ - { 19, 5, -63, }, /* 103 */ - { 19, 9, 8, }, /* 104 */ - { 19, 5, -62, }, /* 105 */ - { 19, 5, -57, }, /* 106 */ - { 19, 9, 0, }, /* 107 */ - { 19, 5, -47, }, /* 108 */ - { 19, 5, -54, }, /* 109 */ - { 19, 5, -8, }, /* 110 */ - { 10, 9, 1, }, /* 111 */ - { 10, 5, -1, }, /* 112 */ - { 19, 5, -86, }, /* 113 */ - { 19, 5, -80, }, /* 114 */ - { 19, 5, 7, }, /* 115 */ - { 19, 9, -60, }, /* 116 */ - { 19, 5, -96, }, /* 117 */ - { 19, 25, 0, }, /* 118 */ - { 19, 9, -7, }, /* 119 */ - { 19, 9, -130, }, /* 120 */ - { 12, 9, 80, }, /* 121 */ - { 12, 9, 32, }, /* 122 */ - { 12, 5, -32, }, /* 123 */ - { 12, 5, -80, }, /* 124 */ - { 12, 9, 1, }, /* 125 */ - { 12, 5, -1, }, /* 126 */ - { 12, 26, 0, }, /* 127 */ - { 12, 12, 0, }, /* 128 */ - { 12, 11, 0, }, /* 129 */ - { 12, 9, 15, }, /* 130 */ - { 12, 5, -15, }, /* 131 */ - { 1, 9, 48, }, /* 132 */ - { 1, 6, 0, }, /* 133 */ - { 1, 21, 0, }, /* 134 */ - { 1, 5, -48, }, /* 135 */ - { 1, 5, 0, }, /* 136 */ - { 1, 17, 0, }, /* 137 */ - { 25, 12, 0, }, /* 138 */ - { 25, 17, 0, }, /* 139 */ - { 25, 21, 0, }, /* 140 */ - { 25, 7, 0, }, /* 141 */ - { 0, 25, 0, }, /* 142 */ - { 0, 21, 0, }, /* 143 */ - { 0, 23, 0, }, /* 144 */ - { 0, 26, 0, }, /* 145 */ - { 0, 12, 0, }, /* 146 */ - { 0, 7, 0, }, /* 147 */ - { 0, 11, 0, }, /* 148 */ - { 0, 6, 0, }, /* 149 */ - { 0, 13, 0, }, /* 150 */ - { 49, 21, 0, }, /* 151 */ - { 49, 1, 0, }, /* 152 */ - { 49, 7, 0, }, /* 153 */ - { 49, 12, 0, }, /* 154 */ - { 55, 7, 0, }, /* 155 */ - { 55, 12, 0, }, /* 156 */ - { 63, 13, 0, }, /* 157 */ - { 63, 7, 0, }, /* 158 */ - { 63, 12, 0, }, /* 159 */ - { 63, 6, 0, }, /* 160 */ - { 63, 26, 0, }, /* 161 */ - { 63, 21, 0, }, /* 162 */ - { 89, 7, 0, }, /* 163 */ - { 89, 12, 0, }, /* 164 */ - { 89, 6, 0, }, /* 165 */ - { 89, 21, 0, }, /* 166 */ - { 14, 12, 0, }, /* 167 */ - { 14, 10, 0, }, /* 168 */ - { 14, 7, 0, }, /* 169 */ - { 14, 13, 0, }, /* 170 */ - { 14, 6, 0, }, /* 171 */ - { 2, 12, 0, }, /* 172 */ - { 2, 10, 0, }, /* 173 */ - { 2, 7, 0, }, /* 174 */ - { 2, 13, 0, }, /* 175 */ - { 2, 23, 0, }, /* 176 */ - { 2, 15, 0, }, /* 177 */ - { 2, 26, 0, }, /* 178 */ - { 21, 12, 0, }, /* 179 */ - { 21, 10, 0, }, /* 180 */ - { 21, 7, 0, }, /* 181 */ - { 21, 13, 0, }, /* 182 */ - { 20, 12, 0, }, /* 183 */ - { 20, 10, 0, }, /* 184 */ - { 20, 7, 0, }, /* 185 */ - { 20, 13, 0, }, /* 186 */ - { 20, 23, 0, }, /* 187 */ - { 43, 12, 0, }, /* 188 */ - { 43, 10, 0, }, /* 189 */ - { 43, 7, 0, }, /* 190 */ - { 43, 13, 0, }, /* 191 */ - { 43, 26, 0, }, /* 192 */ - { 53, 12, 0, }, /* 193 */ - { 53, 7, 0, }, /* 194 */ - { 53, 10, 0, }, /* 195 */ - { 53, 13, 0, }, /* 196 */ - { 53, 15, 0, }, /* 197 */ - { 53, 26, 0, }, /* 198 */ - { 53, 23, 0, }, /* 199 */ - { 54, 10, 0, }, /* 200 */ - { 54, 7, 0, }, /* 201 */ - { 54, 12, 0, }, /* 202 */ - { 54, 13, 0, }, /* 203 */ - { 54, 15, 0, }, /* 204 */ - { 54, 26, 0, }, /* 205 */ - { 28, 10, 0, }, /* 206 */ - { 28, 7, 0, }, /* 207 */ - { 28, 12, 0, }, /* 208 */ - { 28, 13, 0, }, /* 209 */ - { 36, 10, 0, }, /* 210 */ - { 36, 7, 0, }, /* 211 */ - { 36, 12, 0, }, /* 212 */ - { 36, 13, 0, }, /* 213 */ - { 36, 15, 0, }, /* 214 */ - { 36, 26, 0, }, /* 215 */ - { 47, 10, 0, }, /* 216 */ - { 47, 7, 0, }, /* 217 */ - { 47, 12, 0, }, /* 218 */ - { 47, 21, 0, }, /* 219 */ - { 56, 7, 0, }, /* 220 */ - { 56, 12, 0, }, /* 221 */ - { 56, 6, 0, }, /* 222 */ - { 56, 21, 0, }, /* 223 */ - { 56, 13, 0, }, /* 224 */ - { 32, 7, 0, }, /* 225 */ - { 32, 12, 0, }, /* 226 */ - { 32, 6, 0, }, /* 227 */ - { 32, 13, 0, }, /* 228 */ - { 57, 7, 0, }, /* 229 */ - { 57, 26, 0, }, /* 230 */ - { 57, 21, 0, }, /* 231 */ - { 57, 12, 0, }, /* 232 */ - { 57, 13, 0, }, /* 233 */ - { 57, 15, 0, }, /* 234 */ - { 57, 22, 0, }, /* 235 */ - { 57, 18, 0, }, /* 236 */ - { 57, 10, 0, }, /* 237 */ - { 38, 7, 0, }, /* 238 */ - { 38, 10, 0, }, /* 239 */ - { 38, 12, 0, }, /* 240 */ - { 38, 13, 0, }, /* 241 */ - { 38, 21, 0, }, /* 242 */ - { 38, 26, 0, }, /* 243 */ - { 16, 9, 7264, }, /* 244 */ - { 16, 7, 0, }, /* 245 */ - { 16, 6, 0, }, /* 246 */ - { 23, 7, 0, }, /* 247 */ - { 15, 7, 0, }, /* 248 */ - { 15, 12, 0, }, /* 249 */ - { 15, 26, 0, }, /* 250 */ - { 15, 21, 0, }, /* 251 */ - { 15, 15, 0, }, /* 252 */ - { 8, 7, 0, }, /* 253 */ - { 7, 17, 0, }, /* 254 */ - { 7, 7, 0, }, /* 255 */ - { 7, 21, 0, }, /* 256 */ - { 40, 29, 0, }, /* 257 */ - { 40, 7, 0, }, /* 258 */ - { 40, 22, 0, }, /* 259 */ - { 40, 18, 0, }, /* 260 */ - { 45, 7, 0, }, /* 261 */ - { 45, 14, 0, }, /* 262 */ - { 50, 7, 0, }, /* 263 */ - { 50, 12, 0, }, /* 264 */ - { 24, 7, 0, }, /* 265 */ - { 24, 12, 0, }, /* 266 */ - { 6, 7, 0, }, /* 267 */ - { 6, 12, 0, }, /* 268 */ - { 51, 7, 0, }, /* 269 */ - { 51, 12, 0, }, /* 270 */ - { 31, 7, 0, }, /* 271 */ - { 31, 1, 0, }, /* 272 */ - { 31, 10, 0, }, /* 273 */ - { 31, 12, 0, }, /* 274 */ - { 31, 21, 0, }, /* 275 */ - { 31, 6, 0, }, /* 276 */ - { 31, 23, 0, }, /* 277 */ - { 31, 13, 0, }, /* 278 */ - { 31, 15, 0, }, /* 279 */ - { 37, 21, 0, }, /* 280 */ - { 37, 17, 0, }, /* 281 */ - { 37, 12, 0, }, /* 282 */ - { 37, 29, 0, }, /* 283 */ - { 37, 13, 0, }, /* 284 */ - { 37, 7, 0, }, /* 285 */ - { 37, 6, 0, }, /* 286 */ - { 34, 7, 0, }, /* 287 */ - { 34, 12, 0, }, /* 288 */ - { 34, 10, 0, }, /* 289 */ - { 34, 26, 0, }, /* 290 */ - { 34, 21, 0, }, /* 291 */ - { 34, 13, 0, }, /* 292 */ - { 52, 7, 0, }, /* 293 */ - { 39, 7, 0, }, /* 294 */ - { 39, 10, 0, }, /* 295 */ - { 39, 13, 0, }, /* 296 */ - { 39, 21, 0, }, /* 297 */ - { 31, 26, 0, }, /* 298 */ - { 5, 7, 0, }, /* 299 */ - { 5, 12, 0, }, /* 300 */ - { 5, 10, 0, }, /* 301 */ - { 5, 21, 0, }, /* 302 */ - { 90, 7, 0, }, /* 303 */ - { 90, 10, 0, }, /* 304 */ - { 90, 12, 0, }, /* 305 */ - { 90, 13, 0, }, /* 306 */ - { 90, 21, 0, }, /* 307 */ - { 90, 6, 0, }, /* 308 */ - { 61, 12, 0, }, /* 309 */ - { 61, 10, 0, }, /* 310 */ - { 61, 7, 0, }, /* 311 */ - { 61, 13, 0, }, /* 312 */ - { 61, 21, 0, }, /* 313 */ - { 61, 26, 0, }, /* 314 */ - { 75, 12, 0, }, /* 315 */ - { 75, 10, 0, }, /* 316 */ - { 75, 7, 0, }, /* 317 */ - { 75, 13, 0, }, /* 318 */ - { 69, 7, 0, }, /* 319 */ - { 69, 10, 0, }, /* 320 */ - { 69, 12, 0, }, /* 321 */ - { 69, 21, 0, }, /* 322 */ - { 69, 13, 0, }, /* 323 */ - { 72, 13, 0, }, /* 324 */ - { 72, 7, 0, }, /* 325 */ - { 72, 6, 0, }, /* 326 */ - { 72, 21, 0, }, /* 327 */ - { 9, 10, 0, }, /* 328 */ - { 9, 7, 0, }, /* 329 */ - { 12, 5, 0, }, /* 330 */ - { 12, 6, 0, }, /* 331 */ - { 33, 5, 35332, }, /* 332 */ - { 33, 5, 3814, }, /* 333 */ - { 33, 5, -59, }, /* 334 */ - { 33, 9, -7615, }, /* 335 */ - { 19, 5, 8, }, /* 336 */ - { 19, 9, -8, }, /* 337 */ - { 19, 5, 74, }, /* 338 */ - { 19, 5, 86, }, /* 339 */ - { 19, 5, 100, }, /* 340 */ - { 19, 5, 128, }, /* 341 */ - { 19, 5, 112, }, /* 342 */ - { 19, 5, 126, }, /* 343 */ - { 19, 8, -8, }, /* 344 */ - { 19, 5, 9, }, /* 345 */ - { 19, 9, -74, }, /* 346 */ - { 19, 8, -9, }, /* 347 */ - { 19, 5, -7205, }, /* 348 */ - { 19, 9, -86, }, /* 349 */ - { 19, 9, -100, }, /* 350 */ - { 19, 9, -112, }, /* 351 */ - { 19, 9, -128, }, /* 352 */ - { 19, 9, -126, }, /* 353 */ - { 27, 1, 0, }, /* 354 */ - { 9, 27, 0, }, /* 355 */ - { 9, 28, 0, }, /* 356 */ - { 27, 11, 0, }, /* 357 */ - { 9, 9, 0, }, /* 358 */ - { 9, 5, 0, }, /* 359 */ - { 19, 9, -7517, }, /* 360 */ - { 33, 9, -8383, }, /* 361 */ - { 33, 9, -8262, }, /* 362 */ - { 33, 9, 28, }, /* 363 */ - { 33, 5, -28, }, /* 364 */ - { 33, 14, 16, }, /* 365 */ - { 33, 14, -16, }, /* 366 */ - { 33, 14, 0, }, /* 367 */ - { 9, 26, 26, }, /* 368 */ - { 9, 26, -26, }, /* 369 */ - { 4, 26, 0, }, /* 370 */ - { 17, 9, 48, }, /* 371 */ - { 17, 5, -48, }, /* 372 */ - { 33, 9, -10743, }, /* 373 */ - { 33, 9, -3814, }, /* 374 */ - { 33, 9, -10727, }, /* 375 */ - { 33, 5, -10795, }, /* 376 */ - { 33, 5, -10792, }, /* 377 */ - { 33, 9, -10780, }, /* 378 */ - { 33, 9, -10749, }, /* 379 */ - { 33, 9, -10783, }, /* 380 */ - { 33, 9, -10782, }, /* 381 */ - { 33, 9, -10815, }, /* 382 */ - { 10, 5, 0, }, /* 383 */ - { 10, 26, 0, }, /* 384 */ - { 10, 12, 0, }, /* 385 */ - { 10, 21, 0, }, /* 386 */ - { 10, 15, 0, }, /* 387 */ - { 16, 5, -7264, }, /* 388 */ - { 58, 7, 0, }, /* 389 */ - { 58, 6, 0, }, /* 390 */ - { 22, 26, 0, }, /* 391 */ - { 22, 6, 0, }, /* 392 */ - { 22, 14, 0, }, /* 393 */ - { 26, 7, 0, }, /* 394 */ - { 26, 6, 0, }, /* 395 */ - { 29, 7, 0, }, /* 396 */ - { 29, 6, 0, }, /* 397 */ - { 3, 7, 0, }, /* 398 */ - { 23, 26, 0, }, /* 399 */ - { 29, 26, 0, }, /* 400 */ - { 22, 7, 0, }, /* 401 */ - { 60, 7, 0, }, /* 402 */ - { 60, 6, 0, }, /* 403 */ - { 60, 26, 0, }, /* 404 */ - { 85, 7, 0, }, /* 405 */ - { 85, 6, 0, }, /* 406 */ - { 85, 21, 0, }, /* 407 */ - { 76, 7, 0, }, /* 408 */ - { 76, 6, 0, }, /* 409 */ - { 76, 21, 0, }, /* 410 */ - { 76, 13, 0, }, /* 411 */ - { 12, 7, 0, }, /* 412 */ - { 12, 21, 0, }, /* 413 */ - { 78, 7, 0, }, /* 414 */ - { 78, 14, 0, }, /* 415 */ - { 78, 12, 0, }, /* 416 */ - { 78, 21, 0, }, /* 417 */ - { 33, 9, -35332, }, /* 418 */ - { 48, 7, 0, }, /* 419 */ - { 48, 12, 0, }, /* 420 */ - { 48, 10, 0, }, /* 421 */ - { 48, 26, 0, }, /* 422 */ - { 64, 7, 0, }, /* 423 */ - { 64, 21, 0, }, /* 424 */ - { 74, 10, 0, }, /* 425 */ - { 74, 7, 0, }, /* 426 */ - { 74, 12, 0, }, /* 427 */ - { 74, 21, 0, }, /* 428 */ - { 74, 13, 0, }, /* 429 */ - { 14, 21, 0, }, /* 430 */ - { 68, 13, 0, }, /* 431 */ - { 68, 7, 0, }, /* 432 */ - { 68, 12, 0, }, /* 433 */ - { 68, 21, 0, }, /* 434 */ - { 73, 7, 0, }, /* 435 */ - { 73, 12, 0, }, /* 436 */ - { 73, 10, 0, }, /* 437 */ - { 73, 21, 0, }, /* 438 */ - { 83, 12, 0, }, /* 439 */ - { 83, 10, 0, }, /* 440 */ - { 83, 7, 0, }, /* 441 */ - { 83, 21, 0, }, /* 442 */ - { 83, 6, 0, }, /* 443 */ - { 83, 13, 0, }, /* 444 */ - { 67, 7, 0, }, /* 445 */ - { 67, 12, 0, }, /* 446 */ - { 67, 10, 0, }, /* 447 */ - { 67, 13, 0, }, /* 448 */ - { 67, 21, 0, }, /* 449 */ - { 38, 6, 0, }, /* 450 */ - { 91, 7, 0, }, /* 451 */ - { 91, 12, 0, }, /* 452 */ - { 91, 6, 0, }, /* 453 */ - { 91, 21, 0, }, /* 454 */ - { 86, 7, 0, }, /* 455 */ - { 86, 10, 0, }, /* 456 */ - { 86, 12, 0, }, /* 457 */ - { 86, 21, 0, }, /* 458 */ - { 86, 13, 0, }, /* 459 */ - { 9, 4, 0, }, /* 460 */ - { 9, 3, 0, }, /* 461 */ - { 25, 25, 0, }, /* 462 */ - { 35, 7, 0, }, /* 463 */ - { 19, 14, 0, }, /* 464 */ - { 19, 15, 0, }, /* 465 */ - { 19, 26, 0, }, /* 466 */ - { 70, 7, 0, }, /* 467 */ - { 66, 7, 0, }, /* 468 */ - { 41, 7, 0, }, /* 469 */ - { 41, 15, 0, }, /* 470 */ - { 18, 7, 0, }, /* 471 */ - { 18, 14, 0, }, /* 472 */ - { 59, 7, 0, }, /* 473 */ - { 59, 21, 0, }, /* 474 */ - { 42, 7, 0, }, /* 475 */ - { 42, 21, 0, }, /* 476 */ - { 42, 14, 0, }, /* 477 */ - { 13, 9, 40, }, /* 478 */ - { 13, 5, -40, }, /* 479 */ - { 46, 7, 0, }, /* 480 */ - { 44, 7, 0, }, /* 481 */ - { 44, 13, 0, }, /* 482 */ - { 11, 7, 0, }, /* 483 */ - { 80, 7, 0, }, /* 484 */ - { 80, 21, 0, }, /* 485 */ - { 80, 15, 0, }, /* 486 */ - { 65, 7, 0, }, /* 487 */ - { 65, 15, 0, }, /* 488 */ - { 65, 21, 0, }, /* 489 */ - { 71, 7, 0, }, /* 490 */ - { 71, 21, 0, }, /* 491 */ - { 30, 7, 0, }, /* 492 */ - { 30, 12, 0, }, /* 493 */ - { 30, 15, 0, }, /* 494 */ - { 30, 21, 0, }, /* 495 */ - { 87, 7, 0, }, /* 496 */ - { 87, 15, 0, }, /* 497 */ - { 87, 21, 0, }, /* 498 */ - { 77, 7, 0, }, /* 499 */ - { 77, 21, 0, }, /* 500 */ - { 82, 7, 0, }, /* 501 */ - { 82, 15, 0, }, /* 502 */ - { 81, 7, 0, }, /* 503 */ - { 81, 15, 0, }, /* 504 */ - { 88, 7, 0, }, /* 505 */ - { 0, 15, 0, }, /* 506 */ - { 84, 12, 0, }, /* 507 */ - { 84, 10, 0, }, /* 508 */ - { 84, 7, 0, }, /* 509 */ - { 84, 21, 0, }, /* 510 */ - { 84, 1, 0, }, /* 511 */ - { 62, 7, 0, }, /* 512 */ - { 62, 14, 0, }, /* 513 */ - { 62, 21, 0, }, /* 514 */ - { 79, 7, 0, }, /* 515 */ - { 19, 12, 0, }, /* 516 */ - { 26, 26, 0, }, /* 517 */ + { 33, 5, 42280, }, /* 70 */ + { 33, 5, 42308, }, /* 71 */ + { 33, 5, -209, }, /* 72 */ + { 33, 5, -211, }, /* 73 */ + { 33, 5, 10743, }, /* 74 */ + { 33, 5, 10749, }, /* 75 */ + { 33, 5, -213, }, /* 76 */ + { 33, 5, -214, }, /* 77 */ + { 33, 5, 10727, }, /* 78 */ + { 33, 5, -218, }, /* 79 */ + { 33, 5, -69, }, /* 80 */ + { 33, 5, -217, }, /* 81 */ + { 33, 5, -71, }, /* 82 */ + { 33, 5, -219, }, /* 83 */ + { 33, 6, 0, }, /* 84 */ + { 9, 6, 0, }, /* 85 */ + { 3, 24, 0, }, /* 86 */ + { 27, 12, 0, }, /* 87 */ + { 27, 12, 84, }, /* 88 */ + { 19, 9, 1, }, /* 89 */ + { 19, 5, -1, }, /* 90 */ + { 19, 24, 0, }, /* 91 */ + { 9, 2, 0, }, /* 92 */ + { 19, 6, 0, }, /* 93 */ + { 19, 5, 130, }, /* 94 */ + { 19, 9, 38, }, /* 95 */ + { 19, 9, 37, }, /* 96 */ + { 19, 9, 64, }, /* 97 */ + { 19, 9, 63, }, /* 98 */ + { 19, 5, 0, }, /* 99 */ + { 19, 9, 32, }, /* 100 */ + { 19, 5, -38, }, /* 101 */ + { 19, 5, -37, }, /* 102 */ + { 19, 5, -32, }, /* 103 */ + { 19, 5, -31, }, /* 104 */ + { 19, 5, -64, }, /* 105 */ + { 19, 5, -63, }, /* 106 */ + { 19, 9, 8, }, /* 107 */ + { 19, 5, -62, }, /* 108 */ + { 19, 5, -57, }, /* 109 */ + { 19, 9, 0, }, /* 110 */ + { 19, 5, -47, }, /* 111 */ + { 19, 5, -54, }, /* 112 */ + { 19, 5, -8, }, /* 113 */ + { 10, 9, 1, }, /* 114 */ + { 10, 5, -1, }, /* 115 */ + { 19, 5, -86, }, /* 116 */ + { 19, 5, -80, }, /* 117 */ + { 19, 5, 7, }, /* 118 */ + { 19, 9, -60, }, /* 119 */ + { 19, 5, -96, }, /* 120 */ + { 19, 25, 0, }, /* 121 */ + { 19, 9, -7, }, /* 122 */ + { 19, 9, -130, }, /* 123 */ + { 12, 9, 80, }, /* 124 */ + { 12, 9, 32, }, /* 125 */ + { 12, 5, -32, }, /* 126 */ + { 12, 5, -80, }, /* 127 */ + { 12, 9, 1, }, /* 128 */ + { 12, 5, -1, }, /* 129 */ + { 12, 26, 0, }, /* 130 */ + { 12, 12, 0, }, /* 131 */ + { 12, 11, 0, }, /* 132 */ + { 12, 9, 15, }, /* 133 */ + { 12, 5, -15, }, /* 134 */ + { 1, 9, 48, }, /* 135 */ + { 1, 6, 0, }, /* 136 */ + { 1, 21, 0, }, /* 137 */ + { 1, 5, -48, }, /* 138 */ + { 1, 5, 0, }, /* 139 */ + { 1, 17, 0, }, /* 140 */ + { 1, 23, 0, }, /* 141 */ + { 25, 12, 0, }, /* 142 */ + { 25, 17, 0, }, /* 143 */ + { 25, 21, 0, }, /* 144 */ + { 25, 7, 0, }, /* 145 */ + { 0, 1, 0, }, /* 146 */ + { 0, 25, 0, }, /* 147 */ + { 0, 21, 0, }, /* 148 */ + { 0, 23, 0, }, /* 149 */ + { 0, 26, 0, }, /* 150 */ + { 0, 12, 0, }, /* 151 */ + { 0, 7, 0, }, /* 152 */ + { 0, 6, 0, }, /* 153 */ + { 0, 13, 0, }, /* 154 */ + { 49, 21, 0, }, /* 155 */ + { 49, 1, 0, }, /* 156 */ + { 49, 7, 0, }, /* 157 */ + { 49, 12, 0, }, /* 158 */ + { 55, 7, 0, }, /* 159 */ + { 55, 12, 0, }, /* 160 */ + { 63, 13, 0, }, /* 161 */ + { 63, 7, 0, }, /* 162 */ + { 63, 12, 0, }, /* 163 */ + { 63, 6, 0, }, /* 164 */ + { 63, 26, 0, }, /* 165 */ + { 63, 21, 0, }, /* 166 */ + { 89, 7, 0, }, /* 167 */ + { 89, 12, 0, }, /* 168 */ + { 89, 6, 0, }, /* 169 */ + { 89, 21, 0, }, /* 170 */ + { 94, 7, 0, }, /* 171 */ + { 94, 12, 0, }, /* 172 */ + { 94, 21, 0, }, /* 173 */ + { 14, 12, 0, }, /* 174 */ + { 14, 10, 0, }, /* 175 */ + { 14, 7, 0, }, /* 176 */ + { 14, 13, 0, }, /* 177 */ + { 14, 21, 0, }, /* 178 */ + { 14, 6, 0, }, /* 179 */ + { 2, 12, 0, }, /* 180 */ + { 2, 10, 0, }, /* 181 */ + { 2, 7, 0, }, /* 182 */ + { 2, 13, 0, }, /* 183 */ + { 2, 23, 0, }, /* 184 */ + { 2, 15, 0, }, /* 185 */ + { 2, 26, 0, }, /* 186 */ + { 21, 12, 0, }, /* 187 */ + { 21, 10, 0, }, /* 188 */ + { 21, 7, 0, }, /* 189 */ + { 21, 13, 0, }, /* 190 */ + { 20, 12, 0, }, /* 191 */ + { 20, 10, 0, }, /* 192 */ + { 20, 7, 0, }, /* 193 */ + { 20, 13, 0, }, /* 194 */ + { 20, 21, 0, }, /* 195 */ + { 20, 23, 0, }, /* 196 */ + { 43, 12, 0, }, /* 197 */ + { 43, 10, 0, }, /* 198 */ + { 43, 7, 0, }, /* 199 */ + { 43, 13, 0, }, /* 200 */ + { 43, 26, 0, }, /* 201 */ + { 43, 15, 0, }, /* 202 */ + { 53, 12, 0, }, /* 203 */ + { 53, 7, 0, }, /* 204 */ + { 53, 10, 0, }, /* 205 */ + { 53, 13, 0, }, /* 206 */ + { 53, 15, 0, }, /* 207 */ + { 53, 26, 0, }, /* 208 */ + { 53, 23, 0, }, /* 209 */ + { 54, 10, 0, }, /* 210 */ + { 54, 7, 0, }, /* 211 */ + { 54, 12, 0, }, /* 212 */ + { 54, 13, 0, }, /* 213 */ + { 54, 15, 0, }, /* 214 */ + { 54, 26, 0, }, /* 215 */ + { 28, 10, 0, }, /* 216 */ + { 28, 7, 0, }, /* 217 */ + { 28, 12, 0, }, /* 218 */ + { 28, 13, 0, }, /* 219 */ + { 36, 10, 0, }, /* 220 */ + { 36, 7, 0, }, /* 221 */ + { 36, 12, 0, }, /* 222 */ + { 36, 13, 0, }, /* 223 */ + { 36, 15, 0, }, /* 224 */ + { 36, 26, 0, }, /* 225 */ + { 47, 10, 0, }, /* 226 */ + { 47, 7, 0, }, /* 227 */ + { 47, 12, 0, }, /* 228 */ + { 47, 21, 0, }, /* 229 */ + { 56, 7, 0, }, /* 230 */ + { 56, 12, 0, }, /* 231 */ + { 56, 6, 0, }, /* 232 */ + { 56, 21, 0, }, /* 233 */ + { 56, 13, 0, }, /* 234 */ + { 32, 7, 0, }, /* 235 */ + { 32, 12, 0, }, /* 236 */ + { 32, 6, 0, }, /* 237 */ + { 32, 13, 0, }, /* 238 */ + { 57, 7, 0, }, /* 239 */ + { 57, 26, 0, }, /* 240 */ + { 57, 21, 0, }, /* 241 */ + { 57, 12, 0, }, /* 242 */ + { 57, 13, 0, }, /* 243 */ + { 57, 15, 0, }, /* 244 */ + { 57, 22, 0, }, /* 245 */ + { 57, 18, 0, }, /* 246 */ + { 57, 10, 0, }, /* 247 */ + { 38, 7, 0, }, /* 248 */ + { 38, 10, 0, }, /* 249 */ + { 38, 12, 0, }, /* 250 */ + { 38, 13, 0, }, /* 251 */ + { 38, 21, 0, }, /* 252 */ + { 38, 26, 0, }, /* 253 */ + { 16, 9, 7264, }, /* 254 */ + { 16, 7, 0, }, /* 255 */ + { 16, 6, 0, }, /* 256 */ + { 23, 7, 0, }, /* 257 */ + { 15, 7, 0, }, /* 258 */ + { 15, 12, 0, }, /* 259 */ + { 15, 21, 0, }, /* 260 */ + { 15, 15, 0, }, /* 261 */ + { 15, 26, 0, }, /* 262 */ + { 8, 7, 0, }, /* 263 */ + { 7, 17, 0, }, /* 264 */ + { 7, 7, 0, }, /* 265 */ + { 7, 21, 0, }, /* 266 */ + { 40, 29, 0, }, /* 267 */ + { 40, 7, 0, }, /* 268 */ + { 40, 22, 0, }, /* 269 */ + { 40, 18, 0, }, /* 270 */ + { 45, 7, 0, }, /* 271 */ + { 45, 14, 0, }, /* 272 */ + { 50, 7, 0, }, /* 273 */ + { 50, 12, 0, }, /* 274 */ + { 24, 7, 0, }, /* 275 */ + { 24, 12, 0, }, /* 276 */ + { 6, 7, 0, }, /* 277 */ + { 6, 12, 0, }, /* 278 */ + { 51, 7, 0, }, /* 279 */ + { 51, 12, 0, }, /* 280 */ + { 31, 7, 0, }, /* 281 */ + { 31, 12, 0, }, /* 282 */ + { 31, 10, 0, }, /* 283 */ + { 31, 21, 0, }, /* 284 */ + { 31, 6, 0, }, /* 285 */ + { 31, 23, 0, }, /* 286 */ + { 31, 13, 0, }, /* 287 */ + { 31, 15, 0, }, /* 288 */ + { 37, 21, 0, }, /* 289 */ + { 37, 17, 0, }, /* 290 */ + { 37, 12, 0, }, /* 291 */ + { 37, 29, 0, }, /* 292 */ + { 37, 13, 0, }, /* 293 */ + { 37, 7, 0, }, /* 294 */ + { 37, 6, 0, }, /* 295 */ + { 34, 7, 0, }, /* 296 */ + { 34, 12, 0, }, /* 297 */ + { 34, 10, 0, }, /* 298 */ + { 34, 26, 0, }, /* 299 */ + { 34, 21, 0, }, /* 300 */ + { 34, 13, 0, }, /* 301 */ + { 52, 7, 0, }, /* 302 */ + { 39, 7, 0, }, /* 303 */ + { 39, 10, 0, }, /* 304 */ + { 39, 13, 0, }, /* 305 */ + { 39, 15, 0, }, /* 306 */ + { 39, 26, 0, }, /* 307 */ + { 31, 26, 0, }, /* 308 */ + { 5, 7, 0, }, /* 309 */ + { 5, 12, 0, }, /* 310 */ + { 5, 10, 0, }, /* 311 */ + { 5, 21, 0, }, /* 312 */ + { 90, 7, 0, }, /* 313 */ + { 90, 10, 0, }, /* 314 */ + { 90, 12, 0, }, /* 315 */ + { 90, 13, 0, }, /* 316 */ + { 90, 21, 0, }, /* 317 */ + { 90, 6, 0, }, /* 318 */ + { 61, 12, 0, }, /* 319 */ + { 61, 10, 0, }, /* 320 */ + { 61, 7, 0, }, /* 321 */ + { 61, 13, 0, }, /* 322 */ + { 61, 21, 0, }, /* 323 */ + { 61, 26, 0, }, /* 324 */ + { 75, 12, 0, }, /* 325 */ + { 75, 10, 0, }, /* 326 */ + { 75, 7, 0, }, /* 327 */ + { 75, 13, 0, }, /* 328 */ + { 92, 7, 0, }, /* 329 */ + { 92, 12, 0, }, /* 330 */ + { 92, 10, 0, }, /* 331 */ + { 92, 21, 0, }, /* 332 */ + { 69, 7, 0, }, /* 333 */ + { 69, 10, 0, }, /* 334 */ + { 69, 12, 0, }, /* 335 */ + { 69, 21, 0, }, /* 336 */ + { 69, 13, 0, }, /* 337 */ + { 72, 13, 0, }, /* 338 */ + { 72, 7, 0, }, /* 339 */ + { 72, 6, 0, }, /* 340 */ + { 72, 21, 0, }, /* 341 */ + { 75, 21, 0, }, /* 342 */ + { 9, 10, 0, }, /* 343 */ + { 9, 7, 0, }, /* 344 */ + { 12, 5, 0, }, /* 345 */ + { 12, 6, 0, }, /* 346 */ + { 33, 5, 35332, }, /* 347 */ + { 33, 5, 3814, }, /* 348 */ + { 33, 5, -59, }, /* 349 */ + { 33, 9, -7615, }, /* 350 */ + { 19, 5, 8, }, /* 351 */ + { 19, 9, -8, }, /* 352 */ + { 19, 5, 74, }, /* 353 */ + { 19, 5, 86, }, /* 354 */ + { 19, 5, 100, }, /* 355 */ + { 19, 5, 128, }, /* 356 */ + { 19, 5, 112, }, /* 357 */ + { 19, 5, 126, }, /* 358 */ + { 19, 8, -8, }, /* 359 */ + { 19, 5, 9, }, /* 360 */ + { 19, 9, -74, }, /* 361 */ + { 19, 8, -9, }, /* 362 */ + { 19, 5, -7205, }, /* 363 */ + { 19, 9, -86, }, /* 364 */ + { 19, 9, -100, }, /* 365 */ + { 19, 9, -112, }, /* 366 */ + { 19, 9, -128, }, /* 367 */ + { 19, 9, -126, }, /* 368 */ + { 27, 1, 0, }, /* 369 */ + { 9, 27, 0, }, /* 370 */ + { 9, 28, 0, }, /* 371 */ + { 27, 11, 0, }, /* 372 */ + { 9, 9, 0, }, /* 373 */ + { 9, 5, 0, }, /* 374 */ + { 19, 9, -7517, }, /* 375 */ + { 33, 9, -8383, }, /* 376 */ + { 33, 9, -8262, }, /* 377 */ + { 33, 9, 28, }, /* 378 */ + { 33, 5, -28, }, /* 379 */ + { 33, 14, 16, }, /* 380 */ + { 33, 14, -16, }, /* 381 */ + { 33, 14, 0, }, /* 382 */ + { 9, 26, 26, }, /* 383 */ + { 9, 26, -26, }, /* 384 */ + { 4, 26, 0, }, /* 385 */ + { 17, 9, 48, }, /* 386 */ + { 17, 5, -48, }, /* 387 */ + { 33, 9, -10743, }, /* 388 */ + { 33, 9, -3814, }, /* 389 */ + { 33, 9, -10727, }, /* 390 */ + { 33, 5, -10795, }, /* 391 */ + { 33, 5, -10792, }, /* 392 */ + { 33, 9, -10780, }, /* 393 */ + { 33, 9, -10749, }, /* 394 */ + { 33, 9, -10783, }, /* 395 */ + { 33, 9, -10782, }, /* 396 */ + { 33, 9, -10815, }, /* 397 */ + { 10, 5, 0, }, /* 398 */ + { 10, 26, 0, }, /* 399 */ + { 10, 12, 0, }, /* 400 */ + { 10, 21, 0, }, /* 401 */ + { 10, 15, 0, }, /* 402 */ + { 16, 5, -7264, }, /* 403 */ + { 58, 7, 0, }, /* 404 */ + { 58, 6, 0, }, /* 405 */ + { 58, 21, 0, }, /* 406 */ + { 58, 12, 0, }, /* 407 */ + { 22, 26, 0, }, /* 408 */ + { 22, 6, 0, }, /* 409 */ + { 22, 14, 0, }, /* 410 */ + { 23, 10, 0, }, /* 411 */ + { 26, 7, 0, }, /* 412 */ + { 26, 6, 0, }, /* 413 */ + { 29, 7, 0, }, /* 414 */ + { 29, 6, 0, }, /* 415 */ + { 3, 7, 0, }, /* 416 */ + { 23, 26, 0, }, /* 417 */ + { 29, 26, 0, }, /* 418 */ + { 22, 7, 0, }, /* 419 */ + { 60, 7, 0, }, /* 420 */ + { 60, 6, 0, }, /* 421 */ + { 60, 26, 0, }, /* 422 */ + { 85, 7, 0, }, /* 423 */ + { 85, 6, 0, }, /* 424 */ + { 85, 21, 0, }, /* 425 */ + { 76, 7, 0, }, /* 426 */ + { 76, 6, 0, }, /* 427 */ + { 76, 21, 0, }, /* 428 */ + { 76, 13, 0, }, /* 429 */ + { 12, 7, 0, }, /* 430 */ + { 12, 21, 0, }, /* 431 */ + { 78, 7, 0, }, /* 432 */ + { 78, 14, 0, }, /* 433 */ + { 78, 12, 0, }, /* 434 */ + { 78, 21, 0, }, /* 435 */ + { 33, 9, -35332, }, /* 436 */ + { 33, 9, -42280, }, /* 437 */ + { 33, 9, -42308, }, /* 438 */ + { 48, 7, 0, }, /* 439 */ + { 48, 12, 0, }, /* 440 */ + { 48, 10, 0, }, /* 441 */ + { 48, 26, 0, }, /* 442 */ + { 64, 7, 0, }, /* 443 */ + { 64, 21, 0, }, /* 444 */ + { 74, 10, 0, }, /* 445 */ + { 74, 7, 0, }, /* 446 */ + { 74, 12, 0, }, /* 447 */ + { 74, 21, 0, }, /* 448 */ + { 74, 13, 0, }, /* 449 */ + { 68, 13, 0, }, /* 450 */ + { 68, 7, 0, }, /* 451 */ + { 68, 12, 0, }, /* 452 */ + { 68, 21, 0, }, /* 453 */ + { 73, 7, 0, }, /* 454 */ + { 73, 12, 0, }, /* 455 */ + { 73, 10, 0, }, /* 456 */ + { 73, 21, 0, }, /* 457 */ + { 83, 12, 0, }, /* 458 */ + { 83, 10, 0, }, /* 459 */ + { 83, 7, 0, }, /* 460 */ + { 83, 21, 0, }, /* 461 */ + { 83, 6, 0, }, /* 462 */ + { 83, 13, 0, }, /* 463 */ + { 67, 7, 0, }, /* 464 */ + { 67, 12, 0, }, /* 465 */ + { 67, 10, 0, }, /* 466 */ + { 67, 13, 0, }, /* 467 */ + { 67, 21, 0, }, /* 468 */ + { 38, 6, 0, }, /* 469 */ + { 91, 7, 0, }, /* 470 */ + { 91, 12, 0, }, /* 471 */ + { 91, 6, 0, }, /* 472 */ + { 91, 21, 0, }, /* 473 */ + { 86, 7, 0, }, /* 474 */ + { 86, 10, 0, }, /* 475 */ + { 86, 12, 0, }, /* 476 */ + { 86, 21, 0, }, /* 477 */ + { 86, 6, 0, }, /* 478 */ + { 86, 13, 0, }, /* 479 */ + { 9, 4, 0, }, /* 480 */ + { 9, 3, 0, }, /* 481 */ + { 25, 25, 0, }, /* 482 */ + { 0, 24, 0, }, /* 483 */ + { 35, 7, 0, }, /* 484 */ + { 19, 14, 0, }, /* 485 */ + { 19, 15, 0, }, /* 486 */ + { 19, 26, 0, }, /* 487 */ + { 70, 7, 0, }, /* 488 */ + { 66, 7, 0, }, /* 489 */ + { 41, 7, 0, }, /* 490 */ + { 41, 15, 0, }, /* 491 */ + { 18, 7, 0, }, /* 492 */ + { 18, 14, 0, }, /* 493 */ + { 59, 7, 0, }, /* 494 */ + { 59, 21, 0, }, /* 495 */ + { 42, 7, 0, }, /* 496 */ + { 42, 21, 0, }, /* 497 */ + { 42, 14, 0, }, /* 498 */ + { 13, 9, 40, }, /* 499 */ + { 13, 5, -40, }, /* 500 */ + { 46, 7, 0, }, /* 501 */ + { 44, 7, 0, }, /* 502 */ + { 44, 13, 0, }, /* 503 */ + { 11, 7, 0, }, /* 504 */ + { 80, 7, 0, }, /* 505 */ + { 80, 21, 0, }, /* 506 */ + { 80, 15, 0, }, /* 507 */ + { 65, 7, 0, }, /* 508 */ + { 65, 15, 0, }, /* 509 */ + { 65, 21, 0, }, /* 510 */ + { 71, 7, 0, }, /* 511 */ + { 71, 21, 0, }, /* 512 */ + { 97, 7, 0, }, /* 513 */ + { 96, 7, 0, }, /* 514 */ + { 30, 7, 0, }, /* 515 */ + { 30, 12, 0, }, /* 516 */ + { 30, 15, 0, }, /* 517 */ + { 30, 21, 0, }, /* 518 */ + { 87, 7, 0, }, /* 519 */ + { 87, 15, 0, }, /* 520 */ + { 87, 21, 0, }, /* 521 */ + { 77, 7, 0, }, /* 522 */ + { 77, 21, 0, }, /* 523 */ + { 82, 7, 0, }, /* 524 */ + { 82, 15, 0, }, /* 525 */ + { 81, 7, 0, }, /* 526 */ + { 81, 15, 0, }, /* 527 */ + { 88, 7, 0, }, /* 528 */ + { 0, 15, 0, }, /* 529 */ + { 93, 10, 0, }, /* 530 */ + { 93, 12, 0, }, /* 531 */ + { 93, 7, 0, }, /* 532 */ + { 93, 21, 0, }, /* 533 */ + { 93, 15, 0, }, /* 534 */ + { 93, 13, 0, }, /* 535 */ + { 84, 12, 0, }, /* 536 */ + { 84, 10, 0, }, /* 537 */ + { 84, 7, 0, }, /* 538 */ + { 84, 21, 0, }, /* 539 */ + { 84, 1, 0, }, /* 540 */ + { 100, 7, 0, }, /* 541 */ + { 100, 13, 0, }, /* 542 */ + { 95, 12, 0, }, /* 543 */ + { 95, 7, 0, }, /* 544 */ + { 95, 10, 0, }, /* 545 */ + { 95, 13, 0, }, /* 546 */ + { 95, 21, 0, }, /* 547 */ + { 99, 12, 0, }, /* 548 */ + { 99, 10, 0, }, /* 549 */ + { 99, 7, 0, }, /* 550 */ + { 99, 21, 0, }, /* 551 */ + { 99, 13, 0, }, /* 552 */ + { 101, 7, 0, }, /* 553 */ + { 101, 12, 0, }, /* 554 */ + { 101, 10, 0, }, /* 555 */ + { 101, 13, 0, }, /* 556 */ + { 62, 7, 0, }, /* 557 */ + { 62, 14, 0, }, /* 558 */ + { 62, 21, 0, }, /* 559 */ + { 79, 7, 0, }, /* 560 */ + { 98, 7, 0, }, /* 561 */ + { 98, 10, 0, }, /* 562 */ + { 98, 12, 0, }, /* 563 */ + { 98, 6, 0, }, /* 564 */ + { 19, 12, 0, }, /* 565 */ + { 26, 26, 0, }, /* 566 */ }; -const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */ +const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */ 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */ - 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, /* U+2000 */ - 76, 76, 65, 77, 65, 65, 78, 17, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */ + 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */ + 75, 75, 65, 76, 65, 65, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */ 87, 88, 89, 90, 91, 92, 93, 70, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+4000 */ @@ -575,49 +624,49 @@ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+9000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 96, /* U+9800 */ 97, 98, 98, 98, 98, 98, 98, 98, 98, 99,100,100,101,102,103,104, /* U+A000 */ -105,106,107,108,109,110, 17,111, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */ +105,106,107,108,109,110,111,112, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */ - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,112, /* U+D000 */ -113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, /* U+D800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F000 */ -114,114, 94, 94,115,116,117,118,119,119,120,121,122,123,124,125, /* U+F800 */ -126,127,128,129, 17,130,131,132,133,134, 17, 17, 17, 17, 17, 17, /* U+10000 */ -135, 17,136, 17,137, 17,138, 17,139, 17, 17, 17,140, 17, 17, 17, /* U+10800 */ - 17,141, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11800 */ -142,142,142,142,142,142,143, 17,144, 17, 17, 17, 17, 17, 17, 17, /* U+12000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+12800 */ -145,145,145,145,145,145,145,145,146, 17, 17, 17, 17, 17, 17, 17, /* U+13000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+13800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C800 */ - 70,147,148,149,150, 17,151, 17,152,153,154,155,156,157,158,159, /* U+1D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E800 */ -160,161,162,163,164, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F800 */ + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,113, /* U+D000 */ +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+D800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F000 */ +115,115, 94, 94,116,117,118,119,120,120,121,122,123,124,125,126, /* U+F800 */ +127,128,129,130, 78,131,132,133,134,135, 78, 78, 78, 78, 78, 78, /* U+10000 */ +136, 78,137,138,139, 78,140, 78,141, 78, 78, 78,142, 78, 78, 78, /* U+10800 */ +143,144,145,146, 78, 78, 78, 78, 78, 78, 78, 78, 78,147, 78, 78, /* U+11000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+11800 */ +148,148,148,148,148,148,149, 78,150, 78, 78, 78, 78, 78, 78, 78, /* U+12000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+12800 */ +151,151,151,151,151,151,151,151,152, 78, 78, 78, 78, 78, 78, 78, /* U+13000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+13800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+16000 */ +153,153,153,153,154, 78, 78, 78, 78, 78, 78, 78, 78, 78,155,156, /* U+16800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A800 */ +157, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C800 */ + 70,158,159,160,161, 78,162, 78,163,164,165,166,167,168,169,170, /* U+1D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,171,172, 78, 78, /* U+1E800 */ +173,174,175,176,177, 78,178,179,180,181,182,183,184,185,186, 78, /* U+1F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1F800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21000 */ @@ -638,469 +687,469 @@ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28800 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,165, 94, 94, /* U+2A000 */ + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,187, 94, 94, /* U+2A000 */ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+2A800 */ - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,166, 17, /* U+2B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F000 */ - 94, 94, 94, 94,167, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF800 */ -168, 17,169,170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE800 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF000 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FF000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+FF800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E800 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10F000 */ -114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+10F800 */ + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,188, 94, /* U+2B000 */ +189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F000 */ + 94, 94, 94, 94,189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF800 */ +190, 78,191,192, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE800 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF000 */ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FF000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+FF800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E800 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10F000 */ +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+10F800 */ }; -const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */ +const pcre_uint16 PRIV(ucd_stage2)[] = { /* 49664 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1114,635 +1163,635 @@ /* block 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 3, 3, 3, 13, 13, 10, 13, 14, 15, 6, 16, 13, 10, - 13, 6, 17, 17, 10, 18, 13, 2, 10, 17, 14, 19, 17, 17, 17, 2, + 1, 2, 3, 3, 3, 3, 13, 2, 10, 13, 14, 15, 6, 16, 13, 10, + 13, 6, 17, 17, 10, 18, 2, 2, 10, 17, 14, 19, 17, 17, 17, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 14, + 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 20, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 20, + 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 21, /* block 2 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 23, 24, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, 21, - 22, 21, 22, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 25, 21, 22, 21, 22, 21, 22, 26, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 24, 25, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 26, 22, 23, 22, 23, 22, 23, 27, /* block 3 */ - 27, 28, 21, 22, 21, 22, 29, 21, 22, 30, 30, 21, 22, 14, 31, 32, - 33, 21, 22, 30, 34, 35, 36, 37, 21, 22, 38, 14, 36, 39, 40, 41, - 21, 22, 21, 22, 21, 22, 42, 21, 22, 42, 14, 14, 21, 22, 42, 21, - 22, 43, 43, 21, 22, 21, 22, 44, 21, 22, 14, 45, 21, 22, 14, 46, - 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 21, 22, 21, - 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 50, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 14, 47, 48, 49, 21, 22, 51, 52, 21, 22, 21, 22, 21, 22, 21, 22, + 28, 29, 22, 23, 22, 23, 30, 22, 23, 31, 31, 22, 23, 20, 32, 33, + 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39, 20, 37, 40, 41, 42, + 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 20, 20, 22, 23, 43, 22, + 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 20, 14, 22, 23, 20, 46, + 14, 14, 14, 14, 47, 48, 49, 47, 48, 49, 47, 48, 49, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 50, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 20, 47, 48, 49, 22, 23, 51, 52, 22, 23, 22, 23, 22, 23, 22, 23, /* block 4 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 53, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 14, 14, 14, 14, 14, 14, 54, 21, 22, 55, 56, 57, - 57, 21, 22, 58, 59, 60, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 61, 62, 63, 64, 65, 14, 66, 66, 14, 67, 14, 68, 14, 14, 14, 14, - 66, 14, 14, 69, 14, 14, 14, 14, 70, 71, 14, 72, 14, 14, 14, 71, - 14, 73, 74, 14, 14, 75, 14, 14, 14, 14, 14, 14, 14, 76, 14, 14, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 53, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 20, 20, 20, 20, 20, 20, 54, 22, 23, 55, 56, 57, + 57, 22, 23, 58, 59, 60, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 61, 62, 63, 64, 65, 20, 66, 66, 20, 67, 20, 68, 20, 20, 20, 20, + 66, 20, 20, 69, 20, 70, 71, 20, 72, 73, 20, 74, 20, 20, 20, 73, + 20, 75, 76, 20, 20, 77, 20, 20, 20, 20, 20, 20, 20, 78, 20, 20, /* block 5 */ - 77, 14, 14, 77, 14, 14, 14, 14, 77, 78, 79, 79, 80, 14, 14, 14, - 14, 14, 81, 14, 45, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 82, 82, 82, 82, 82, 10, 10, 10, 10, 10, 10, 10, 83, 10, 83, 10, + 79, 20, 20, 79, 20, 20, 20, 20, 79, 80, 81, 81, 82, 20, 20, 20, + 20, 20, 83, 20, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 84, 84, 84, 84, 84, 10, 10, 10, 10, 10, 86, 86, 85, 10, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* block 6 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 85, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 86, 87, 86, 87, 83, 88, 86, 87, 89, 89, 90, 91, 91, 91, 2, 89, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 89, 90, 89, 90, 85, 91, 89, 90, 92, 92, 93, 94, 94, 94, 2, 92, /* block 7 */ - 89, 89, 89, 89, 88, 10, 92, 2, 93, 93, 93, 89, 94, 89, 95, 95, - 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 89, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99, 99, - 96,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, -100,100,101,100,100,100,100,100,100,100,100,100,102,103,103,104, -105,106,107,107,107,108,109,110, 86, 87, 86, 87, 86, 87, 86, 87, - 86, 87,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -113,114,115, 96,116,117,118, 86, 87,119, 86, 87, 96,120,120,120, + 92, 92, 92, 92, 91, 10, 95, 2, 96, 96, 96, 92, 97, 92, 98, 98, + 99,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100, 92,100,100,100,100,100,100,100,100,100,101,102,102,102, + 99,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,104,103,103,103,103,103,103,103,103,103,105,106,106,107, +108,109,110,110,110,111,112,113, 89, 90, 89, 90, 89, 90, 89, 90, + 89, 90,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +116,117,118, 99,119,120,121, 89, 90,122, 89, 90, 99,123,123,123, /* block 8 */ -121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, -122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, -122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, -123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, -123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 9 */ -125,126,127,128,128, 84, 84,128,129,129,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -130,125,126,125,126,125,126,125,126,125,126,125,126,125,126,131, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, +128,129,130,131,131, 87, 87,131,132,132,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +133,128,129,128,129,128,129,128,129,128,129,128,129,128,129,134, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, /* block 10 */ -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, -132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, -132,132,132,132,132,132,132, 89, 89,133,134,134,134,134,134,134, - 89,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92, 92, + 92,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135, 92, 92,136,137,137,137,137,137,137, + 92,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, /* block 11 */ -135,135,135,135,135,135,135,136, 89, 2,137, 89, 89, 89, 89, 89, - 89,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, -138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, -138,138,138,138,138,138,138,138,138,138,138,138,138,138,139,138, -140,138,138,140,138,138,140,138, 89, 89, 89, 89, 89, 89, 89, 89, -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, -141,141,141,141,141,141,141,141,141,141,141, 89, 89, 89, 89, 89, -141,141,141,140,140, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +138,138,138,138,138,138,138,139, 92, 2,140, 92, 92, 92, 92,141, + 92,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,143,142, +144,142,142,144,142,142,144,142, 92, 92, 92, 92, 92, 92, 92, 92, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145, 92, 92, 92, 92, 92, +145,145,145,144,144, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 12 */ - 16, 16, 16, 16, 89, 89,142,142,142,143,143,144, 2,143,145,145, -146,146,146,146,146,146,146,146,146,146,146, 2, 89, 89,143, 2, - 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, - 83,147,147,147,147,147,147,147,147,147,147, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84,146,146,146,146,146,146,146,146,146, 89, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,143,143,143,143,147,147, - 84,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +146,146,146,146,146, 92,147,147,147,148,148,149, 2,148,150,150, +151,151,151,151,151,151,151,151,151,151,151, 2, 92, 92,148, 2, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 85,152,152,152,152,152,152,152,152,152,152, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87,151,151,151,151,151,151,151,151,151, 87, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,148,148,148,148,152,152, + 87,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 13 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,143,147,146,146,146,146,146,146,146, 16,148,146, -146,146,146,146,146,149,149,146,146,145,146,146,146,146,147,147, -150,150,150,150,150,150,150,150,150,150,147,147,147,145,145,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,148,152,151,151,151,151,151,151,151, 16,150,151, +151,151,151,151,151,153,153,151,151,150,151,151,151,151,152,152, +154,154,154,154,154,154,154,154,154,154,152,152,152,150,150,152, /* block 14 */ -151,151,151,151,151,151,151,151,151,151,151,151,151,151, 89,152, -153,154,153,153,153,153,153,153,153,153,153,153,153,153,153,153, -153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154, 89, 89,153,153,153, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +155,155,155,155,155,155,155,155,155,155,155,155,155,155, 92,156, +157,158,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158, 92, 92,157,157,157, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 15 */ -155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, -155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, -155,155,155,155,155,155,156,156,156,156,156,156,156,156,156,156, -156,155, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -157,157,157,157,157,157,157,157,157,157,158,158,158,158,158,158, -158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, -158,158,158,158,158,158,158,158,158,158,158,159,159,159,159,159, -159,159,159,159,160,160,161,162,162,162,160, 89, 89, 89, 89, 89, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160, +160,159, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +161,161,161,161,161,161,161,161,161,161,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,163,163,163,163,163, +163,163,163,163,164,164,165,166,166,166,164, 92, 92, 92, 92, 92, /* block 16 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,164,164,164,164,165,164,164,164,164,164, -164,164,164,164,165,164,164,164,165,164,164,164,164,164, 89, 89, -166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,168,168,168,168,169,168,168,168,168,168, +168,168,168,168,169,168,168,168,169,168,168,168,168,168, 92, 92, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, 92, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,172,172,172, 92, 92,173, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 17 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152, 92,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 92, /* block 18 */ -167,167,167,168,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, -169,169,169,169,169,169,169,169,169,169, 89, 89,167,169,168,168, -168,167,167,167,167,167,167,167,167,168,168,168,168,167,168, 89, -169, 84, 84,167,167,167, 89, 89,169,169,169,169,169,169,169,169, -169,169,167,167, 2, 2,170,170,170,170,170,170,170,170,170,170, - 2,171,169, 89, 89, 89, 89, 89, 89,169,169,169,169,169,169,169, +174,174,174,175,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,174,175,174,176,175,175, +175,174,174,174,174,174,174,174,174,175,175,175,175,174,175,175, +176, 87, 87,174,174,174,174,174,176,176,176,176,176,176,176,176, +176,176,174,174, 2, 2,177,177,177,177,177,177,177,177,177,177, +178,179,176,176,176,176,176,176, 92,176,176,176,176,176,176,176, /* block 19 */ - 89,172,173,173, 89,174,174,174,174,174,174,174,174, 89, 89,174, -174, 89, 89,174,174,174,174,174,174,174,174,174,174,174,174,174, -174,174,174,174,174,174,174,174,174, 89,174,174,174,174,174,174, -174, 89,174, 89, 89, 89,174,174,174,174, 89, 89,172,174,173,173, -173,172,172,172,172, 89, 89,173,173, 89, 89,173,173,172,174, 89, - 89, 89, 89, 89, 89, 89, 89,173, 89, 89, 89, 89,174,174, 89,174, -174,174,172,172, 89, 89,175,175,175,175,175,175,175,175,175,175, -174,174,176,176,177,177,177,177,177,177,178,176, 89, 89, 89, 89, + 92,180,181,181, 92,182,182,182,182,182,182,182,182, 92, 92,182, +182, 92, 92,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182, 92,182,182,182,182,182,182, +182, 92,182, 92, 92, 92,182,182,182,182, 92, 92,180,182,181,181, +181,180,180,180,180, 92, 92,181,181, 92, 92,181,181,180,182, 92, + 92, 92, 92, 92, 92, 92, 92,181, 92, 92, 92, 92,182,182, 92,182, +182,182,180,180, 92, 92,183,183,183,183,183,183,183,183,183,183, +182,182,184,184,185,185,185,185,185,185,186,184, 92, 92, 92, 92, /* block 20 */ - 89,179,179,180, 89,181,181,181,181,181,181, 89, 89, 89, 89,181, -181, 89, 89,181,181,181,181,181,181,181,181,181,181,181,181,181, -181,181,181,181,181,181,181,181,181, 89,181,181,181,181,181,181, -181, 89,181,181, 89,181,181, 89,181,181, 89, 89,179, 89,180,180, -180,179,179, 89, 89, 89, 89,179,179, 89, 89,179,179,179, 89, 89, - 89,179, 89, 89, 89, 89, 89, 89, 89,181,181,181,181, 89,181, 89, - 89, 89, 89, 89, 89, 89,182,182,182,182,182,182,182,182,182,182, -179,179,181,181,181,179, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,187,187,188, 92,189,189,189,189,189,189, 92, 92, 92, 92,189, +189, 92, 92,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189, 92,189,189,189,189,189,189, +189, 92,189,189, 92,189,189, 92,189,189, 92, 92,187, 92,188,188, +188,187,187, 92, 92, 92, 92,187,187, 92, 92,187,187,187, 92, 92, + 92,187, 92, 92, 92, 92, 92, 92, 92,189,189,189,189, 92,189, 92, + 92, 92, 92, 92, 92, 92,190,190,190,190,190,190,190,190,190,190, +187,187,189,189,189,187, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 21 */ - 89,183,183,184, 89,185,185,185,185,185,185,185,185,185, 89,185, -185,185, 89,185,185,185,185,185,185,185,185,185,185,185,185,185, -185,185,185,185,185,185,185,185,185, 89,185,185,185,185,185,185, -185, 89,185,185, 89,185,185,185,185,185, 89, 89,183,185,184,184, -184,183,183,183,183,183, 89,183,183,184, 89,184,184,183, 89, 89, -185, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -185,185,183,183, 89, 89,186,186,186,186,186,186,186,186,186,186, - 89,187, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,191,191,192, 92,193,193,193,193,193,193,193,193,193, 92,193, +193,193, 92,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193, 92,193,193,193,193,193,193, +193, 92,193,193, 92,193,193,193,193,193, 92, 92,191,193,192,192, +192,191,191,191,191,191, 92,191,191,192, 92,192,192,191, 92, 92, +193, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +193,193,191,191, 92, 92,194,194,194,194,194,194,194,194,194,194, +195,196, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 22 */ - 89,188,189,189, 89,190,190,190,190,190,190,190,190, 89, 89,190, -190, 89, 89,190,190,190,190,190,190,190,190,190,190,190,190,190, -190,190,190,190,190,190,190,190,190, 89,190,190,190,190,190,190, -190, 89,190,190, 89,190,190,190,190,190, 89, 89,188,190,189,188, -189,188,188,188,188, 89, 89,189,189, 89, 89,189,189,188, 89, 89, - 89, 89, 89, 89, 89, 89,188,189, 89, 89, 89, 89,190,190, 89,190, -190,190,188,188, 89, 89,191,191,191,191,191,191,191,191,191,191, -192,190, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,197,198,198, 92,199,199,199,199,199,199,199,199, 92, 92,199, +199, 92, 92,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199, 92,199,199,199,199,199,199, +199, 92,199,199, 92,199,199,199,199,199, 92, 92,197,199,198,197, +198,197,197,197,197, 92, 92,198,198, 92, 92,198,198,197, 92, 92, + 92, 92, 92, 92, 92, 92,197,198, 92, 92, 92, 92,199,199, 92,199, +199,199,197,197, 92, 92,200,200,200,200,200,200,200,200,200,200, +201,199,202,202,202,202,202,202, 92, 92, 92, 92, 92, 92, 92, 92, /* block 23 */ - 89, 89,193,194, 89,194,194,194,194,194,194, 89, 89, 89,194,194, -194, 89,194,194,194,194, 89, 89, 89,194,194, 89,194, 89,194,194, - 89, 89, 89,194,194, 89, 89, 89,194,194,194, 89, 89, 89,194,194, -194,194,194,194,194,194,194,194,194,194, 89, 89, 89, 89,195,195, -193,195,195, 89, 89, 89,195,195,195, 89,195,195,195,193, 89, 89, -194, 89, 89, 89, 89, 89, 89,195, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89,196,196,196,196,196,196,196,196,196,196, -197,197,197,198,198,198,198,198,198,199,198, 89, 89, 89, 89, 89, + 92, 92,203,204, 92,204,204,204,204,204,204, 92, 92, 92,204,204, +204, 92,204,204,204,204, 92, 92, 92,204,204, 92,204, 92,204,204, + 92, 92, 92,204,204, 92, 92, 92,204,204,204, 92, 92, 92,204,204, +204,204,204,204,204,204,204,204,204,204, 92, 92, 92, 92,205,205, +203,205,205, 92, 92, 92,205,205,205, 92,205,205,205,203, 92, 92, +204, 92, 92, 92, 92, 92, 92,205, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92,206,206,206,206,206,206,206,206,206,206, +207,207,207,208,208,208,208,208,208,209,208, 92, 92, 92, 92, 92, /* block 24 */ - 89,200,200,200, 89,201,201,201,201,201,201,201,201, 89,201,201, -201, 89,201,201,201,201,201,201,201,201,201,201,201,201,201,201, -201,201,201,201,201,201,201,201,201, 89,201,201,201,201,201,201, -201,201,201,201, 89,201,201,201,201,201, 89, 89, 89,201,202,202, -202,200,200,200,200, 89,202,202,202, 89,202,202,202,202, 89, 89, - 89, 89, 89, 89, 89,202,202, 89,201,201, 89, 89, 89, 89, 89, 89, -201,201,202,202, 89, 89,203,203,203,203,203,203,203,203,203,203, - 89, 89, 89, 89, 89, 89, 89, 89,204,204,204,204,204,204,204,205, + 92,210,210,210, 92,211,211,211,211,211,211,211,211, 92,211,211, +211, 92,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211, 92,211,211,211,211,211,211, +211,211,211,211, 92,211,211,211,211,211, 92, 92, 92,211,212,212, +212,210,210,210,210, 92,212,212,212, 92,212,212,212,212, 92, 92, + 92, 92, 92, 92, 92,212,212, 92,211,211, 92, 92, 92, 92, 92, 92, +211,211,212,212, 92, 92,213,213,213,213,213,213,213,213,213,213, + 92, 92, 92, 92, 92, 92, 92, 92,214,214,214,214,214,214,214,215, /* block 25 */ - 89, 89,206,206, 89,207,207,207,207,207,207,207,207, 89,207,207, -207, 89,207,207,207,207,207,207,207,207,207,207,207,207,207,207, -207,207,207,207,207,207,207,207,207, 89,207,207,207,207,207,207, -207,207,207,207, 89,207,207,207,207,207, 89, 89,208,207,206,208, -206,206,206,206,206, 89,208,206,206, 89,206,206,208,208, 89, 89, - 89, 89, 89, 89, 89,206,206, 89, 89, 89, 89, 89, 89, 89,207, 89, -207,207,208,208, 89, 89,209,209,209,209,209,209,209,209,209,209, - 89, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92,216,216, 92,217,217,217,217,217,217,217,217, 92,217,217, +217, 92,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217, 92,217,217,217,217,217,217, +217,217,217,217, 92,217,217,217,217,217, 92, 92,218,217,216,218, +216,216,216,216,216, 92,218,216,216, 92,216,216,218,218, 92, 92, + 92, 92, 92, 92, 92,216,216, 92, 92, 92, 92, 92, 92, 92,217, 92, +217,217,218,218, 92, 92,219,219,219,219,219,219,219,219,219,219, + 92,217,217, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 26 */ - 89, 89,210,210, 89,211,211,211,211,211,211,211,211, 89,211,211, -211, 89,211,211,211,211,211,211,211,211,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211, 89,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211,211, 89, 89, 89,211,210,210, -210,212,212,212,212, 89,210,210,210, 89,210,210,210,212, 89, 89, - 89, 89, 89, 89, 89, 89, 89,210, 89, 89, 89, 89, 89, 89, 89, 89, -211,211,212,212, 89, 89,213,213,213,213,213,213,213,213,213,213, -214,214,214,214,214,214, 89, 89, 89,215,211,211,211,211,211,211, + 92, 92,220,220, 92,221,221,221,221,221,221,221,221, 92,221,221, +221, 92,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221, 92, 92,221,220,220, +220,222,222,222,222, 92,220,220,220, 92,220,220,220,222,221, 92, + 92, 92, 92, 92, 92, 92, 92,220, 92, 92, 92, 92, 92, 92, 92, 92, +221,221,222,222, 92, 92,223,223,223,223,223,223,223,223,223,223, +224,224,224,224,224,224, 92, 92, 92,225,221,221,221,221,221,221, /* block 27 */ - 89, 89,216,216, 89,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217, 89, 89, 89,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217, 89,217,217,217,217,217,217,217,217,217, 89,217, 89, 89, -217,217,217,217,217,217,217, 89, 89, 89,218, 89, 89, 89, 89,216, -216,216,218,218,218, 89,218, 89,216,216,216,216,216,216,216,216, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89,216,216,219, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92,226,226, 92,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227, 92, 92, 92,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227, 92,227,227,227,227,227,227,227,227,227, 92,227, 92, 92, +227,227,227,227,227,227,227, 92, 92, 92,228, 92, 92, 92, 92,226, +226,226,228,228,228, 92,228, 92,226,226,226,226,226,226,226,226, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92,226,226,229, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 28 */ - 89,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, -220,221,220,220,221,221,221,221,221,221,221, 89, 89, 89, 89, 3, -220,220,220,220,220,220,222,221,221,221,221,221,221,221,221,223, -224,224,224,224,224,224,224,224,224,224,223,223, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,231,230,230,231,231,231,231,231,231,231, 92, 92, 92, 92, 3, +230,230,230,230,230,230,232,231,231,231,231,231,231,231,231,233, +234,234,234,234,234,234,234,234,234,234,233,233, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 29 */ - 89,225,225, 89,225, 89, 89,225,225, 89,225, 89, 89,225, 89, 89, - 89, 89, 89, 89,225,225,225,225, 89,225,225,225,225,225,225,225, - 89,225,225,225, 89,225, 89,225, 89, 89,225,225, 89,225,225,225, -225,226,225,225,226,226,226,226,226,226, 89,226,226,225, 89, 89, -225,225,225,225,225, 89,227, 89,226,226,226,226,226,226, 89, 89, -228,228,228,228,228,228,228,228,228,228, 89, 89,225,225, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92,235,235, 92,235, 92, 92,235,235, 92,235, 92, 92,235, 92, 92, + 92, 92, 92, 92,235,235,235,235, 92,235,235,235,235,235,235,235, + 92,235,235,235, 92,235, 92,235, 92, 92,235,235, 92,235,235,235, +235,236,235,235,236,236,236,236,236,236, 92,236,236,235, 92, 92, +235,235,235,235,235, 92,237, 92,236,236,236,236,236,236, 92, 92, +238,238,238,238,238,238,238,238,238,238, 92, 92,235,235,235,235, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 30 */ -229,230,230,230,231,231,231,231,231,231,231,231,231,231,231,231, -231,231,231,230,230,230,230,230,232,232,230,230,230,230,230,230, -233,233,233,233,233,233,233,233,233,233,234,234,234,234,234,234, -234,234,234,234,230,232,230,232,230,232,235,236,235,236,237,237, -229,229,229,229,229,229,229,229, 89,229,229,229,229,229,229,229, -229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, -229,229,229,229,229,229,229,229,229,229,229,229,229, 89, 89, 89, - 89,232,232,232,232,232,232,232,232,232,232,232,232,232,232,237, +239,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,240,241,240,240,240,242,242,240,240,240,240,240,240, +243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244, +244,244,244,244,240,242,240,242,240,242,245,246,245,246,247,247, +239,239,239,239,239,239,239,239, 92,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239, 92, 92, 92, + 92,242,242,242,242,242,242,242,242,242,242,242,242,242,242,247, /* block 31 */ -232,232,232,232,232,231,232,232,229,229,229,229, 89, 89, 89, 89, -232,232,232,232,232,232,232,232, 89,232,232,232,232,232,232,232, -232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, -232,232,232,232,232,232,232,232,232,232,232,232,232, 89,230,230, -230,230,230,230,230,230,232,230,230,230,230,230,230, 89,230,230, -231,231,231,231,231, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +242,242,242,242,242,241,242,242,239,239,239,239,239,242,242,242, +242,242,242,242,242,242,242,242, 92,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242, 92,240,240, +240,240,240,240,240,240,242,240,240,240,240,240,240, 92,240,240, +241,241,241,241,241, 13, 13, 13, 13,241,241, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 32 */ -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,239,239,240,240,240, -240,239,240,240,240,240,240,240,239,240,240,239,239,240,240,238, -241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242, -238,238,238,238,238,238,239,239,240,240,238,238,238,238,240,240, -240,238,239,239,239,238,238,239,239,239,239,239,239,239,238,238, -238,240,240,240,240,238,238,238,238,238,238,238,238,238,238,238, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,249,249,250,250,250, +250,249,250,250,250,250,250,250,249,250,250,249,249,250,250,248, +251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252, +248,248,248,248,248,248,249,249,250,250,248,248,248,248,250,250, +250,248,249,249,249,248,248,249,249,249,249,249,249,249,248,248, +248,250,250,250,250,248,248,248,248,248,248,248,248,248,248,248, /* block 33 */ -238,238,240,239,239,240,240,239,239,239,239,239,239,240,238,239, -241,241,241,241,241,241,241,241,241,241,239,239,239,240,243,243, -244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, -244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, -244,244,244,244,244,244, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, -245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, -245,245,245,245,245,245,245,245,245,245,245, 2,246, 89, 89, 89, +248,248,250,249,249,250,250,249,249,249,249,249,249,250,248,249, +251,251,251,251,251,251,251,251,251,251,249,249,249,250,253,253, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254, 92,254, 92, 92, 92, 92, 92,254, 92, 92, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255, 2,256,255,255,255, /* block 34 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 35 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248, 89,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258, 92,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 36 */ -248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248, 89, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258, 92, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, /* block 37 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,248,248, 89, 89, 89, 89,249, -250,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252, -252,252,252,252,252,252,252,252,252,252,252,252,252, 89, 89, 89, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258,258,258,258,258, 92, 92,259,259,259, +260,260,260,260,260,260,260,260,260,261,261,261,261,261,261,261, +261,261,261,261,261,261,261,261,261,261,261,261,261, 92, 92, 92, /* block 38 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -250,250,250,250,250,250,250,250,250,250, 89, 89, 89, 89, 89, 89, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +262,262,262,262,262,262,262,262,262,262, 92, 92, 92, 92, 92, 92, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,263,263,263, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 39 */ -254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +264,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 40 */ -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 41 */ -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,256,256,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,266,266,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, /* block 42 */ -257,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, -258,258,258,258,258,258,258,258,258,258,258,259,260, 89, 89, 89, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,261,261, 2, 2, 2,262,262, -262, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +267,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268, +268,268,268,268,268,268,268,268,268,268,268,269,270, 92, 92, 92, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, +271,271,271,271,271,271,271,271,271,271,271, 2, 2, 2,272,272, +272, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 43 */ -263,263,263,263,263,263,263,263,263,263,263,263,263, 89,263,263, -263,263,264,264,264, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, -265,265,266,266,266, 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89, -267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267, -267,267,268,268, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -269,269,269,269,269,269,269,269,269,269,269,269,269, 89,269,269, -269, 89,270,270, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +273,273,273,273,273,273,273,273,273,273,273,273,273, 92,273,273, +273,273,274,274,274, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275, +275,275,276,276,276, 2, 2, 92, 92, 92, 92, 92, 92, 92, 92, 92, +277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,278,278, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +279,279,279,279,279,279,279,279,279,279,279,279,279, 92,279,279, +279, 92,280,280, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 44 */ -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, -271,271,271,271,272,272,273,274,274,274,274,274,274,274,273,273, -273,273,273,273,273,273,274,273,273,274,274,274,274,274,274,274, -274,274,274,274,275,275,275,276,275,275,275,277,271,274, 89, 89, -278,278,278,278,278,278,278,278,278,278, 89, 89, 89, 89, 89, 89, -279,279,279,279,279,279,279,279,279,279, 89, 89, 89, 89, 89, 89, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, +281,281,281,281,282,282,283,282,282,282,282,282,282,282,283,283, +283,283,283,283,283,283,282,283,283,282,282,282,282,282,282,282, +282,282,282,282,284,284,284,285,284,284,284,286,281,282, 92, 92, +287,287,287,287,287,287,287,287,287,287, 92, 92, 92, 92, 92, 92, +288,288,288,288,288,288,288,288,288,288, 92, 92, 92, 92, 92, 92, /* block 45 */ -280,280, 2, 2,280, 2,281,280,280,280,280,282,282,282,283, 89, -284,284,284,284,284,284,284,284,284,284, 89, 89, 89, 89, 89, 89, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,286,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285, 89, 89, 89, 89, 89, 89, 89, 89, +289,289, 2, 2,289, 2,290,289,289,289,289,291,291,291,292, 92, +293,293,293,293,293,293,293,293,293,293, 92, 92, 92, 92, 92, 92, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,295,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294, 92, 92, 92, 92, 92, 92, 92, 92, /* block 46 */ -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285, -285,285,285,285,285,285,285,285,285,282,285, 89, 89, 89, 89, 89, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -255,255,255,255,255,255, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, +294,294,294,294,294,294,294,294,294,291,294, 92, 92, 92, 92, 92, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265, +265,265,265,265,265,265, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 47 */ -287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287, -287,287,287,287,287,287,287,287,287,287,287,287,287, 89, 89, 89, -288,288,288,289,289,289,289,288,288,289,289,289, 89, 89, 89, 89, -289,289,288,289,289,289,289,289,289,288,288,288, 89, 89, 89, 89, -290, 89, 89, 89,291,291,292,292,292,292,292,292,292,292,292,292, -293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293, -293,293,293,293,293,293,293,293,293,293,293,293,293,293, 89, 89, -293,293,293,293,293, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, +296,296,296,296,296,296,296,296,296,296,296,296,296, 92, 92, 92, +297,297,297,298,298,298,298,297,297,298,298,298, 92, 92, 92, 92, +298,298,297,298,298,298,298,298,298,297,297,297, 92, 92, 92, 92, +299, 92, 92, 92,300,300,301,301,301,301,301,301,301,301,301,301, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302, 92, 92, +302,302,302,302,302, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 48 */ -294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, -294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294, -294,294,294,294,294,294,294,294,294,294,294,294, 89, 89, 89, 89, -295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295, -295,294,294,294,294,294,294,294,295,295, 89, 89, 89, 89, 89, 89, -296,296,296,296,296,296,296,296,296,296,296, 89, 89, 89,297,297, -298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, -298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, - -/* block 49 */ -299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299, -299,299,299,299,299,299,299,300,300,301,301,301, 89, 89,302,302, -303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, 303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, 303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303, -303,303,303,303,303,304,305,304,305,305,305,305,305,305,305, 89, -305,304,305,304,304,305,305,305,305,305,305,305,305,304,304,304, -304,304,304,305,305,305,305,305,305,305,305,305,305, 89, 89,305, +303,303,303,303,303,303,303,303,303,303,303,303, 92, 92, 92, 92, +304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304, +304,303,303,303,303,303,303,303,304,304, 92, 92, 92, 92, 92, 92, +305,305,305,305,305,305,305,305,305,305,306, 92, 92, 92,307,307, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, + +/* block 49 */ +309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309, +309,309,309,309,309,309,309,310,310,311,311,311, 92, 92,312,312, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,314,315,314,315,315,315,315,315,315,315, 92, +315,314,315,314,314,315,315,315,315,315,315,315,315,314,314,314, +314,314,314,315,315,315,315,315,315,315,315,315,315, 92, 92,315, /* block 50 */ -306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89, -306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89, -307,307,307,307,307,307,307,308,307,307,307,307,307,307, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, +316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92, +317,317,317,317,317,317,317,318,317,317,317,317,317,317, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 51 */ -309,309,309,309,310,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,309,310,309,309,309,309,309,310,309,310,310,310, -310,310,309,310,310,311,311,311,311,311,311,311, 89, 89, 89, 89, -312,312,312,312,312,312,312,312,312,312,313,313,313,313,313,313, -313,314,314,314,314,314,314,314,314,314,314,309,309,309,309,309, -309,309,309,309,314,314,314,314,314,314,314,314,314, 89, 89, 89, +319,319,319,319,320,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,319,320,319,319,319,319,319,320,319,320,320,320, +320,320,319,320,320,321,321,321,321,321,321,321, 92, 92, 92, 92, +322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323, +323,324,324,324,324,324,324,324,324,324,324,319,319,319,319,319, +319,319,319,319,324,324,324,324,324,324,324,324,324, 92, 92, 92, /* block 52 */ -315,315,316,317,317,317,317,317,317,317,317,317,317,317,317,317, -317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317, -317,316,315,315,315,315,316,316,315,315,316, 89, 89, 89,317,317, -318,318,318,318,318,318,318,318,318,318, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +325,325,326,327,327,327,327,327,327,327,327,327,327,327,327,327, +327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, +327,326,325,325,325,325,326,326,325,325,326,325,326,326,327,327, +328,328,328,328,328,328,328,328,328,328,327,327,327,327,327,327, +329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, +329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329, +329,329,329,329,329,329,330,331,330,330,331,331,331,330,331,330, +330,330,331,331, 92, 92, 92, 92, 92, 92, 92, 92,332,332,332,332, /* block 53 */ -319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319, -319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319, -319,319,319,319,320,320,320,320,320,320,320,320,321,321,321,321, -321,321,321,321,320,320,321,321, 89, 89, 89,322,322,322,322,322, -323,323,323,323,323,323,323,323,323,323, 89, 89, 89,319,319,319, -324,324,324,324,324,324,324,324,324,324,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, -325,325,325,325,325,325,325,325,326,326,326,326,326,326,327,327, +333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, +333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333, +333,333,333,333,334,334,334,334,334,334,334,334,335,335,335,335, +335,335,335,335,334,334,335,335, 92, 92, 92,336,336,336,336,336, +337,337,337,337,337,337,337,337,337,337, 92, 92, 92,333,333,333, +338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,340,340,340,340,340,340,341,341, /* block 54 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84,328, 84, 84, 84, 84, 84, 84, 84,329,329,329,329, 84,329,329, -329,329,328, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +342,342,342,342,342,342,342,342, 92, 92, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87,343, 87, 87, 87, 87, 87, 87, 87,344,344,344,344, 87,344,344, +344,344,343,343, 87,344,344, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 55 */ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 96, 96, 96, 96, 96,330, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, 90, 90, - 90, 90, 14, 14, 14, 14, 96, 96, 96, 96, 96, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14,331,332, 14, 14, 14,333, 14, 14, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 99, 99, 99, 99, 99,345, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, 93, 93, + 93, 93, 84, 84, 84, 84, 93, 93, 93, 93, 93, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20,346,347, 20, 20, 20,348, 20, 20, /* block 56 */ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87, /* block 57 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 58 */ - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 14, 14, 14, 14, 14,334, 14, 14,335, 14, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 20, 20, 20, 20, 20,349, 20, 20,350, 20, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, /* block 59 */ -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89, - 96,336, 96,336, 96,336, 96,336, 89,337, 89,337, 89,337, 89,337, -336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337, -338,338,339,339,339,339,340,340,341,341,342,342,343,343, 89, 89, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92, + 99,351, 99,351, 99,351, 99,351, 92,352, 92,352, 92,352, 92,352, +351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352, +353,353,354,354,354,354,355,355,356,356,357,357,358,358, 92, 92, /* block 60 */ -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344, -336,336, 96,345, 96, 89, 96, 96,337,337,346,346,347, 88,348, 88, - 88, 88, 96,345, 96, 89, 96, 96,349,349,349,349,347, 88, 88, 88, -336,336, 96, 96, 89, 89, 96, 96,337,337,350,350, 89, 88, 88, 88, -336,336, 96, 96, 96,115, 96, 96,337,337,351,351,119, 88, 88, 88, - 89, 89, 96,345, 96, 89, 96, 96,352,352,353,353,347, 88, 88, 89, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359, +351,351, 99,360, 99, 92, 99, 99,352,352,361,361,362, 91,363, 91, + 91, 91, 99,360, 99, 92, 99, 99,364,364,364,364,362, 91, 91, 91, +351,351, 99, 99, 92, 92, 99, 99,352,352,365,365, 92, 91, 91, 91, +351,351, 99, 99, 99,118, 99, 99,352,352,366,366,122, 91, 91, 91, + 92, 92, 99,360, 99, 92, 99, 99,367,367,368,368,362, 91, 91, 92, /* block 61 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,354,354, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,369,369, 16, 16, 7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15, - 2, 2, 2, 2, 2, 2, 2, 2,355,356, 16, 16, 16, 16, 16, 1, + 2, 2, 2, 2, 2, 2, 2, 2,370,371, 16, 16, 16, 16, 16, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11, 11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, - 16, 16, 16, 16, 16, 89, 89, 89, 89, 89, 16, 16, 16, 16, 16, 16, - 17, 82, 89, 89, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 82, + 16, 16, 16, 16, 16, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16, + 17, 84, 92, 92, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 84, /* block 62 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 89, - 82, 82, 82, 82, 82, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 92, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,357,357,357, -357, 84,357,357,357, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,372,372,372, +372, 87,372,372,372, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 63 */ - 13, 13,358, 13, 13, 13, 13,358, 13, 13,359,358,358,358,359,359, -358,358,358,359, 13,358, 13, 13, 13,358,358,358,358,358, 13, 13, - 13, 13, 13, 13,358, 13,360, 13,358, 13,361,362,358,358, 13,359, -358,358,363,358,359,329,329,329,329,359, 13, 13,359,359,358,358, - 6, 6, 6, 6, 6,358,359,359,359,359, 13, 6, 13, 13,364, 13, + 13, 13,373, 13, 13, 13, 13,373, 13, 13,374,373,373,373,374,374, +373,373,373,374, 13,373, 13, 13, 6,373,373,373,373,373, 13, 13, + 13, 13, 13, 13,373, 13,375, 13,373, 13,376,377,373,373, 13,374, +373,373,378,373,374,344,344,344,344,374, 13, 13,374,374,373,373, + 6, 6, 6, 6, 6,373,374,374,374,374, 13, 6, 13, 13,379, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, -366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366, +380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, +381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381, /* block 64 */ -367,367,367, 21, 22,367,367,367,367, 17, 89, 89, 89, 89, 89, 89, +382,382,382, 22, 23,382,382,382,382, 17, 92, 92, 92, 92, 92, 92, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13, 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1778,16 +1827,16 @@ 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, - 6, 6, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 68 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1795,10 +1844,10 @@ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13,368,368,368,368,368,368,368,368,368,368, -368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368, -369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, -369,369,369,369,369,369,369,369,369,369, 17, 17, 17, 17, 17, 17, + 13, 13, 13, 13, 13, 13,383,383,383,383,383,383,383,383,383,383, +383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, +384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, +384,384,384,384,384,384,384,384,384,384, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* block 70 */ @@ -1832,46 +1881,36 @@ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 73 */ + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 89, 13, 89, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - -/* block 74 */ - 89, 13, 13, 13, 13, 89, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 89, 13, - 13, 13, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 89, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, + 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -/* block 75 */ +/* block 74 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 89, 6, 89, 89, 89, + 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -/* block 76 */ -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, +/* block 75 */ +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, +385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385, -/* block 77 */ +/* block 76 */ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -1881,145 +1920,155 @@ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6, -/* block 78 */ +/* block 77 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 78 */ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 79 */ -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, -371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, 89, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, -372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, 89, - 21, 22,373,374,375,376,377, 21, 22, 21, 22, 21, 22,378,379,380, -381, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 82,382,382, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, +386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 92, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 92, + 22, 23,388,389,390,391,392, 22, 23, 22, 23, 22, 23,393,394,395, +396, 20, 22, 23, 20, 22, 23, 20, 20, 20, 20, 20, 84, 84,397,397, /* block 80 */ -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112, -111,112,111,112,383,384,384,384,384,384,384,111,112,111,112,385, -385,385, 89, 89, 89, 89, 89, 89, 89,386,386,386,386,387,386,386, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115, +114,115,114,115,398,399,399,399,399,399,399,114,115,114,115,400, +400,400,114,115, 92, 92, 92, 92, 92,401,401,401,401,402,401,401, /* block 81 */ -388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388, -388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388, -388,388,388,388,388,388, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389, -389,389,389,389,389,389, 89, 89, 89, 89, 89, 89, 89, 89, 89,390, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, +403,403,403,403,403,403, 92,403, 92, 92, 92, 92, 92,403, 92, 92, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, +404,404,404,404,404,404,404,404, 92, 92, 92, 92, 92, 92, 92,405, +406, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,407, /* block 82 */ -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248, 89, 89, 89, 89, 89, 89, 89, 89, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89, -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, +258,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, /* block 83 */ 2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2, - 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 83, - 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 85, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 84 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391, 89,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408, 92,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 85 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, /* block 86 */ -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +408,408,408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, /* block 87 */ - 1, 2, 2, 2, 13,392,329,393, 4, 5, 4, 5, 4, 5, 4, 5, + 1, 2, 2, 2, 13,409,344,410, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5, - 13,393,393,393,393,393,393,393,393,393, 84, 84, 84, 84, 84, 84, - 7, 83, 83, 83, 83, 83, 13, 13,393,393,393,392,329, 2, 13, 13, - 89,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, + 13,410,410,410,410,410,410,410,410,410, 87, 87, 87, 87,411,411, + 7, 85, 85, 85, 85, 85, 13, 13,410,410,410,409,344, 2, 13, 13, + 92,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, /* block 88 */ -394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394, -394,394,394,394,394,394,394, 89, 89, 84, 84, 10, 10,395,395,394, - 7,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396, 2, 83,397,397,396, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412, 92, 92, 87, 87, 10, 10,413,413,412, + 7,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414, 2, 85,415,415,414, /* block 89 */ - 89, 89, 89, 89, 89,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398, 89, 89, - 89,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, + 92, 92, 92, 92, 92,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416, 92, 92, + 92,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, /* block 90 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398, 89, 89, 89, 89, 89, 89, 89, 89, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 91 */ -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 89, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, -399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 13, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, +417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 13, /* block 92 */ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, @@ -2027,551 +2076,661 @@ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, 89, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 92, /* block 93 */ -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400, 13, 13, 13, 13, 13, 13, 13, 13, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, +418,418,418,418,418,418,418,418, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 94 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 95 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, /* block 96 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 97 */ -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,403,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,421,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 98 */ -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, +420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420, /* block 99 */ -402,402,402,402,402,402,402,402,402,402,402,402,402, 89, 89, 89, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404, -404,404,404,404,404,404,404, 89, 89, 89, 89, 89, 89, 89, 89, 89, -405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405, -405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405, -405,405,405,405,405,405,405,405,406,406,406,406,406,406,407,407, +420,420,420,420,420,420,420,420,420,420,420,420,420, 92, 92, 92, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, +422,422,422,422,422,422,422, 92, 92, 92, 92, 92, 92, 92, 92, 92, +423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, +423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, +423,423,423,423,423,423,423,423,424,424,424,424,424,424,425,425, /* block 100 */ -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, /* block 101 */ -408,408,408,408,408,408,408,408,408,408,408,408,409,410,410,410, -408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408, -411,411,411,411,411,411,411,411,411,411,408,408, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, - 89, 89,125,126,125,126,125,126,125,126,125,126,125,126,412,128, -129,129,129,413, 89, 89, 89, 89, 89, 89, 89, 89,128,128,413,331, +426,426,426,426,426,426,426,426,426,426,426,426,427,428,428,428, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +429,429,429,429,429,429,429,429,429,429,426,426, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,430,131, +132,132,132,431,131,131,131,131,131,131,131,131,131,131,431,346, /* block 102 */ -125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126, -125,126,125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, -414,414,414,414,414,414,415,415,415,415,415,415,415,415,415,415, -416,416,417,417,417,417,417,417, 89, 89, 89, 89, 89, 89, 89, 89, +128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129, +128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92,131, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,433, +434,434,435,435,435,435,435,435, 92, 92, 92, 92, 92, 92, 92, 92, /* block 103 */ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 10, 10, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 14, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, - 82, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,418, 21, 22, + 10, 10, 10, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 10, 10, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 20, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, + 84, 20, 20, 20, 20, 20, 20, 20, 20, 22, 23, 22, 23,436, 22, 23, /* block 104 */ - 21, 22, 21, 22, 21, 22, 21, 22, 83, 10, 10, 21, 22, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 45, 45, 45, 45, 45, + 22, 23, 22, 23, 22, 23, 22, 23, 85, 10, 10, 22, 23,437, 20, 92, + 22, 23, 22, 23, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,438, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 84, 84, 20, 14, 14, 14, 14, 14, /* block 105 */ -419,419,420,419,419,419,420,419,419,419,419,420,419,419,419,419, -419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, -419,419,419,421,421,420,420,421,422,422,422,422, 89, 89, 89, 89, - 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 89, 89, 89, 89, 89, 89, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423, -423,423,423,423,424,424,424,424, 89, 89, 89, 89, 89, 89, 89, 89, +439,439,440,439,439,439,440,439,439,439,439,440,439,439,439,439, +439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439, +439,439,439,441,441,440,440,441,442,442,442,442, 92, 92, 92, 92, + 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 92, 92, 92, 92, 92, 92, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443, +443,443,443,443,444,444,444,444, 92, 92, 92, 92, 92, 92, 92, 92, /* block 106 */ -425,425,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,425,425,425,425,425,425,425,425,425,425,425,425, -425,425,425,425,427, 89, 89, 89, 89, 89, 89, 89, 89, 89,428,428, -429,429,429,429,429,429,429,429,429,429, 89, 89, 89, 89, 89, 89, -167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, -167,167,169,169,169,169,169,169,430,430,430,169, 89, 89, 89, 89, +445,445,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,445,445,445,445,445,445,445,445,445,445,445,445, +445,445,445,445,447, 92, 92, 92, 92, 92, 92, 92, 92, 92,448,448, +449,449,449,449,449,449,449,449,449,449, 92, 92, 92, 92, 92, 92, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,176,176,176,176,176,176,178,178,178,176, 92, 92, 92, 92, /* block 107 */ -431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432, -432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, -432,432,432,432,432,432,433,433,433,433,433,433,433,433,434,434, -435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435, -435,435,435,435,435,435,435,436,436,436,436,436,436,436,436,436, -436,436,437,437, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,438, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89, +450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451, +451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, +451,451,451,451,451,451,452,452,452,452,452,452,452,452,453,453, +454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454, +454,454,454,454,454,454,454,455,455,455,455,455,455,455,455,455, +455,455,456,456, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,457, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, /* block 108 */ -439,439,439,440,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441, -441,441,441,439,440,440,439,439,439,439,440,440,439,440,440,440, -440,442,442,442,442,442,442,442,442,442,442,442,442,442, 89,443, -444,444,444,444,444,444,444,444,444,444, 89, 89, 89, 89,442,442, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +458,458,458,459,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,458,459,459,458,458,458,458,459,459,458,459,459,459, +459,461,461,461,461,461,461,461,461,461,461,461,461,461, 92,462, +463,463,463,463,463,463,463,463,463,463, 92, 92, 92, 92,461,461, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 109 */ -445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445, -445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445, -445,445,445,445,445,445,445,445,445,446,446,446,446,446,446,447, -447,446,446,447,447,446,446, 89, 89, 89, 89, 89, 89, 89, 89, 89, -445,445,445,446,445,445,445,445,445,445,445,445,446,447, 89, 89, -448,448,448,448,448,448,448,448,448,448, 89, 89,449,449,449,449, -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -450,238,238,238,238,238,238,243,243,243,238,239, 89, 89, 89, 89, +464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, +464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, +464,464,464,464,464,464,464,464,464,465,465,465,465,465,465,466, +466,465,465,466,466,465,465, 92, 92, 92, 92, 92, 92, 92, 92, 92, +464,464,464,465,464,464,464,464,464,464,464,464,465,466, 92, 92, +467,467,467,467,467,467,467,467,467,467, 92, 92,468,468,468,468, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +469,248,248,248,248,248,248,253,253,253,248,249, 92, 92, 92, 92, /* block 110 */ -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, -452,451,452,452,452,451,451,452,452,451,451,451,451,451,452,452, -451,452,451, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,451,451,453,454,454, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, +471,470,471,471,471,470,470,471,471,470,470,470,470,470,471,471, +470,471,470, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,470,470,472,473,473, +474,474,474,474,474,474,474,474,474,474,474,475,476,476,475,475, +477,477,474,478,478,475,476, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 111 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455, -455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455, -455,455,455,456,456,457,456,456,457,456,456,458,456,457, 89, 89, -459,459,459,459,459,459,459,459,459,459, 89, 89, 89, 89, 89, 89, + 92,258,258,258,258,258,258, 92, 92,258,258,258,258,258,258, 92, + 92,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92, +258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 112 */ -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247, 89, 89, 89, 89,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89, 89, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, +474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, +474,474,474,475,475,476,475,475,476,475,475,477,475,476, 92, 92, +479,479,479,479,479,479,479,479,479,479, 92, 92, 92, 92, 92, 92, /* block 113 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257, 92, 92, 92, 92,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, 92, /* block 114 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, /* block 115 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, /* block 116 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, /* block 117 */ - 14, 14, 14, 14, 14, 14, 14, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89,136,136,136,136,136, 89, 89, 89, 89, 89,141,138,141, -141,141,141,141,141,141,141,141,141,462,141,141,141,141,141,141, -141,141,141,141,141,141,141, 89,141,141,141,141,141, 89,141, 89, -141,141, 89,141,141, 89,141,141,141,141,141,141,141,141,141,141, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 118 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, + 20, 20, 20, 20, 20, 20, 20, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92,139,139,139,139,139, 92, 92, 92, 92, 92,145,142,145, +145,145,145,145,145,145,145,145,145,482,145,145,145,145,145,145, +145,145,145,145,145,145,145, 92,145,145,145,145,145, 92,145, 92, +145,145, 92,145,145, 92,145,145,145,145,145,145,145,145,145,145, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 119 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 120 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147, 4, 5, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 121 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, - 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -147,147,147,147,147,147,147,147,147,147,147,147,144, 13, 89, 89, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152, 4, 5, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, /* block 122 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 89, 89, 89, 89, 89, 89, - 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, - 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11, - 2, 2, 2, 89, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, - 2, 2, 6, 7, 6, 6, 6, 89, 2, 3, 2, 2, 89, 89, 89, 89, -147,147,147,147,147, 89,147,147,147,147,147,147,147,147,147,147, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +152,152,152,152,152,152,152,152,152,152,152,152,149, 13, 92, 92, /* block 123 */ -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147, 89, 89, 16, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 92, 92, 92, 92, 92, 92, + 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, + 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11, + 2, 2, 2, 92, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2, + 2, 2, 6, 7, 6, 6, 6, 92, 2, 3, 2, 2, 92, 92, 92, 92, +152,152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152, /* block 124 */ - 89, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 16, + +/* block 125 */ + 92, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4, - 5, 2, 4, 5, 2, 2,396,396,396,396,396,396,396,396,396,396, - 83,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, - -/* block 125 */ -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396, 83, 83, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89, - 89, 89,247,247,247,247,247,247, 89, 89,247,247,247,247,247,247, - 89, 89,247,247,247,247,247,247, 89, 89,247,247,247, 89, 89, 89, - 3, 3, 6, 10, 13, 3, 3, 89, 13, 6, 6, 6, 6, 13, 13, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 16, 16, 16, 13, 13, 89, 89, + 5, 2, 4, 5, 2, 2,414,414,414,414,414,414,414,414,414,414, + 85,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 126 */ -463,463,463,463,463,463,463,463,463,463,463,463, 89,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463, 89,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463, 89,463,463, 89,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89, -463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414, 85, 85, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, +257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92, + 92, 92,257,257,257,257,257,257, 92, 92,257,257,257,257,257,257, + 92, 92,257,257,257,257,257,257, 92, 92,257,257,257, 92, 92, 92, + 3, 3, 6, 10, 13, 3, 3, 92, 13, 6, 6, 6, 6, 13, 13, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 13, 13, 92, 92, /* block 127 */ -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463, -463,463,463,463,463,463,463,463,463,463,463, 89, 89, 89, 89, 89, +484,484,484,484,484,484,484,484,484,484,484,484, 92,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484, 92,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484, 92,484,484, 92,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, +484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 128 */ - 2, 2, 13, 89, 89, 89, 89, 17, 17, 17, 17, 17, 17, 17, 17, 17, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484, 92, 92, 92, 92, 92, + +/* block 129 */ + 2, 2, 2, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464, -464,464,464,464,464,465,465,465,465,466,466,466,466,466,466,466, + 17, 17, 17, 17, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, +485,485,485,485,485,486,486,486,486,487,487,487,487,487,487,487, -/* block 129 */ -466,466,466,466,466,466,466,466,466,466,465, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 130 */ +487,487,487,487,487,487,487,487,487,487,486, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 89, 89, - -/* block 130 */ -467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467, -467,467,467,467,467,467,467,467,467,467,467,467,467, 89, 89, 89, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468, -468, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 92, 92, /* block 131 */ -469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, -469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, 89, -470,470,470,470, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,472,471,471,471,471,471,471,471,471,472, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488, +488,488,488,488,488,488,488,488,488,488,488,488,488, 92, 92, 92, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, +489, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 132 */ -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473, 89,474, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475, 89, 89, 89, 89,475,475,475,475,475,475,475,475, -476,477,477,477,477,477, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, +490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, 92, +491,491,491,491, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,493,492,492,492,492,492,492,492,492,493, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 133 */ -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, +494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494, +494,494,494,494,494,494,494,494,494,494,494,494,494,494, 92,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496, 92, 92, 92, 92,496,496,496,496,496,496,496,496, +497,498,498,498,498,498, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 134 */ -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481, 89, 89, -482,482,482,482,482,482,482,482,482,482, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, +499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, +499,499,499,499,499,499,499,499,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, +501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, /* block 135 */ -483,483,483,483,483,483, 89, 89,483, 89,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483, 89,483,483, 89, 89, 89,483, 89, 89,483, -484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, -484,484,484,484,484,484, 89,485,486,486,486,486,486,486,486,486, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502, 92, 92, +503,503,503,503,503,503,503,503,503,503, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 136 */ -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,488,488,488,488,488,488, 89, 89, 89,489, -490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, -490,490,490,490,490,490,490,490,490,490, 89, 89, 89, 89, 89,491, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +504,504,504,504,504,504, 92, 92,504, 92,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504, 92,504,504, 92, 92, 92,504, 92, 92,504, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505, 92,506,507,507,507,507,507,507,507,507, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 137 */ -492,493,493,493, 89,493,493, 89, 89, 89, 89, 89,493,493,493,493, -492,492,492,492, 89,492,492,492, 89,492,492,492,492,492,492,492, -492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, -492,492,492,492, 89, 89, 89, 89,493,493,493, 89, 89, 89, 89,493, -494,494,494,494,494,494,494,494, 89, 89, 89, 89, 89, 89, 89, 89, -495,495,495,495,495,495,495,495,495, 89, 89, 89, 89, 89, 89, 89, -496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, -496,496,496,496,496,496,496,496,496,496,496,496,496,497,497,498, +508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508, +508,508,508,508,508,508,509,509,509,509,509,509, 92, 92, 92,510, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511, 92, 92, 92, 92, 92,512, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 138 */ -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499, 89, 89, 89,500,500,500,500,500,500,500, -501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501, -501,501,501,501,501,501, 89, 89,502,502,502,502,502,502,502,502, -503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, -503,503,503, 89, 89, 89, 89, 89,504,504,504,504,504,504,504,504, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514, 92, 92, 92, 92, 92, 92,514,514, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 139 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +515,516,516,516, 92,516,516, 92, 92, 92, 92, 92,516,516,516,516, +515,515,515,515, 92,515,515,515, 92,515,515,515,515,515,515,515, +515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +515,515,515,515, 92, 92, 92, 92,516,516,516, 92, 92, 92, 92,516, +517,517,517,517,517,517,517,517, 92, 92, 92, 92, 92, 92, 92, 92, +518,518,518,518,518,518,518,518,518, 92, 92, 92, 92, 92, 92, 92, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519,519,519,519,519,519,519,519,519,519,519,520,520,521, /* block 140 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, 89, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522, 92, 92, 92,523,523,523,523,523,523,523, +524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +524,524,524,524,524,524, 92, 92,525,525,525,525,525,525,525,525, +526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, +526,526,526, 92, 92, 92, 92, 92,527,527,527,527,527,527,527,527, /* block 141 */ -507,507,508,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -508,508,508,507,507,507,507,508,508,507,507,510,510,511,510,510, -510,510, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 142 */ -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, 92, /* block 143 */ -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, -512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +530,531,530,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +532,532,532,532,532,532,532,532,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,533,533,533,533,533,533,533, 92, 92, + 92, 92,534,534,534,534,534,534,534,534,534,534,534,534,534,534, +534,534,534,534,534,534,535,535,535,535,535,535,535,535,535,535, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 144 */ -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,513, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -514,514,514,514, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +536,536,537,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +537,537,537,536,536,536,536,537,537,536,536,539,539,540,539,539, +539,539, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541, 92, 92, 92, 92, 92, 92, 92, +542,542,542,542,542,542,542,542,542,542, 92, 92, 92, 92, 92, 92, /* block 145 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +543,543,543,544,544,544,544,544,544,544,544,544,544,544,544,544, +544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, +544,544,544,544,544,544,544,543,543,543,543,543,545,543,543,543, +543,543,543,543,543, 92,546,546,546,546,546,546,546,546,546,546, +547,547,547,547, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 146 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +548,548,549,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550, +550,550,550,549,549,549,548,548,548,548,548,548,548,548,548,549, +549,550,550,550,550,551,551,551,551, 92, 92, 92, 92, 92, 92, 92, +552,552,552,552,552,552,552,552,552,552, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, /* block 147 */ +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,554,555,554,555,555, +554,554,554,554,554,554,555,554, 92, 92, 92, 92, 92, 92, 92, 92, +556,556,556,556,556,556,556,556,556,556, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 148 */ +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, + +/* block 149 */ +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 150 */ +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +559,559,559,559, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 151 */ +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, + +/* block 152 */ +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, +560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 153 */ +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, + +/* block 154 */ +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 155 */ +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561, +561,561,561,561,561, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +561,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, +562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 92, + +/* block 156 */ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,563, +563,563,563,564,564,564,564,564,564,564,564,564,564,564,564,564, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 157 */ +414,412, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 158 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -2579,211 +2738,321 @@ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 148 */ +/* block 159 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13,328,328, 84, 84, 84, 13, 13, 13,328,328,328, -328,328,328, 16, 16, 16, 16, 16, 16, 16, 16, 84, 84, 84, 84, 84, + 13, 13, 13, 13, 13,343,343, 87, 87, 87, 13, 13, 13,343,343,343, +343,343,343, 16, 16, 16, 16, 16, 16, 16, 16, 87, 87, 87, 87, 87, -/* block 149 */ - 84, 84, 84, 13, 13, 84, 84, 84, 84, 84, 84, 84, 13, 13, 13, 13, +/* block 160 */ + 87, 87, 87, 13, 13, 87, 87, 87, 87, 87, 87, 87, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 84, 84, 84, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 87, 87, 87, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 150 */ -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466, -466,466,516,516,516,466, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 161 */ +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +487,487,565,565,565,487, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 151 */ +/* block 162 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 152 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359, -359,359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +/* block 163 */ +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, +374,374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -/* block 153 */ -358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358, 89,358,358, - 89, 89,358, 89, 89,358,358, 89, 89,358,358,358,358, 89,358,358, -358,358,358,358,358,358,359,359,359,359, 89,359, 89,359,359,359, -359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +/* block 164 */ +373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373, 92,373,373, + 92, 92,373, 92, 92,373,373, 92, 92,373,373,373,373, 92,373,373, +373,373,373,373,373,373,374,374,374,374, 92,374, 92,374,374,374, +374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, -/* block 154 */ -359,359,359,359,358,358, 89,358,358,358,358, 89, 89,358,358,358, -358,358,358,358,358, 89,358,358,358,358,358,358,358, 89,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,358,358, 89,358,358,358,358, 89, -358,358,358,358,358, 89,358, 89, 89, 89,358,358,358,358,358,358, -358, 89,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +/* block 165 */ +374,374,374,374,373,373, 92,373,373,373,373, 92, 92,373,373,373, +373,373,373,373,373, 92,373,373,373,373,373,373,373, 92,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,373,373, 92,373,373,373,373, 92, +373,373,373,373,373, 92,373, 92, 92, 92,373,373,373,373,373,373, +373, 92,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -/* block 155 */ -358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +/* block 166 */ +373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, -/* block 156 */ -359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +/* block 167 */ +374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -/* block 157 */ -358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359, 89, 89,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358, 6,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359, 6,359,359,359,359, -359,359,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358, 6,359,359,359,359, +/* block 168 */ +373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374, 92, 92,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373, 6,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374, 6,374,374,374,374, +374,374,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373, 6,374,374,374,374, -/* block 158 */ -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359, 6,359,359,359,359,359,359,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358, 6,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 6, -359,359,359,359,359,359,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 6, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +/* block 169 */ +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374, 6,374,374,374,374,374,374,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373, 6,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 6, +374,374,374,374,374,374,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 6, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, -/* block 159 */ -359,359,359,359,359,359,359,359,359, 6,359,359,359,359,359,359, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358, 6,359,359,359,359,359,359, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359, 6,359,359,359,359,359,359,358,359, 89, 89, 8, 8, +/* block 170 */ +374,374,374,374,374,374,374,374,374, 6,374,374,374,374,374,374, +373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373, 6,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374, 6,374,374,374,374,374,374,373,374, 92, 92, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -/* block 160 */ +/* block 171 */ +152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, + 92,152,152, 92,152, 92, 92,152, 92,152,152,152,152,152,152,152, +152,152,152, 92,152,152,152,152, 92,152, 92,152, 92, 92, 92, 92, + 92, 92,152, 92, 92, 92, 92,152, 92,152, 92,152, 92,152,152,152, + 92,152,152, 92,152, 92, 92,152, 92,152, 92,152, 92,152, 92,152, + 92,152,152, 92,152, 92, 92,152,152,152,152, 92,152,152,152,152, +152,152,152, 92,152,152,152,152, 92,152,152,152,152, 92,152, 92, + +/* block 172 */ +152,152,152,152,152,152,152,152,152,152, 92,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, + 92,152,152,152, 92,152,152,152,152,152, 92,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +147,147, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 173 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -/* block 161 */ +/* block 174 */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 162 */ - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89, +/* block 175 */ + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, - 89, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13, - 89, 89, 13, 89, 89, 89, 13, 89, 89, 89, 13, 13, 13, 13, 13, 89, - 89, 89, 89, 89, 89, 89, 89, 13, 89, 89, 89, 89, 89, 89, 89, 13, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13, 13, 89, 89, 13, -/* block 163 */ - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 13, 13, 13, 89, 89, - 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 176 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -/* block 164 */ -517, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 177 */ +566, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 165 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 178 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, -/* block 166 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 179 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 167 */ -401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, -401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 180 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, + 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -/* block 168 */ - 89, 16, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 181 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 92, 92, 92, + +/* block 182 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 183 */ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, + +/* block 184 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 185 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 186 */ + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 187 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 188 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, + +/* block 189 */ +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + +/* block 190 */ + 92, 16, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, @@ -2791,35 +3060,35 @@ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -/* block 169 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - -/* block 170 */ - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, +/* block 191 */ + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + +/* block 192 */ + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, -/* block 171 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461, 89, 89, +/* block 193 */ +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +481,481,481,481,481,481,481,481,481,481,481,481,481,481, 92, 92, }; diff -Nru pcre3-8.12/pcre_valid_utf8.c pcre3-8.31/pcre_valid_utf8.c --- pcre3-8.12/pcre_valid_utf8.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcre_valid_utf8.c 2011-12-28 16:57:51.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -54,127 +54,246 @@ *************************************************/ /* This function is called (optionally) at the start of compile or match, to -validate that a supposed UTF-8 string is actually valid. The early check means +check that a supposed UTF-8 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check -can be turned off for maximum performance, but the consequences of supplying -an invalid string are then undefined. +can be turned off for maximum performance, but the consequences of supplying an +invalid string are then undefined. Originally, this function checked according to RFC 2279, allowing for values in the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in the canonical format. Once somebody had pointed out RFC 3629 to me (it obsoletes 2279), additional restrictions were applied. The values are now limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the -subrange 0xd000 to 0xdfff is excluded. +subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte +characters is still checked. + +From release 8.13 more information about the details of the error are passed +back in the returned value: + +PCRE_UTF8_ERR0 No error +PCRE_UTF8_ERR1 Missing 1 byte at the end of the string +PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string +PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string +PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string +PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string +PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80 +PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80 +PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80 +PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629 +PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629 +PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted +PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted +PCRE_UTF8_ERR15 Overlong 2-byte sequence +PCRE_UTF8_ERR16 Overlong 3-byte sequence +PCRE_UTF8_ERR17 Overlong 4-byte sequence +PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur) +PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur) +PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character) +PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff Arguments: string points to the string length length of string, or -1 if the string is zero-terminated + errp pointer to an error position offset variable -Returns: < 0 if the string is a valid UTF-8 string - >= 0 otherwise; the value is the offset of the bad byte - -Bad bytes can be: - - . An isolated byte whose most significant bits are 0x80, because this - can only correctly appear within a UTF-8 character; - - . A byte whose most significant bits are 0xc0, but whose other bits indicate - that there are more than 3 additional bytes (i.e. an RFC 2279 starting - byte, which is no longer valid under RFC 3629); - - . - -The returned offset may also be equal to the length of the string; this means -that one or more bytes is missing from the final UTF-8 character. +Returns: = 0 if the string is a valid UTF-8 string + > 0 otherwise, setting the offset of the bad character */ int -_pcre_valid_utf8(USPTR string, int length) +PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset) { -#ifdef SUPPORT_UTF8 -register USPTR p; +#ifdef SUPPORT_UTF +register PCRE_PUCHAR p; if (length < 0) { for (p = string; *p != 0; p++); - length = p - string; + length = (int)(p - string); } for (p = string; length-- > 0; p++) { - register int ab; - register int c = *p; - if (c < 128) continue; - if (c < 0xc0) return p - string; - ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */ - if (ab > 3) return p - string; /* Too many for RFC 3629 */ - if (length < ab) return p + 1 + length - string; /* Missing bytes */ - length -= ab; + register int ab, c, d; + + c = *p; + if (c < 128) continue; /* ASCII character */ + + if (c < 0xc0) /* Isolated 10xx xxxx byte */ + { + *erroroffset = (int)(p - string); + return PCRE_UTF8_ERR20; + } + + if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */ + { + *erroroffset = (int)(p - string); + return PCRE_UTF8_ERR21; + } + + ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */ + if (length < ab) + { + *erroroffset = (int)(p - string); /* Missing bytes */ + return ab - length; /* Codes ERR1 to ERR5 */ + } + length -= ab; /* Length remaining */ /* Check top bits in the second byte */ - if ((*(++p) & 0xc0) != 0x80) return p - string; - /* Check for overlong sequences for each different length, and for the - excluded range 0xd000 to 0xdfff. */ + if (((d = *(++p)) & 0xc0) != 0x80) + { + *erroroffset = (int)(p - string) - 1; + return PCRE_UTF8_ERR6; + } + + /* For each length, check that the remaining bytes start with the 0x80 bit + set and not the 0x40 bit. Then check for an overlong sequence, and for the + excluded range 0xd800 to 0xdfff. */ switch (ab) { - /* Check for xx00 000x (overlong sequence) */ + /* 2-byte character. No further bytes to check for 0x80. Check first byte + for for xx00 000x (overlong sequence). */ - case 1: - if ((c & 0x3e) == 0) return p - string; - continue; /* We know there aren't any more bytes to check */ + case 1: if ((c & 0x3e) == 0) + { + *erroroffset = (int)(p - string) - 1; + return PCRE_UTF8_ERR15; + } + break; - /* Check for 1110 0000, xx0x xxxx (overlong sequence) or - 1110 1101, 1010 xxxx (0xd000 - 0xdfff) */ + /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes + for 1110 0000, xx0x xxxx (overlong sequence) or + 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */ case 2: - if ((c == 0xe0 && (*p & 0x20) == 0) || - (c == 0xed && *p >= 0xa0)) - return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if (c == 0xe0 && (d & 0x20) == 0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR16; + } + if (c == 0xed && d >= 0xa0) + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR14; + } break; - /* Check for 1111 0000, xx00 xxxx (overlong sequence) or - greater than 0x0010ffff (f4 8f bf bf) */ + /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 + bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a + character greater than 0x0010ffff (f4 8f bf bf) */ case 3: - if ((c == 0xf0 && (*p & 0x30) == 0) || - (c > 0xf4 ) || - (c == 0xf4 && *p > 0x8f)) - return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if (c == 0xf0 && (d & 0x30) == 0) + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR17; + } + if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR13; + } break; -#if 0 - /* These cases can no longer occur, as we restrict to a maximum of four - bytes nowadays. Leave the code here in case we ever want to add an option - for longer sequences. */ + /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be + rejected by the length test below. However, we do the appropriate tests + here so that overlong sequences get diagnosed, and also in case there is + ever an option for handling these larger code points. */ + + /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for + 1111 1000, xx00 0xxx */ - /* Check for 1111 1000, xx00 0xxx */ case 4: - if (c == 0xf8 && (*p & 0x38) == 0) return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR9; + } + if (c == 0xf8 && (d & 0x38) == 0) + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR18; + } break; - /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ + /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for + 1111 1100, xx00 00xx. */ + case 5: - if (c == 0xfe || c == 0xff || - (c == 0xfc && (*p & 0x3c) == 0)) return p - string; + if ((*(++p) & 0xc0) != 0x80) /* Third byte */ + { + *erroroffset = (int)(p - string) - 2; + return PCRE_UTF8_ERR7; + } + if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ + { + *erroroffset = (int)(p - string) - 3; + return PCRE_UTF8_ERR8; + } + if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ + { + *erroroffset = (int)(p - string) - 4; + return PCRE_UTF8_ERR9; + } + if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ + { + *erroroffset = (int)(p - string) - 5; + return PCRE_UTF8_ERR10; + } + if (c == 0xfc && (d & 0x3c) == 0) + { + *erroroffset = (int)(p - string) - 5; + return PCRE_UTF8_ERR19; + } break; -#endif - } - /* Check for valid bytes after the 2nd, if any; all must start 10 */ - while (--ab > 0) + /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are + excluded by RFC 3629. The pointer p is currently at the last byte of the + character. */ + + if (ab > 3) { - if ((*(++p) & 0xc0) != 0x80) return p - string; + *erroroffset = (int)(p - string) - ab; + return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; } } -#else + +#else /* SUPPORT_UTF */ (void)(string); /* Keep picky compilers happy */ (void)(length); #endif -return -1; +return PCRE_UTF8_ERR0; /* This indicates success */ } /* End of pcre_valid_utf8.c */ diff -Nru pcre3-8.12/pcre_version.c pcre3-8.31/pcre_version.c --- pcre3-8.12/pcre_version.c 2008-07-09 15:51:30.000000000 +0000 +++ pcre3-8.31/pcre_version.c 2011-12-28 16:57:50.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2008 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -79,8 +79,13 @@ pre-processor time. This hack uses a standard trick for avoiding calling the STRING macro with an empty argument when doing the test. */ +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION pcre_version(void) +#else +PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION +pcre16_version(void) +#endif { return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)? XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) : diff -Nru pcre3-8.12/pcre_xclass.c pcre3-8.31/pcre_xclass.c --- pcre3-8.12/pcre_xclass.c 2010-06-03 19:15:23.000000000 +0000 +++ pcre3-8.31/pcre_xclass.c 2011-12-28 16:57:58.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -64,39 +64,63 @@ */ BOOL -_pcre_xclass(int c, const uschar *data) +PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf) { int t; BOOL negated = (*data & XCL_NOT) != 0; +(void)utf; +#ifdef COMPILE_PCRE8 +/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ +utf = TRUE; +#endif + /* Character values < 256 are matched against a bitmap, if one is present. If not, we still carry on, because there may be ranges that start below 256 in the additional data. */ if (c < 256) { - if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0) - return !negated; /* char found */ + if ((*data & XCL_MAP) != 0 && + (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0) + return !negated; /* char found */ } /* First skip the bit map if present. Then match against the list of Unicode properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ -if ((*data++ & XCL_MAP) != 0) data += 32; +if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar); while ((t = *data++) != XCL_END) { int x, y; if (t == XCL_SINGLE) { - GETCHARINC(x, data); +#ifdef SUPPORT_UTF + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + } + else +#endif + x = *data++; if (c == x) return !negated; } else if (t == XCL_RANGE) { - GETCHARINC(x, data); - GETCHARINC(y, data); +#ifdef SUPPORT_UTF + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + GETCHARINC(y, data); /* macro generates multiple statements */ + } + else +#endif + { + x = *data++; + y = *data++; + } if (c >= x && c <= y) return !negated; } @@ -117,7 +141,7 @@ break; case PT_GC: - if ((data[1] == _pcre_ucp_gentype[prop->chartype]) == (t == XCL_PROP)) + if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP)) return !negated; break; @@ -130,28 +154,28 @@ break; case PT_ALNUM: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N) == (t == XCL_PROP)) + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP)) return !negated; break; case PT_SPACE: /* Perl space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_PXSPACE: /* POSIX space */ - if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP)) return !negated; break; case PT_WORD: - if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || - _pcre_ucp_gentype[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) + if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || + PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == (t == XCL_PROP)) return !negated; break; diff -Nru pcre3-8.12/pcrecpp.cc pcre3-8.31/pcrecpp.cc --- pcre3-8.12/pcrecpp.cc 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/pcrecpp.cc 2012-01-15 18:00:31.000000000 +0000 @@ -37,6 +37,7 @@ #include #include #include /* for SHRT_MIN, USHRT_MAX, etc */ +#include /* for memcpy */ #include #include #include @@ -79,12 +80,6 @@ // If the user doesn't ask for any options, we just use this one static RE_Options default_options; -// PCRE6.x compatible API -void RE::Init(const char *c_pat, const RE_Options* options) { - const string cxx_pat(c_pat); - Init(cxx_pat, options); -} - void RE::Init(const string& pat, const RE_Options* options) { pattern_ = pat; if (options == NULL) { @@ -389,7 +384,6 @@ int vec[kVecSize]; string out; int start = 0; - int lastend = -1; bool last_match_was_empty_string = false; while (start <= static_cast(str->length())) { @@ -445,7 +439,6 @@ out.append(*str, start, matchstart - start); Rewrite(&out, rewrite, *str, vec, matches); start = matchend; - lastend = matchend; count++; last_match_was_empty_string = (matchstart == matchend); } diff -Nru pcre3-8.12/pcrecpp.h pcre3-8.31/pcrecpp.h --- pcre3-8.12/pcrecpp.h 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/pcrecpp.h 2010-01-02 16:25:49.000000000 +0000 @@ -658,8 +658,6 @@ private: void Init(const string& pattern, const RE_Options* options); - // Old version from PCRE 6.x, for compatibility - void Init(const char *pattern, const RE_Options* options); void Cleanup(); // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with diff -Nru pcre3-8.12/pcrecpp_unittest.cc pcre3-8.31/pcrecpp_unittest.cc --- pcre3-8.12/pcrecpp_unittest.cc 2010-01-02 16:29:56.000000000 +0000 +++ pcre3-8.31/pcrecpp_unittest.cc 2011-08-21 13:44:57.000000000 +0000 @@ -38,6 +38,7 @@ #endif #include +#include /* for memset and strcmp */ #include #include #include "pcrecpp.h" @@ -412,7 +413,7 @@ } static void TestMatchNumberPeculiarity() { - printf("Testing match-number peculiaraity\n"); + printf("Testing match-number peculiarity\n"); string word1; string word2; @@ -832,6 +833,7 @@ return 0; } + printf("PCRE C++ wrapper tests\n"); printf("Testing FullMatch\n"); int i; diff -Nru pcre3-8.12/pcredemo.c pcre3-8.31/pcredemo.c --- pcre3-8.12/pcredemo.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcredemo.c 2012-02-29 08:56:17.000000000 +0000 @@ -248,7 +248,7 @@ * more than one byte. * * * * However, there is a complication concerned with newlines. When the * -* newline convention is such that CRLF is a valid newline, we want must * +* newline convention is such that CRLF is a valid newline, we must * * advance by two characters rather than one. The newline convention can * * be set in the regex by (*CR), etc.; if not, we must find the default. * *************************************************************************/ diff -Nru pcre3-8.12/pcregrep.c pcre3-8.31/pcregrep.c --- pcre3-8.12/pcregrep.c 2011-01-15 11:25:12.000000000 +0000 +++ pcre3-8.31/pcregrep.c 2012-06-02 10:55:16.000000000 +0000 @@ -6,7 +6,7 @@ its pattern matching. On a Unix or Win32 system it can recurse into directories. - Copyright (c) 1997-2011 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -74,9 +74,9 @@ #define OFFSET_SIZE 99 #if BUFSIZ > 8192 -#define MBUFTHIRD BUFSIZ +#define PATBUFSIZE BUFSIZ #else -#define MBUFTHIRD 8192 +#define PATBUFSIZE 8192 #endif /* Values for the "filenames" variable, which specifies options for file name @@ -104,6 +104,10 @@ enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF }; +/* Binary file options */ + +enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT }; + /* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some environments), a warning is issued if the value of fwrite() is ignored. Unfortunately, casting to (void) does not suppress the warning. To get round @@ -135,6 +139,7 @@ static char *colour_option = NULL; static char *dee_option = NULL; static char *DEE_option = NULL; +static char *main_buffer = NULL; static char *newline = NULL; static char *pattern_filename = NULL; static char *stdin_name = (char *)"(standard input)"; @@ -146,6 +151,7 @@ static pcre **pattern_list = NULL; static pcre_extra **hints_list = NULL; +static char *file_list = NULL; static char *include_pattern = NULL; static char *exclude_pattern = NULL; static char *include_dir_pattern = NULL; @@ -158,7 +164,10 @@ static int after_context = 0; static int before_context = 0; +static int binary_files = BIN_BINARY; static int both_context = 0; +static int bufthird = PCREGREP_BUFSIZE; +static int bufsize = 3*PCREGREP_BUFSIZE; static int dee_action = dee_READ; static int DEE_action = DEE_READ; static int error_count = 0; @@ -166,6 +175,12 @@ static int only_matching = -1; static int process_options = 0; +#ifdef SUPPORT_PCREGREP_JIT +static int study_options = PCRE_STUDY_JIT_COMPILE; +#else +static int study_options = 0; +#endif + static unsigned long int match_limit = 0; static unsigned long int match_limit_recursion = 0; @@ -187,7 +202,7 @@ /* Structure for options and list of them */ enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER, - OP_OP_NUMBER, OP_PATLIST }; + OP_OP_NUMBER, OP_PATLIST, OP_BINFILES }; typedef struct option_item { int type; @@ -214,12 +229,19 @@ #define N_LBUFFER (-12) #define N_M_LIMIT (-13) #define N_M_LIMIT_REC (-14) +#define N_BUFSIZE (-15) +#define N_NOJIT (-16) +#define N_FILE_LIST (-17) +#define N_BINARY_FILES (-18) static option_item optionlist[] = { - { OP_NODATA, N_NULL, NULL, "", " terminate options" }, + { OP_NODATA, N_NULL, NULL, "", "terminate options" }, { OP_NODATA, N_HELP, NULL, "help", "display this help and exit" }, { OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" }, + { OP_NODATA, 'a', NULL, "text", "treat binary files as text" }, { OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" }, + { OP_BINFILES, N_BINARY_FILES, NULL, "binary-files=word", "set treatment of binary files" }, + { OP_NUMBER, N_BUFSIZE,&bufthird, "buffer-size=number", "set processing buffer size parameter" }, { OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" }, { OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" }, { OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" }, @@ -229,10 +251,17 @@ { OP_PATLIST, 'e', NULL, "regex(p)=pattern", "specify pattern (may be used more than once)" }, { OP_NODATA, 'F', NULL, "fixed-strings", "patterns are sets of newline-separated strings" }, { OP_STRING, 'f', &pattern_filename, "file=path", "read patterns from file" }, + { OP_STRING, N_FILE_LIST, &file_list, "file-list=path","read files to search from file" }, { OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" }, { OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" }, { OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" }, + { OP_NODATA, 'I', NULL, "", "treat binary files as not matching (ignore)" }, { OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" }, +#ifdef SUPPORT_PCREGREP_JIT + { OP_NODATA, N_NOJIT, NULL, "no-jit", "do not use just-in-time compiler optimization" }, +#else + { OP_NODATA, N_NOJIT, NULL, "no-jit", "ignored: this pcregrep does not support JIT" }, +#endif { OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" }, { OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" }, { OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" }, @@ -310,8 +339,9 @@ { if (resource_error) { - fprintf(stderr, "pcregrep: Error %d or %d means that a resource limit " - "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT); + fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit " + "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT, + PCRE_ERROR_JIT_STACKLIMIT); fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n"); } @@ -607,7 +637,7 @@ Returns: the number of characters read, zero at end of file */ -static int +static unsigned int read_one_line(char *buffer, int length, FILE *f) { int c; @@ -634,7 +664,8 @@ endptr end of available data lenptr where to put the length of the eol sequence -Returns: pointer to the last byte of the line, including the newline byte(s) +Returns: pointer after the last byte of the line, + including the newline byte(s) */ static char * @@ -935,10 +966,11 @@ to find all possible matches. Arguments: - matchptr the start of the subject - length the length of the subject to match - offsets the offets vector to fill in - mrc address of where to put the result of pcre_exec() + matchptr the start of the subject + length the length of the subject to match + startoffset where to start matching + offsets the offets vector to fill in + mrc address of where to put the result of pcre_exec() Returns: TRUE if there was a match FALSE if there was no match @@ -946,7 +978,8 @@ */ static BOOL -match_patterns(char *matchptr, size_t length, int *offsets, int *mrc) +match_patterns(char *matchptr, size_t length, int startoffset, int *offsets, + int *mrc) { int i; size_t slen = length; @@ -958,8 +991,8 @@ } for (i = 0; i < pattern_count; i++) { - *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length, 0, - PCRE_NOTEMPTY, offsets, OFFSET_SIZE); + *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length, + startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE); if (*mrc >= 0) return TRUE; if (*mrc == PCRE_ERROR_NOMATCH) continue; fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc); @@ -967,7 +1000,8 @@ fprintf(stderr, "%s", msg); FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */ fprintf(stderr, "\n\n"); - if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT) + if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT || + *mrc == PCRE_ERROR_JIT_STACKLIMIT) resource_error = TRUE; if (error_count++ > 20) { @@ -987,7 +1021,7 @@ *************************************************/ /* This is called from grep_or_recurse() below. It uses a buffer that is three -times the value of MBUFTHIRD. The matching point is never allowed to stray into +times the value of bufthird. The matching point is never allowed to stray into the top third of the buffer, thus keeping more of the file available for context printing or for multiline scanning. For large files, the pointer will be in the middle third most of the time, so the bottom third is available for @@ -998,17 +1032,19 @@ the gzFile pointer when reading is via libz the BZFILE pointer when reading is via libbz2 frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2 + filename the file name or NULL (for errors) printname the file name if it is to be printed for each match or NULL if the file name is not to be printed it cannot be NULL if filenames[_nomatch]_only is set Returns: 0 if there was at least one match 1 otherwise (no matches) - 2 if there is a read error on a .bz2 file + 2 if an overlong line is encountered + 3 if there is a read error on a .bz2 file */ static int -pcregrep(void *handle, int frtype, char *printname) +pcregrep(void *handle, int frtype, char *filename, char *printname) { int rc = 1; int linenumber = 1; @@ -1017,10 +1053,10 @@ int filepos = 0; int offsets[OFFSET_SIZE]; char *lastmatchrestart = NULL; -char buffer[3*MBUFTHIRD]; -char *ptr = buffer; +char *ptr = main_buffer; char *endptr; size_t bufflength; +BOOL binary = FALSE; BOOL endhyphenpending = FALSE; BOOL input_line_buffered = line_buffered; FILE *in = NULL; /* Ensure initialized */ @@ -1043,7 +1079,7 @@ if (frtype == FR_LIBZ) { ingz = (gzFile)handle; - bufflength = gzread (ingz, buffer, 3*MBUFTHIRD); + bufflength = gzread (ingz, main_buffer, bufsize); } else #endif @@ -1052,7 +1088,7 @@ if (frtype == FR_LIBBZ2) { inbz2 = (BZFILE *)handle; - bufflength = BZ2_bzread(inbz2, buffer, 3*MBUFTHIRD); + bufflength = BZ2_bzread(inbz2, main_buffer, bufsize); if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */ } /* without the cast it is unsigned. */ else @@ -1062,11 +1098,22 @@ in = (FILE *)handle; if (is_file_tty(in)) input_line_buffered = TRUE; bufflength = input_line_buffered? - read_one_line(buffer, 3*MBUFTHIRD, in) : - fread(buffer, 1, 3*MBUFTHIRD, in); + read_one_line(main_buffer, bufsize, in) : + fread(main_buffer, 1, bufsize, in); } -endptr = buffer + bufflength; +endptr = main_buffer + bufflength; + +/* Unless binary-files=text, see if we have a binary file. This uses the same +rule as GNU grep, namely, a search for a binary zero byte near the start of the +file. */ + +if (binary_files != BIN_TEXT) + { + binary = + memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL; + if (binary && binary_files == BIN_NOMATCH) return 1; + } /* Loop while the current pointer is not at the end of the file. For large files, endptr will be at the end of the buffer when we are in the middle of the @@ -1077,6 +1124,7 @@ { int endlinelength; int mrc = 0; + int startoffset = 0; BOOL match; char *matchptr = ptr; char *t = ptr; @@ -1094,6 +1142,20 @@ linelength = t - ptr - endlinelength; length = multiline? (size_t)(endptr - ptr) : linelength; + /* Check to see if the line we are looking at extends right to the very end + of the buffer without a line terminator. This means the line is too long to + handle. */ + + if (endlinelength == 0 && t == main_buffer + bufsize) + { + fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n" + "pcregrep: check the --buffer-size option\n", + linenumber, + (filename == NULL)? "" : " of file ", + (filename == NULL)? "" : filename); + return 2; + } + /* Extra processing for Jeffrey Friedl's debugging. */ #ifdef JFRIEDL_DEBUG @@ -1153,7 +1215,7 @@ than NOMATCH. This code is in a subroutine so that it can be re-used for finding subsequent matches when colouring matched lines. */ - match = match_patterns(matchptr, length, offsets, &mrc); + match = match_patterns(matchptr, length, startoffset, offsets, &mrc); /* If it's a match or a not-match (as required), do what's wanted. */ @@ -1169,6 +1231,16 @@ if (count_only) count++; + /* When handling a binary file and binary-files==binary, the "binary" + variable will be set true (it's false in all other cases). In this + situation we just want to output the file name. No need to scan further. */ + + else if (binary) + { + fprintf(stdout, "Binary file %s matches\n", filename); + return 0; + } + /* If all we want is a file name, there is no need to scan any more lines in the file. */ @@ -1186,10 +1258,10 @@ captured portion of it, as long as this string is not empty, and the --file-offsets and --line-offsets options output offsets for the matching substring (they both force --only-matching = 0). None of these options - prints any context. Afterwards, adjust the start and length, and then jump - back to look for further matches in the same line. If we are in invert - mode, however, nothing is printed and we do not restart - this could still - be useful because the return code is set. */ + prints any context. Afterwards, adjust the start and then jump back to look + for further matches in the same line. If we are in invert mode, however, + nothing is printed and we do not restart - this could still be useful + because the return code is set. */ else if (only_matching >= 0) { @@ -1216,11 +1288,10 @@ } } else if (printname != NULL || number) fprintf(stdout, "\n"); - matchptr += offsets[1]; - length -= offsets[1]; match = FALSE; if (line_buffered) fflush(stdout); - rc = 0; /* Had some success */ + rc = 0; /* Had some success */ + startoffset = offsets[1]; /* Restart after the match */ goto ONLY_MATCHING_RESTART; } } @@ -1279,11 +1350,11 @@ int linecount = 0; char *p = ptr; - while (p > buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && + while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) && linecount < before_context) { linecount++; - p = previous_line(p, buffer); + p = previous_line(p, main_buffer); } if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted) @@ -1353,19 +1424,17 @@ if (do_colour && !invert) { int plength; - int last_offset = 0; FWRITE(ptr, 1, offsets[0], stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "%c[00m", 0x1b); for (;;) { - last_offset += offsets[1]; - matchptr += offsets[1]; - length -= offsets[1]; - if (last_offset >= linelength + endlinelength || - !match_patterns(matchptr, length, offsets, &mrc)) break; - FWRITE(matchptr, 1, offsets[0], stdout); + startoffset = offsets[1]; + if (startoffset >= (int)linelength + endlinelength || + !match_patterns(matchptr, length, startoffset, offsets, &mrc)) + break; + FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout); fprintf(stdout, "%c[%sm", 0x1b, colour_string); FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout); fprintf(stdout, "%c[00m", 0x1b); @@ -1375,9 +1444,8 @@ and its line-ending characters (if they matched the pattern), so there may be no more to print. */ - plength = (linelength + endlinelength) - last_offset; - if (plength > 0) - FWRITE(ptr + last_offset, 1, plength, stdout); + plength = (int)((linelength + endlinelength) - startoffset); + if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout); } /* Not colouring; no need to search for further matches */ @@ -1426,9 +1494,9 @@ /* If input is line buffered, and the buffer is not yet full, read another line and add it into the buffer. */ - if (input_line_buffered && bufflength < sizeof(buffer)) + if (input_line_buffered && bufflength < (size_t)bufsize) { - int add = read_one_line(ptr, sizeof(buffer) - (ptr - buffer), in); + int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in); bufflength += add; endptr += add; } @@ -1438,11 +1506,11 @@ 1/3 and refill it. Before we do this, if some unprinted "after" lines are about to be lost, print them. */ - if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD) + if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird) { if (after_context > 0 && lastmatchnumber > 0 && - lastmatchrestart < buffer + MBUFTHIRD) + lastmatchrestart < main_buffer + bufthird) { do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); lastmatchnumber = 0; @@ -1450,32 +1518,32 @@ /* Now do the shuffle */ - memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD); - ptr -= MBUFTHIRD; + memmove(main_buffer, main_buffer + bufthird, 2*bufthird); + ptr -= bufthird; #ifdef SUPPORT_LIBZ if (frtype == FR_LIBZ) - bufflength = 2*MBUFTHIRD + - gzread (ingz, buffer + 2*MBUFTHIRD, MBUFTHIRD); + bufflength = 2*bufthird + + gzread (ingz, main_buffer + 2*bufthird, bufthird); else #endif #ifdef SUPPORT_LIBBZ2 if (frtype == FR_LIBBZ2) - bufflength = 2*MBUFTHIRD + - BZ2_bzread(inbz2, buffer + 2*MBUFTHIRD, MBUFTHIRD); + bufflength = 2*bufthird + + BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird); else #endif - bufflength = 2*MBUFTHIRD + + bufflength = 2*bufthird + (input_line_buffered? - read_one_line(buffer + 2*MBUFTHIRD, MBUFTHIRD, in) : - fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in)); - endptr = buffer + bufflength; + read_one_line(main_buffer + 2*bufthird, bufthird, in) : + fread(main_buffer + 2*bufthird, 1, bufthird, in)); + endptr = main_buffer + bufflength; /* Adjust any last match point */ - if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD; + if (lastmatchnumber > 0) lastmatchrestart -= bufthird; } } /* Loop through the whole file */ @@ -1539,7 +1607,6 @@ int rc = 1; int sep; int frtype; -int pathlen; void *handle; FILE *in = NULL; /* Ensure initialized */ @@ -1551,11 +1618,15 @@ BZFILE *inbz2 = NULL; #endif +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 +int pathlen; +#endif + /* If the file name is "-" we scan stdin */ if (strcmp(pathname, "-") == 0) { - return pcregrep(stdin, FR_PLAIN, + return pcregrep(stdin, FR_PLAIN, stdin_name, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? stdin_name : NULL); } @@ -1630,7 +1701,9 @@ argument at top level, we don't show the file name, unless we are only showing the file name, or the filename was forced (-H). */ +#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2 pathlen = (int)(strlen(pathname)); +#endif /* Open using zlib if it is supported and the file name ends with .gz. */ @@ -1687,7 +1760,7 @@ /* Now grep the file */ -rc = pcregrep(handle, frtype, (filenames > FN_DEFAULT || +rc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL); /* Close in an appropriate manner. */ @@ -1698,14 +1771,14 @@ else #endif -/* If it is a .bz2 file and the result is 2, it means that the first attempt to +/* If it is a .bz2 file and the result is 3, it means that the first attempt to read failed. If the error indicates that the file isn't in fact bzipped, try again as a normal file. */ #ifdef SUPPORT_LIBBZ2 if (frtype == FR_LIBBZ2) { - if (rc == 2) + if (rc == 3) { int errnum; const char *err = BZ2_bzerror(inbz2, &errnum); @@ -1717,6 +1790,7 @@ else if (!silent) fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n", pathname, err); + rc = 2; /* The normal "something went wrong" code */ } BZ2_bzclose(inbz2); } @@ -1803,15 +1877,25 @@ if (strchr(op->long_name, '_') != NULL) continue; - if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " "); - n = 31 - printf(" %s --%s", s, op->long_name); + if (op->one_char > 0 && (op->long_name)[0] == 0) + n = 31 - printf(" -%c", op->one_char); + else + { + if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); + else strcpy(s, " "); + n = 31 - printf(" %s --%s", s, op->long_name); + } + if (n < 1) n = 1; - printf("%.*s%s\n", n, " ", op->help_text); + printf("%.*s%s\n", n, " ", op->help_text); } -printf("\nWhen reading patterns from a file instead of using a command line option,\n"); -printf("trailing white space is removed and blank lines are ignored.\n"); -printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT); +printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n"); +printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE); +printf("When reading patterns or file names from a file, trailing white\n"); +printf("space is removed and blank lines are ignored.\n"); +printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n", + MAX_PATTERN_COUNT, PATBUFSIZE); printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n"); printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); @@ -1831,11 +1915,14 @@ { case N_FOFFSETS: file_offsets = TRUE; break; case N_HELP: help(); pcregrep_exit(0); - case N_LOFFSETS: line_offsets = number = TRUE; break; case N_LBUFFER: line_buffered = TRUE; break; + case N_LOFFSETS: line_offsets = number = TRUE; break; + case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break; + case 'a': binary_files = BIN_TEXT; break; case 'c': count_only = TRUE; break; case 'F': process_options |= PO_FIXED_STRINGS; break; case 'H': filenames = FN_FORCE; break; + case 'I': binary_files = BIN_NOMATCH; break; case 'h': filenames = FN_NONE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break; @@ -1913,7 +2000,7 @@ static BOOL compile_single_pattern(char *pattern, int options, char *filename, int count) { -char buffer[MBUFTHIRD + 16]; +char buffer[PATBUFSIZE]; const char *error; int errptr; @@ -1924,7 +2011,7 @@ return FALSE; } -sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern, +sprintf(buffer, "%s%.*s%s", prefix[process_options], bufthird, pattern, suffix[process_options]); pattern_list[pattern_count] = pcre_compile(buffer, options, &error, &errptr, pcretables); @@ -1983,7 +2070,7 @@ if ((process_options & PO_FIXED_STRINGS) != 0) { char *eop = pattern + strlen(pattern); - char buffer[MBUFTHIRD]; + char buffer[PATBUFSIZE]; for(;;) { int ellength; @@ -2021,6 +2108,10 @@ const char *locale_from = "--locale"; const char *error; +#ifdef SUPPORT_PCREGREP_JIT +pcre_jit_stack *jit_stack = NULL; +#endif + /* Set the default line ending value from the default in the PCRE library; "lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf". Note that the return values from pcre_config(), though derived from the ASCII @@ -2277,6 +2368,24 @@ patterns[cmd_pattern_count++] = option_data; } + /* Handle OP_BINARY_FILES */ + + else if (op->type == OP_BINFILES) + { + if (strcmp(option_data, "binary") == 0) + binary_files = BIN_BINARY; + else if (strcmp(option_data, "without-match") == 0) + binary_files = BIN_NOMATCH; + else if (strcmp(option_data, "text") == 0) + binary_files = BIN_TEXT; + else + { + fprintf(stderr, "pcregrep: unknown value \"%s\" for binary-files\n", + option_data); + pcregrep_exit(usage(2)); + } + } + /* Otherwise, deal with single string or numeric data values. */ else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER && @@ -2295,6 +2404,16 @@ while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++; while (isdigit((unsigned char)(*endptr))) n = n * 10 + (int)(*endptr++ - '0'); + if (toupper(*endptr) == 'K') + { + n *= 1024; + endptr++; + } + else if (toupper(*endptr) == 'M') + { + n *= 1024*1024; + endptr++; + } if (*endptr != 0) { if (longop) @@ -2461,12 +2580,14 @@ } #endif -/* Get memory to store the pattern and hints lists. */ +/* Get memory for the main buffer, and to store the pattern and hints lists. */ +bufsize = 3*bufthird; +main_buffer = (char *)malloc(bufsize); pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *)); hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *)); -if (pattern_list == NULL || hints_list == NULL) +if (main_buffer == NULL || pattern_list == NULL || hints_list == NULL) { fprintf(stderr, "pcregrep: malloc failed\n"); goto EXIT2; @@ -2498,7 +2619,7 @@ int linenumber = 0; FILE *f; char *filename; - char buffer[MBUFTHIRD]; + char buffer[PATBUFSIZE]; if (strcmp(pattern_filename, "-") == 0) { @@ -2517,7 +2638,7 @@ filename = pattern_filename; } - while (fgets(buffer, MBUFTHIRD, f) != NULL) + while (fgets(buffer, PATBUFSIZE, f) != NULL) { char *s = buffer + (int)strlen(buffer); while (s > buffer && isspace((unsigned char)(s[-1]))) s--; @@ -2531,11 +2652,17 @@ if (f != stdin) fclose(f); } -/* Study the regular expressions, as we will be running them many times */ +/* Study the regular expressions, as we will be running them many times. Unless +JIT has been explicitly disabled, arrange a stack for it to use. */ + +#ifdef SUPPORT_PCREGREP_JIT +if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0) + jit_stack = pcre_jit_stack_alloc(32*1024, 1024*1024); +#endif for (j = 0; j < pattern_count; j++) { - hints_list[j] = pcre_study(pattern_list[j], 0, &error); + hints_list[j] = pcre_study(pattern_list[j], study_options, &error); if (error != NULL) { char s[16]; @@ -2544,6 +2671,10 @@ goto EXIT2; } hint_count++; +#ifdef SUPPORT_PCREGREP_JIT + if (jit_stack != NULL && hints_list[j] != NULL) + pcre_assign_jit_stack(hints_list[j], NULL, jit_stack); +#endif } /* If --match-limit or --recursion-limit was set, put the value(s) into the @@ -2625,20 +2756,55 @@ } } -/* If there are no further arguments, do the business on stdin and exit. */ +/* If a file that contains a list of files to search has been specified, read +it line by line and search the given files. Otherwise, if there are no further +arguments, do the business on stdin and exit. */ -if (i >= argc) +if (file_list != NULL) { - rc = pcregrep(stdin, FR_PLAIN, (filenames > FN_DEFAULT)? stdin_name : NULL); + char buffer[PATBUFSIZE]; + FILE *fl; + if (strcmp(file_list, "-") == 0) fl = stdin; else + { + fl = fopen(file_list, "rb"); + if (fl == NULL) + { + fprintf(stderr, "pcregrep: Failed to open %s: %s\n", file_list, + strerror(errno)); + goto EXIT2; + } + } + while (fgets(buffer, PATBUFSIZE, fl) != NULL) + { + int frc; + char *end = buffer + (int)strlen(buffer); + while (end > buffer && isspace(end[-1])) end--; + *end = 0; + if (*buffer != 0) + { + frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE); + if (frc > 1) rc = frc; + else if (frc == 0 && rc == 1) rc = 0; + } + } + if (fl != stdin) fclose (fl); + } + +/* Do this only if there was no file list (and no file arguments). */ + +else if (i >= argc) + { + rc = pcregrep(stdin, FR_PLAIN, stdin_name, + (filenames > FN_DEFAULT)? stdin_name : NULL); goto EXIT; } -/* Otherwise, work through the remaining arguments as files or directories. -Pass in the fact that there is only one argument at top level - this suppresses -the file name if the argument is not a directory and filenames are not -otherwise forced. */ +/* After handling file-list or if there are remaining arguments, work through +them as files or directories. Pass in the fact that there is only one argument +at top level - this suppresses the file name if the argument is not a directory +and filenames are not otherwise forced. */ -only_one_at_top = i == argc - 1; /* Catch initial value of i */ +only_one_at_top = i == argc - 1 && file_list == NULL; for (; i < argc; i++) { @@ -2649,6 +2815,10 @@ } EXIT: +#ifdef SUPPORT_PCREGREP_JIT +if (jit_stack != NULL) pcre_jit_stack_free(jit_stack); +#endif +if (main_buffer != NULL) free(main_buffer); if (pattern_list != NULL) { for (i = 0; i < pattern_count; i++) free(pattern_list[i]); @@ -2658,7 +2828,7 @@ { for (i = 0; i < hint_count; i++) { - if (hints_list[i] != NULL) free(hints_list[i]); + if (hints_list[i] != NULL) pcre_free_study(hints_list[i]); } free(hints_list); } diff -Nru pcre3-8.12/pcreposix.c pcre3-8.31/pcreposix.c --- pcre3-8.12/pcreposix.c 2010-11-24 17:38:32.000000000 +0000 +++ pcre3-8.31/pcreposix.c 2012-06-20 15:08:49.000000000 +0000 @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2010 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -152,6 +152,16 @@ REG_BADPAT, /* (*MARK) must have an argument */ REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */ REG_BADPAT, /* \c must be followed by an ASCII character */ + REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */ + /* 70 */ + REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */ + REG_BADPAT, /* \N is not supported in a class */ + REG_BADPAT, /* too many forward references */ + REG_BADPAT, /* disallowed UTF-8/16 code point (>= 0xd800 && <= 0xdfff) */ + REG_BADPAT, /* invalid UTF-16 string (should not occur) */ + /* 75 */ + REG_BADPAT, /* overlong MARK name */ + REG_BADPAT /* character value in \u.... sequence is too large */ }; /* Table of texts corresponding to POSIX error codes */ @@ -222,7 +232,7 @@ PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION regfree(regex_t *preg) { -(pcre_free)(preg->re_pcre); +(PUBL(free))(preg->re_pcre); } @@ -267,11 +277,12 @@ if (preg->re_pcre == NULL) { - return (errorcode < sizeof(eint)/sizeof(const int))? + return (errorcode < (int)(sizeof(eint)/sizeof(const int)))? eint[errorcode] : REG_BADPAT; } -preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); +(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, + &(preg->re_nsub)); return 0; } @@ -397,6 +408,7 @@ case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; case PCRE_ERROR_BADUTF8: return REG_INVARG; case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; + case PCRE_ERROR_BADMODE: return REG_INVARG; default: return REG_ASSERT; } } diff -Nru pcre3-8.12/pcreposix.h pcre3-8.31/pcreposix.h --- pcre3-8.12/pcreposix.h 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/pcreposix.h 2011-12-28 16:57:51.000000000 +0000 @@ -9,7 +9,7 @@ Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2012 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -133,19 +133,14 @@ /* The functions */ -PCREPOSIX_EXP_DECL int pcreposix_regcomp(regex_t *, const char *, int); -PCREPOSIX_EXP_DECL int pcreposix_regexec(const regex_t *, const char *, size_t, +PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int); +PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t, regmatch_t *, int); -PCREPOSIX_EXP_DECL size_t pcreposix_regerror(int, const regex_t *, char *, size_t); -PCREPOSIX_EXP_DECL void pcreposix_regfree(regex_t *); +PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t); +PCREPOSIX_EXP_DECL void regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif -#define regcomp pcreposix_regcomp -#define regexec pcreposix_regexec -#define regerror pcreposix_regerror -#define regfree pcreposix_regfree - #endif /* End of pcreposix.h */ diff -Nru pcre3-8.12/pcretest.c pcre3-8.31/pcretest.c --- pcre3-8.12/pcretest.c 2013-03-27 06:36:17.000000000 +0000 +++ pcre3-8.31/pcretest.c 2012-06-02 10:55:16.000000000 +0000 @@ -4,7 +4,8 @@ /* This program was hacked up as a tester for PCRE. I really should have written it more tidily in the first place. Will I ever learn? It has grown and -been extended and consequently is now rather, er, *very* untidy in places. +been extended and consequently is now rather, er, *very* untidy in places. The +addition of 16-bit support has made it even worse. :-( ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -35,6 +36,15 @@ ----------------------------------------------------------------------------- */ +/* This program now supports the testing of both the 8-bit and 16-bit PCRE +libraries in a single program. This is different from the modules such as +pcre_compile.c in the library itself, which are compiled separately for each +mode. If both modes are enabled, for example, pcre_compile.c is compiled twice +(the second time with COMPILE_PCRE16 defined). By contrast, pcretest.c is +compiled only once. Therefore, it must not make use of any of the macros from +pcre_internal.h that depend on COMPILE_PCRE8 or COMPILE_PCRE16. It does, +however, make use of SUPPORT_PCRE8 and SUPPORT_PCRE16 to ensure that it calls +only supported library functions. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -48,14 +58,26 @@ #include #include -#ifdef SUPPORT_LIBREADLINE +/* Both libreadline and libedit are optionally supported. The user-supplied +original patch uses readline/readline.h for libedit, but in at least one system +it is installed as editline/readline.h, so the configuration code now looks for +that first, falling back to readline/readline.h. */ + +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) #ifdef HAVE_UNISTD_H #include #endif +#if defined(SUPPORT_LIBREADLINE) #include #include +#else +#if defined(HAVE_EDITLINE_READLINE_H) +#include +#else +#include +#endif +#endif #endif - /* A number of things vary for Windows builds. Originally, pcretest opened its input and output without "b"; then I was told that "b" was needed in some @@ -94,6 +116,7 @@ #define OUTPUT_MODE "wb" #endif +#define PRIV(name) name /* We have to include pcre_internal.h because we need the internal info for displaying the results of pcre_study() and we also need to know about the @@ -105,40 +128,52 @@ appropriately for an application, not for building PCRE. */ #include "pcre.h" + +#if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 +/* Configure internal macros to 16 bit mode. */ +#define COMPILE_PCRE16 +#endif + #include "pcre_internal.h" +/* The pcre_printint() function, which prints the internal form of a compiled +regex, is held in a separate file so that (a) it can be compiled in either +8-bit or 16-bit mode, and (b) it can be #included directly in pcre_compile.c +when that is compiled in debug mode. */ + +#ifdef SUPPORT_PCRE8 +void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#endif +#ifdef SUPPORT_PCRE16 +void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); +#endif + /* We need access to some of the data tables that PCRE uses. So as not to have to keep two copies, we include the source file here, changing the names of the external symbols to prevent clashes. */ -#define _pcre_ucp_gentype ucp_gentype -#define _pcre_utf8_table1 utf8_table1 -#define _pcre_utf8_table1_size utf8_table1_size -#define _pcre_utf8_table2 utf8_table2 -#define _pcre_utf8_table3 utf8_table3 -#define _pcre_utf8_table4 utf8_table4 -#define _pcre_utt utt -#define _pcre_utt_size utt_size -#define _pcre_utt_names utt_names -#define _pcre_OP_lengths OP_lengths +#define PCRE_INCLUDED #include "pcre_tables.c" -/* We also need the pcre_printint() function for printing out compiled -patterns. This function is in a separate file so that it can be included in -pcre_compile.c when that module is compiled with debugging enabled. It needs to -know which case is being compiled. */ - -#define COMPILING_PCRETEST -#include "pcre_printint.src" - /* The definition of the macro PRINTABLE, which determines whether to print an output character as-is or as a hex value when showing compiled patterns, is -contained in the printint.src file. We uses it here also, in cases when the -locale has not been explicitly changed, so as to get consistent output from -systems that differ in their output from isprint() even in the "C" locale. */ +the same as in the printint.src file. We uses it here in cases when the locale +has not been explicitly changed, so as to get consistent output from systems +that differ in their output from isprint() even in the "C" locale. */ -#define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c)) +#ifdef EBCDIC +#define PRINTABLE(c) ((c) >= 64 && (c) < 255) +#else +#define PRINTABLE(c) ((c) >= 32 && (c) < 127) +#endif + +#define PRINTOK(c) (locale_set? isprint(c) : PRINTABLE(c)) + +/* Posix support is disabled in 16 bit only mode. */ +#if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 && !defined NOPOSIX +#define NOPOSIX +#endif /* It is possible to compile this test program without including support for testing the POSIX interface, though this is not available via the standard @@ -148,18 +183,422 @@ #include "pcreposix.h" #endif -/* It is also possible, for the benefit of the version currently imported into -Exim, to build pcretest without support for UTF8 (define NOUTF8), without the -interface to the DFA matcher (NODFA), and without the doublecheck of the old -"info" function (define NOINFOCHECK). In fact, we automatically cut out the -UTF8 support if PCRE is built without it. */ - -#ifndef SUPPORT_UTF8 -#ifndef NOUTF8 -#define NOUTF8 +/* It is also possible, originally for the benefit of a version that was +imported into Exim, to build pcretest without support for UTF8 or UTF16 (define +NOUTF), without the interface to the DFA matcher (NODFA). In fact, we +automatically cut out the UTF support if PCRE is built without it. */ + +#ifndef SUPPORT_UTF +#ifndef NOUTF +#define NOUTF #endif #endif +/* To make the code a bit tidier for 8-bit and 16-bit support, we define macros +for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called +only from one place and is handled differently). I couldn't dream up any way of +using a single macro to do this in a generic way, because of the many different +argument requirements. We know that at least one of SUPPORT_PCRE8 and +SUPPORT_PCRE16 must be set. First define macros for each individual mode; then +use these in the definitions of generic macros. + +**** Special note about the PCHARSxxx macros: the address of the string to be +printed is always given as two arguments: a base address followed by an offset. +The base address is cast to the correct data size for 8 or 16 bit data; the +offset is in units of this size. If the string were given as base+offset in one +argument, the casting might be incorrectly applied. */ + +#ifdef SUPPORT_PCRE8 + +#define PCHARS8(lv, p, offset, len, f) \ + lv = pchars((pcre_uint8 *)(p) + offset, len, f) + +#define PCHARSV8(p, offset, len, f) \ + (void)pchars((pcre_uint8 *)(p) + offset, len, f) + +#define READ_CAPTURE_NAME8(p, cn8, cn16, re) \ + p = read_capture_name8(p, cn8, re) + +#define STRLEN8(p) ((int)strlen((char *)p)) + +#define SET_PCRE_CALLOUT8(callout) \ + pcre_callout = callout + +#define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \ + pcre_assign_jit_stack(extra, callback, userdata) + +#define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \ + re = pcre_compile((char *)pat, options, error, erroffset, tables) + +#define PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) \ + rc = pcre_copy_named_substring(re, (char *)bptr, offsets, count, \ + (char *)namesptr, cbuffer, size) + +#define PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) \ + rc = pcre_copy_substring((char *)bptr, offsets, count, i, cbuffer, size) + +#define PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) \ + count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) + +#define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) \ + count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \ + offsets, size_offsets) + +#define PCRE_FREE_STUDY8(extra) \ + pcre_free_study(extra) + +#define PCRE_FREE_SUBSTRING8(substring) \ + pcre_free_substring(substring) + +#define PCRE_FREE_SUBSTRING_LIST8(listptr) \ + pcre_free_substring_list(listptr) + +#define PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + rc = pcre_get_named_substring(re, (char *)bptr, offsets, count, \ + (char *)getnamesptr, subsptr) + +#define PCRE_GET_STRINGNUMBER8(n, rc, ptr) \ + n = pcre_get_stringnumber(re, (char *)ptr) + +#define PCRE_GET_SUBSTRING8(rc, bptr, offsets, count, i, subsptr) \ + rc = pcre_get_substring((char *)bptr, offsets, count, i, subsptr) + +#define PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) \ + rc = pcre_get_substring_list((const char *)bptr, offsets, count, listptr) + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) \ + rc = pcre_pattern_to_host_byte_order(re, extra, tables) + +#define PCRE_PRINTINT8(re, outfile, debug_lengths) \ + pcre_printint(re, outfile, debug_lengths) + +#define PCRE_STUDY8(extra, re, options, error) \ + extra = pcre_study(re, options, error) + +#define PCRE_JIT_STACK_ALLOC8(startsize, maxsize) \ + pcre_jit_stack_alloc(startsize, maxsize) + +#define PCRE_JIT_STACK_FREE8(stack) \ + pcre_jit_stack_free(stack) + +#endif /* SUPPORT_PCRE8 */ + +/* -----------------------------------------------------------*/ + +#ifdef SUPPORT_PCRE16 + +#define PCHARS16(lv, p, offset, len, f) \ + lv = pchars16((PCRE_SPTR16)(p) + offset, len, f) + +#define PCHARSV16(p, offset, len, f) \ + (void)pchars16((PCRE_SPTR16)(p) + offset, len, f) + +#define READ_CAPTURE_NAME16(p, cn8, cn16, re) \ + p = read_capture_name16(p, cn16, re) + +#define STRLEN16(p) ((int)strlen16((PCRE_SPTR16)p)) + +#define SET_PCRE_CALLOUT16(callout) \ + pcre16_callout = (int (*)(pcre16_callout_block *))callout + +#define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \ + pcre16_assign_jit_stack((pcre16_extra *)extra, \ + (pcre16_jit_callback)callback, userdata) + +#define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \ + re = (pcre *)pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, \ + tables) + +#define PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) \ + rc = pcre16_copy_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \ + count, (PCRE_SPTR16)namesptr, (PCRE_UCHAR16 *)cbuffer, size/2) + +#define PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size) \ + rc = pcre16_copy_substring((PCRE_SPTR16)bptr, offsets, count, i, \ + (PCRE_UCHAR16 *)cbuffer, size/2) + +#define PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) \ + count = pcre16_dfa_exec((pcre16 *)re, (pcre16_extra *)extra, \ + (PCRE_SPTR16)bptr, len, start_offset, options, offsets, size_offsets, \ + workspace, size_workspace) + +#define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) \ + count = pcre16_exec((pcre16 *)re, (pcre16_extra *)extra, (PCRE_SPTR16)bptr, \ + len, start_offset, options, offsets, size_offsets) + +#define PCRE_FREE_STUDY16(extra) \ + pcre16_free_study((pcre16_extra *)extra) + +#define PCRE_FREE_SUBSTRING16(substring) \ + pcre16_free_substring((PCRE_SPTR16)substring) + +#define PCRE_FREE_SUBSTRING_LIST16(listptr) \ + pcre16_free_substring_list((PCRE_SPTR16 *)listptr) + +#define PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + rc = pcre16_get_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \ + count, (PCRE_SPTR16)getnamesptr, (PCRE_SPTR16 *)(void*)subsptr) + +#define PCRE_GET_STRINGNUMBER16(n, rc, ptr) \ + n = pcre16_get_stringnumber(re, (PCRE_SPTR16)ptr) + +#define PCRE_GET_SUBSTRING16(rc, bptr, offsets, count, i, subsptr) \ + rc = pcre16_get_substring((PCRE_SPTR16)bptr, offsets, count, i, \ + (PCRE_SPTR16 *)(void*)subsptr) + +#define PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr) \ + rc = pcre16_get_substring_list((PCRE_SPTR16)bptr, offsets, count, \ + (PCRE_SPTR16 **)(void*)listptr) + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables) \ + rc = pcre16_pattern_to_host_byte_order((pcre16 *)re, (pcre16_extra *)extra, \ + tables) + +#define PCRE_PRINTINT16(re, outfile, debug_lengths) \ + pcre16_printint(re, outfile, debug_lengths) + +#define PCRE_STUDY16(extra, re, options, error) \ + extra = (pcre_extra *)pcre16_study((pcre16 *)re, options, error) + +#define PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \ + (pcre_jit_stack *)pcre16_jit_stack_alloc(startsize, maxsize) + +#define PCRE_JIT_STACK_FREE16(stack) \ + pcre16_jit_stack_free((pcre16_jit_stack *)stack) + +#endif /* SUPPORT_PCRE16 */ + + +/* ----- Both modes are supported; a runtime test is needed, except for +pcre_config(), and the JIT stack functions, when it doesn't matter which +version is called. ----- */ + +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + +#define CHAR_SIZE (use_pcre16? 2:1) + +#define PCHARS(lv, p, offset, len, f) \ + if (use_pcre16) \ + PCHARS16(lv, p, offset, len, f); \ + else \ + PCHARS8(lv, p, offset, len, f) + +#define PCHARSV(p, offset, len, f) \ + if (use_pcre16) \ + PCHARSV16(p, offset, len, f); \ + else \ + PCHARSV8(p, offset, len, f) + +#define READ_CAPTURE_NAME(p, cn8, cn16, re) \ + if (use_pcre16) \ + READ_CAPTURE_NAME16(p, cn8, cn16, re); \ + else \ + READ_CAPTURE_NAME8(p, cn8, cn16, re) + +#define SET_PCRE_CALLOUT(callout) \ + if (use_pcre16) \ + SET_PCRE_CALLOUT16(callout); \ + else \ + SET_PCRE_CALLOUT8(callout) + +#define STRLEN(p) (use_pcre16? STRLEN16(p) : STRLEN8(p)) + +#define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \ + if (use_pcre16) \ + PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata); \ + else \ + PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) + +#define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \ + if (use_pcre16) \ + PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \ + else \ + PCRE_COMPILE8(re, pat, options, error, erroffset, tables) + +#define PCRE_CONFIG pcre_config + +#define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) \ + if (use_pcre16) \ + PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size); \ + else \ + PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ + namesptr, cbuffer, size) + +#define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \ + if (use_pcre16) \ + PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size); \ + else \ + PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) + +#define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) \ + if (use_pcre16) \ + PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace); \ + else \ + PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets, workspace, size_workspace) + +#define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) \ + if (use_pcre16) \ + PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets); \ + else \ + PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \ + offsets, size_offsets) + +#define PCRE_FREE_STUDY(extra) \ + if (use_pcre16) \ + PCRE_FREE_STUDY16(extra); \ + else \ + PCRE_FREE_STUDY8(extra) + +#define PCRE_FREE_SUBSTRING(substring) \ + if (use_pcre16) \ + PCRE_FREE_SUBSTRING16(substring); \ + else \ + PCRE_FREE_SUBSTRING8(substring) + +#define PCRE_FREE_SUBSTRING_LIST(listptr) \ + if (use_pcre16) \ + PCRE_FREE_SUBSTRING_LIST16(listptr); \ + else \ + PCRE_FREE_SUBSTRING_LIST8(listptr) + +#define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) \ + if (use_pcre16) \ + PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr); \ + else \ + PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \ + getnamesptr, subsptr) + +#define PCRE_GET_STRINGNUMBER(n, rc, ptr) \ + if (use_pcre16) \ + PCRE_GET_STRINGNUMBER16(n, rc, ptr); \ + else \ + PCRE_GET_STRINGNUMBER8(n, rc, ptr) + +#define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \ + if (use_pcre16) \ + PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr); \ + else \ + PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr) + +#define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \ + if (use_pcre16) \ + PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr); \ + else \ + PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) + +#define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \ + (use_pcre16 ? \ + PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \ + :PCRE_JIT_STACK_ALLOC8(startsize, maxsize)) + +#define PCRE_JIT_STACK_FREE(stack) \ + if (use_pcre16) \ + PCRE_JIT_STACK_FREE16(stack); \ + else \ + PCRE_JIT_STACK_FREE8(stack) + +#define PCRE_MAKETABLES \ + (use_pcre16? pcre16_maketables() : pcre_maketables()) + +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \ + if (use_pcre16) \ + PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables); \ + else \ + PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) + +#define PCRE_PRINTINT(re, outfile, debug_lengths) \ + if (use_pcre16) \ + PCRE_PRINTINT16(re, outfile, debug_lengths); \ + else \ + PCRE_PRINTINT8(re, outfile, debug_lengths) + +#define PCRE_STUDY(extra, re, options, error) \ + if (use_pcre16) \ + PCRE_STUDY16(extra, re, options, error); \ + else \ + PCRE_STUDY8(extra, re, options, error) + +/* ----- Only 8-bit mode is supported ----- */ + +#elif defined SUPPORT_PCRE8 +#define CHAR_SIZE 1 +#define PCHARS PCHARS8 +#define PCHARSV PCHARSV8 +#define READ_CAPTURE_NAME READ_CAPTURE_NAME8 +#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT8 +#define STRLEN STRLEN8 +#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK8 +#define PCRE_COMPILE PCRE_COMPILE8 +#define PCRE_CONFIG pcre_config +#define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING8 +#define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING8 +#define PCRE_DFA_EXEC PCRE_DFA_EXEC8 +#define PCRE_EXEC PCRE_EXEC8 +#define PCRE_FREE_STUDY PCRE_FREE_STUDY8 +#define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING8 +#define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST8 +#define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING8 +#define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER8 +#define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING8 +#define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST8 +#define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC8 +#define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE8 +#define PCRE_MAKETABLES pcre_maketables() +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER8 +#define PCRE_PRINTINT PCRE_PRINTINT8 +#define PCRE_STUDY PCRE_STUDY8 + +/* ----- Only 16-bit mode is supported ----- */ + +#else +#define CHAR_SIZE 2 +#define PCHARS PCHARS16 +#define PCHARSV PCHARSV16 +#define READ_CAPTURE_NAME READ_CAPTURE_NAME16 +#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT16 +#define STRLEN STRLEN16 +#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK16 +#define PCRE_COMPILE PCRE_COMPILE16 +#define PCRE_CONFIG pcre16_config +#define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING16 +#define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING16 +#define PCRE_DFA_EXEC PCRE_DFA_EXEC16 +#define PCRE_EXEC PCRE_EXEC16 +#define PCRE_FREE_STUDY PCRE_FREE_STUDY16 +#define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING16 +#define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST16 +#define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING16 +#define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER16 +#define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING16 +#define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST16 +#define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC16 +#define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE16 +#define PCRE_MAKETABLES pcre16_maketables() +#define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER16 +#define PCRE_PRINTINT PCRE_PRINTINT16 +#define PCRE_STUDY PCRE_STUDY16 +#endif + +/* ----- End of mode-specific function call macros ----- */ + /* Other parameters */ @@ -171,6 +610,10 @@ #endif #endif +#if !defined NODFA +#define DFA_WS_DIMENSION 1000 +#endif + /* This is the default loop count for timing. */ #define LOOPREPEAT 500000 @@ -185,17 +628,117 @@ static int callout_fail_id; static int debug_lengths; static int first_callout; +static int jit_was_used; static int locale_set = 0; static int show_malloc; -static int use_utf8; +static int use_utf; static size_t gotten_store; +static size_t first_gotten_store = 0; +static const unsigned char *last_callout_mark = NULL; /* The buffers grow automatically if very long input lines are encountered. */ static int buffer_size = 50000; -static uschar *buffer = NULL; -static uschar *dbuffer = NULL; -static uschar *pbuffer = NULL; +static pcre_uint8 *buffer = NULL; +static pcre_uint8 *dbuffer = NULL; +static pcre_uint8 *pbuffer = NULL; + +/* Another buffer is needed translation to 16-bit character strings. It will +obtained and extended as required. */ + +#ifdef SUPPORT_PCRE16 +static int buffer16_size = 0; +static pcre_uint16 *buffer16 = NULL; + +#ifdef SUPPORT_PCRE8 + +/* We need the table of operator lengths that is used for 16-bit compiling, in +order to swap bytes in a pattern for saving/reloading testing. Luckily, the +data is defined as a macro. However, we must ensure that LINK_SIZE is adjusted +appropriately for the 16-bit world. Just as a safety check, make sure that +COMPILE_PCRE16 is *not* set. */ + +#ifdef COMPILE_PCRE16 +#error COMPILE_PCRE16 must not be set when compiling pcretest.c +#endif + +#if LINK_SIZE == 2 +#undef LINK_SIZE +#define LINK_SIZE 1 +#elif LINK_SIZE == 3 || LINK_SIZE == 4 +#undef LINK_SIZE +#define LINK_SIZE 2 +#else +#error LINK_SIZE must be either 2, 3, or 4 +#endif + +#undef IMM2_SIZE +#define IMM2_SIZE 1 + +#endif /* SUPPORT_PCRE8 */ + +static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS }; +#endif /* SUPPORT_PCRE16 */ + +/* If we have 8-bit support, default use_pcre16 to false; if there is also +16-bit support, it can be changed by an option. If there is no 8-bit support, +there must be 16-bit support, so default it to 1. */ + +#ifdef SUPPORT_PCRE8 +static int use_pcre16 = 0; +#else +static int use_pcre16 = 1; +#endif + +/* JIT study options for -s+n and /S+n where '1' <= n <= '7'. */ + +static int jit_study_bits[] = + { + PCRE_STUDY_JIT_COMPILE, + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE, + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE, + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE, + PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE +}; + +/* Textual explanations for runtime error codes */ + +static const char *errtexts[] = { + NULL, /* 0 is no error */ + NULL, /* NOMATCH is handled specially */ + "NULL argument passed", + "bad option value", + "magic number missing", + "unknown opcode - pattern overwritten?", + "no more memory", + NULL, /* never returned by pcre_exec() or pcre_dfa_exec() */ + "match limit exceeded", + "callout error code", + NULL, /* BADUTF8/16 is handled specially */ + NULL, /* BADUTF8/16 offset is handled specially */ + NULL, /* PARTIAL is handled specially */ + "not used - internal error", + "internal error - pattern overwritten?", + "bad count value", + "item unsupported for DFA matching", + "backreference condition or recursion test not supported for DFA matching", + "match limit not supported for DFA matching", + "workspace size exceeded in DFA matching", + "too much recursion for DFA matching", + "recursion limit exceeded", + "not used - internal error", + "invalid combination of newline options", + "bad offset value", + NULL, /* SHORTUTF8/16 is handled specially */ + "nested recursion at the same subject position", + "JIT stack limit reached", + "pattern compiled in wrong mode: 8-bit/16-bit error", + "pattern compiled with other endianness", + "invalid data in workspace for DFA restart" +}; /************************************************* @@ -210,7 +753,7 @@ /* This is the set of tables distributed as default with PCRE. It recognizes only ASCII characters. */ -static const unsigned char tables0[] = { +static const pcre_uint8 tables0[] = { /* This table is a lower casing table. */ @@ -383,7 +926,7 @@ be at least an approximation of ISO 8859. In particular, there are characters greater than 128 that are marked as spaces, letters, etc. */ -static const unsigned char tables1[] = { +static const pcre_uint8 tables1[] = { 0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, @@ -546,6 +1089,188 @@ #endif /* HAVE_STRERROR */ +/************************************************* +* JIT memory callback * +*************************************************/ + +static pcre_jit_stack* jit_callback(void *arg) +{ +jit_was_used = TRUE; +return (pcre_jit_stack *)arg; +} + + +#if !defined NOUTF || defined SUPPORT_PCRE16 +/************************************************* +* Convert UTF-8 string to value * +*************************************************/ + +/* This function takes one or more bytes that represents a UTF-8 character, +and returns the value of the character. + +Argument: + utf8bytes a pointer to the byte vector + vptr a pointer to an int to receive the value + +Returns: > 0 => the number of bytes consumed + -6 to 0 => malformed UTF-8 character at offset = (-return) +*/ + +static int +utf82ord(pcre_uint8 *utf8bytes, int *vptr) +{ +int c = *utf8bytes++; +int d = c; +int i, j, s; + +for (i = -1; i < 6; i++) /* i is number of additional bytes */ + { + if ((d & 0x80) == 0) break; + d <<= 1; + } + +if (i == -1) { *vptr = c; return 1; } /* ascii character */ +if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ + +/* i now has a value in the range 1-5 */ + +s = 6*i; +d = (c & utf8_table3[i]) << s; + +for (j = 0; j < i; j++) + { + c = *utf8bytes++; + if ((c & 0xc0) != 0x80) return -(j+1); + s -= 6; + d |= (c & 0x3f) << s; + } + +/* Check that encoding was the correct unique one */ + +for (j = 0; j < utf8_table1_size; j++) + if (d <= utf8_table1[j]) break; +if (j != i) return -(i+1); + +/* Valid value */ + +*vptr = d; +return i+1; +} +#endif /* NOUTF || SUPPORT_PCRE16 */ + + + +#if !defined NOUTF || defined SUPPORT_PCRE16 +/************************************************* +* Convert character value to UTF-8 * +*************************************************/ + +/* This function takes an integer value in the range 0 - 0x7fffffff +and encodes it as a UTF-8 character in 0 to 6 bytes. + +Arguments: + cvalue the character value + utf8bytes pointer to buffer for result - at least 6 bytes long + +Returns: number of characters placed in the buffer +*/ + +static int +ord2utf8(int cvalue, pcre_uint8 *utf8bytes) +{ +register int i, j; +for (i = 0; i < utf8_table1_size; i++) + if (cvalue <= utf8_table1[i]) break; +utf8bytes += i; +for (j = i; j > 0; j--) + { + *utf8bytes-- = 0x80 | (cvalue & 0x3f); + cvalue >>= 6; + } +*utf8bytes = utf8_table2[i] | cvalue; +return i + 1; +} +#endif + + +#ifdef SUPPORT_PCRE16 +/************************************************* +* Convert a string to 16-bit * +*************************************************/ + +/* In non-UTF mode, the space needed for a 16-bit string is exactly double the +8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than +double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4 +in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The +result is always left in buffer16. + +Note that this function does not object to surrogate values. This is +deliberate; it makes it possible to construct UTF-16 strings that are invalid, +for the purpose of testing that they are correctly faulted. + +Patterns to be converted are either plain ASCII or UTF-8; data lines are always +in UTF-8 so that values greater than 255 can be handled. + +Arguments: + data TRUE if converting a data line; FALSE for a regex + p points to a byte string + utf true if UTF-8 (to be converted to UTF-16) + len number of bytes in the string (excluding trailing zero) + +Returns: number of 16-bit data items used (excluding trailing zero) + OR -1 if a UTF-8 string is malformed + OR -2 if a value > 0x10ffff is encountered + OR -3 if a value > 0xffff is encountered when not in UTF mode +*/ + +static int +to16(int data, pcre_uint8 *p, int utf, int len) +{ +pcre_uint16 *pp; + +if (buffer16_size < 2*len + 2) + { + if (buffer16 != NULL) free(buffer16); + buffer16_size = 2*len + 2; + buffer16 = (pcre_uint16 *)malloc(buffer16_size); + if (buffer16 == NULL) + { + fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size); + exit(1); + } + } + +pp = buffer16; + +if (!utf && !data) + { + while (len-- > 0) *pp++ = *p++; + } + +else + { + int c = 0; + while (len > 0) + { + int chlen = utf82ord(p, &c); + if (chlen <= 0) return -1; + if (c > 0x10ffff) return -2; + p += chlen; + len -= chlen; + if (c < 0x10000) *pp++ = c; else + { + if (!utf) return -3; + c -= 0x10000; + *pp++ = 0xD800 | (c >> 10); + *pp++ = 0xDC00 | (c & 0x3ff); + } + } + } + +*pp = 0; +return pp - buffer16; +} +#endif /************************************************* @@ -571,24 +1296,24 @@ NULL if no data read and EOF reached */ -static uschar * -extend_inputline(FILE *f, uschar *start, const char *prompt) +static pcre_uint8 * +extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt) { -uschar *here = start; +pcre_uint8 *here = start; for (;;) { - int rlen = (int)(buffer_size - (here - buffer)); + size_t rlen = (size_t)(buffer_size - (here - buffer)); if (rlen > 1000) { int dlen; - /* If libreadline support is required, use readline() to read a line if the - input is a terminal. Note that readline() removes the trailing newline, so - we must put it back again, to be compatible with fgets(). */ + /* If libreadline or libedit support is required, use readline() to read a + line if the input is a terminal. Note that readline() removes the trailing + newline, so we must put it back again, to be compatible with fgets(). */ -#ifdef SUPPORT_LIBREADLINE +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) if (isatty(fileno(f))) { size_t len; @@ -621,9 +1346,9 @@ else { int new_buffer_size = 2*buffer_size; - uschar *new_buffer = (unsigned char *)malloc(new_buffer_size); - uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size); - uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size); + pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size); + pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size); + pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size); if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL) { @@ -654,10 +1379,6 @@ - - - - /************************************************* * Read number from string * *************************************************/ @@ -674,7 +1395,7 @@ */ static int -get_value(unsigned char *str, unsigned char **endptr) +get_value(pcre_uint8 *str, pcre_uint8 **endptr) { int result = 0; while(*str != 0 && isspace(*str)) str++; @@ -685,165 +1406,187 @@ - /************************************************* -* Convert UTF-8 string to value * +* Print one character * *************************************************/ -/* This function takes one or more bytes that represents a UTF-8 character, -and returns the value of the character. - -Argument: - utf8bytes a pointer to the byte vector - vptr a pointer to an int to receive the value - -Returns: > 0 => the number of bytes consumed - -6 to 0 => malformed UTF-8 character at offset = (-return) -*/ - -#if !defined NOUTF8 +/* Print a single character either literally, or as a hex escape. */ -static int -utf82ord(unsigned char *utf8bytes, int *vptr) +static int pchar(int c, FILE *f) { -int c = *utf8bytes++; -int d = c; -int i, j, s; +if (PRINTOK(c)) + { + if (f != NULL) fprintf(f, "%c", c); + return 1; + } -for (i = -1; i < 6; i++) /* i is number of additional bytes */ +if (c < 0x100) { - if ((d & 0x80) == 0) break; - d <<= 1; + if (use_utf) + { + if (f != NULL) fprintf(f, "\\x{%02x}", c); + return 6; + } + else + { + if (f != NULL) fprintf(f, "\\x%02x", c); + return 4; + } } -if (i == -1) { *vptr = c; return 1; } /* ascii character */ -if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ +if (f != NULL) fprintf(f, "\\x{%02x}", c); +return (c <= 0x000000ff)? 6 : + (c <= 0x00000fff)? 7 : + (c <= 0x0000ffff)? 8 : + (c <= 0x000fffff)? 9 : 10; +} -/* i now has a value in the range 1-5 */ -s = 6*i; -d = (c & utf8_table3[i]) << s; -for (j = 0; j < i; j++) - { - c = *utf8bytes++; - if ((c & 0xc0) != 0x80) return -(j+1); - s -= 6; - d |= (c & 0x3f) << s; - } +#ifdef SUPPORT_PCRE8 +/************************************************* +* Print 8-bit character string * +*************************************************/ -/* Check that encoding was the correct unique one */ +/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. +If handed a NULL file, just counts chars without printing. */ -for (j = 0; j < utf8_table1_size; j++) - if (d <= utf8_table1[j]) break; -if (j != i) return -(i+1); +static int pchars(pcre_uint8 *p, int length, FILE *f) +{ +int c = 0; +int yield = 0; -/* Valid value */ +if (length < 0) + length = strlen((char *)p); -*vptr = d; -return i+1; -} +while (length-- > 0) + { +#if !defined NOUTF + if (use_utf) + { + int rc = utf82ord(p, &c); + if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ + { + length -= rc - 1; + p += rc; + yield += pchar(c, f); + continue; + } + } +#endif + c = *p++; + yield += pchar(c, f); + } +return yield; +} #endif +#ifdef SUPPORT_PCRE16 /************************************************* -* Convert character value to UTF-8 * +* Find length of 0-terminated 16-bit string * *************************************************/ -/* This function takes an integer value in the range 0 - 0x7fffffff -and encodes it as a UTF-8 character in 0 to 6 bytes. - -Arguments: - cvalue the character value - utf8bytes pointer to buffer for result - at least 6 bytes long - -Returns: number of characters placed in the buffer -*/ - -#if !defined NOUTF8 - -static int -ord2utf8(int cvalue, uschar *utf8bytes) +static int strlen16(PCRE_SPTR16 p) { -register int i, j; -for (i = 0; i < utf8_table1_size; i++) - if (cvalue <= utf8_table1[i]) break; -utf8bytes += i; -for (j = i; j > 0; j--) - { - *utf8bytes-- = 0x80 | (cvalue & 0x3f); - cvalue >>= 6; - } -*utf8bytes = utf8_table2[i] | cvalue; -return i + 1; +int len = 0; +while (*p++ != 0) len++; +return len; } - -#endif - +#endif /* SUPPORT_PCRE16 */ +#ifdef SUPPORT_PCRE16 /************************************************* -* Print character string * +* Print 16-bit character string * *************************************************/ -/* Character string printing function. Must handle UTF-8 strings in utf8 -mode. Yields number of characters printed. If handed a NULL file, just counts -chars without printing. */ +/* Must handle UTF-16 strings in utf mode. Yields number of characters printed. +If handed a NULL file, just counts chars without printing. */ -static int pchars(unsigned char *p, int length, FILE *f) +static int pchars16(PCRE_SPTR16 p, int length, FILE *f) { -int c = 0; int yield = 0; +if (length < 0) + length = strlen16(p); + while (length-- > 0) { -#if !defined NOUTF8 - if (use_utf8) + int c = *p++ & 0xffff; +#if !defined NOUTF + if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0) { - int rc = utf82ord(p, &c); - - if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ + int d = *p & 0xffff; + if (d >= 0xDC00 && d < 0xDFFF) { - length -= rc - 1; - p += rc; - if (PRINTHEX(c)) - { - if (f != NULL) fprintf(f, "%c", c); - yield++; - } - else - { - int n = 4; - if (f != NULL) fprintf(f, "\\x{%02x}", c); - yield += (n <= 0x000000ff)? 2 : - (n <= 0x00000fff)? 3 : - (n <= 0x0000ffff)? 4 : - (n <= 0x000fffff)? 5 : 6; - } - continue; + c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000; + length--; + p++; } } #endif + yield += pchar(c, f); + } - /* Not UTF-8, or malformed UTF-8 */ +return yield; +} +#endif /* SUPPORT_PCRE16 */ - c = *p++; - if (PRINTHEX(c)) - { - if (f != NULL) fprintf(f, "%c", c); - yield++; - } - else - { - if (f != NULL) fprintf(f, "\\x%02x", c); - yield += 4; - } + + +#ifdef SUPPORT_PCRE8 +/************************************************* +* Read a capture name (8-bit) and check it * +*************************************************/ + +static pcre_uint8 * +read_capture_name8(pcre_uint8 *p, pcre_uint8 **pp, pcre *re) +{ +pcre_uint8 *npp = *pp; +while (isalnum(*p)) *npp++ = *p++; +*npp++ = 0; +*npp = 0; +if (pcre_get_stringnumber(re, (char *)(*pp)) < 0) + { + fprintf(outfile, "no parentheses with name \""); + PCHARSV(*pp, 0, -1, outfile); + fprintf(outfile, "\"\n"); } -return yield; +*pp = npp; +return p; } +#endif /* SUPPORT_PCRE8 */ + + + +#ifdef SUPPORT_PCRE16 +/************************************************* +* Read a capture name (16-bit) and check it * +*************************************************/ + +/* Note that the text being read is 8-bit. */ + +static pcre_uint8 * +read_capture_name16(pcre_uint8 *p, pcre_uint16 **pp, pcre *re) +{ +pcre_uint16 *npp = *pp; +while (isalnum(*p)) *npp++ = *p++; +*npp++ = 0; +*npp = 0; +if (pcre16_get_stringnumber((pcre16 *)re, (PCRE_SPTR16)(*pp)) < 0) + { + fprintf(outfile, "no parentheses with name \""); + PCHARSV(*pp, 0, -1, outfile); + fprintf(outfile, "\"\n"); + } +*pp = npp; +return p; +} +#endif /* SUPPORT_PCRE16 */ @@ -872,7 +1615,7 @@ else { fprintf(f, "%2d: ", i/2); - (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i], + PCHARSV(cb->subject, cb->offset_vector[i], cb->offset_vector[i+1] - cb->offset_vector[i], f); fprintf(f, "\n"); } @@ -885,13 +1628,13 @@ if (f != NULL) fprintf(f, "--->"); -pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f); -post_start = pchars((unsigned char *)(cb->subject + cb->start_match), +PCHARS(pre_start, cb->subject, 0, cb->start_match, f); +PCHARS(post_start, cb->subject, cb->start_match, cb->current_position - cb->start_match, f); -subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL); +PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL); -(void)pchars((unsigned char *)(cb->subject + cb->current_position), +PCHARSV(cb->subject, cb->current_position, cb->subject_length - cb->current_position, f); if (f != NULL) fprintf(f, "\n"); @@ -928,6 +1671,19 @@ fprintf(outfile, "\n"); first_callout = 0; +if (cb->mark != last_callout_mark) + { + if (cb->mark == NULL) + fprintf(outfile, "Latest Mark: \n"); + else + { + fprintf(outfile, "Latest Mark: "); + PCHARSV(cb->mark, 0, -1, outfile); + putc('\n', outfile); + } + last_callout_mark = cb->mark; + } + if (cb->callout_data != NULL) { int callout_data = *((int *)(cb->callout_data)); @@ -947,13 +1703,15 @@ * Local malloc functions * *************************************************/ -/* Alternative malloc function, to test functionality and show the size of the -compiled re. */ +/* Alternative malloc function, to test functionality and save the size of a +compiled re, which is the first store request that pcre_compile() makes. The +show_malloc variable is set only during matching. */ static void *new_malloc(size_t size) { void *block = malloc(size); gotten_store = size; +if (first_gotten_store == 0) first_gotten_store = size; if (show_malloc) fprintf(outfile, "malloc %3d %p\n", (int)size, block); return block; @@ -966,7 +1724,6 @@ free(block); } - /* For recursion malloc/free, to test stacking calls */ static void *stack_malloc(size_t size) @@ -989,31 +1746,270 @@ * Call pcre_fullinfo() * *************************************************/ -/* Get one piece of information from the pcre_fullinfo() function */ +/* Get one piece of information from the pcre_fullinfo() function. When only +one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct +value, but the code is defensive. + +Arguments: + re compiled regex + study study data + option PCRE_INFO_xxx option + ptr where to put the data + +Returns: 0 when OK, < 0 on error +*/ -static void new_info(pcre *re, pcre_extra *study, int option, void *ptr) +static int +new_info(pcre *re, pcre_extra *study, int option, void *ptr) { int rc; -if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0) - fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option); + +if (use_pcre16) +#ifdef SUPPORT_PCRE16 + rc = pcre16_fullinfo((pcre16 *)re, (pcre16_extra *)study, option, ptr); +#else + rc = PCRE_ERROR_BADMODE; +#endif +else +#ifdef SUPPORT_PCRE8 + rc = pcre_fullinfo(re, study, option, ptr); +#else + rc = PCRE_ERROR_BADMODE; +#endif + +if (rc < 0) + { + fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, + use_pcre16? "16" : "", option); + if (rc == PCRE_ERROR_BADMODE) + fprintf(outfile, "Running in %s-bit mode but pattern was compiled in " + "%s-bit mode\n", use_pcre16? "16":"8", use_pcre16? "8":"16"); + } + +return rc; } /************************************************* -* Byte flipping function * +* Swap byte functions * *************************************************/ -static unsigned long int -byteflip(unsigned long int value, int n) +/* The following functions swap the bytes of a pcre_uint16 and pcre_uint32 +value, respectively. + +Arguments: + value any number + +Returns: the byte swapped value +*/ + +static pcre_uint32 +swap_uint32(pcre_uint32 value) { -if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | - ((value & 0xff000000) >> 24); + (value >> 24); } +static pcre_uint16 +swap_uint16(pcre_uint16 value) +{ +return (value >> 8) | (value << 8); +} + + + +/************************************************* +* Flip bytes in a compiled pattern * +*************************************************/ + +/* This function is called if the 'F' option was present on a pattern that is +to be written to a file. We flip the bytes of all the integer fields in the +regex data block and the study block. In 16-bit mode this also flips relevant +bytes in the pattern itself. This is to make it possible to test PCRE's +ability to reload byte-flipped patterns, e.g. those compiled on a different +architecture. */ + +static void +regexflip(pcre *ere, pcre_extra *extra) +{ +REAL_PCRE *re = (REAL_PCRE *)ere; +#ifdef SUPPORT_PCRE16 +int op; +pcre_uint16 *ptr = (pcre_uint16 *)re + re->name_table_offset; +int length = re->name_count * re->name_entry_size; +#ifdef SUPPORT_UTF +BOOL utf = (re->options & PCRE_UTF16) != 0; +BOOL utf16_char = FALSE; +#endif /* SUPPORT_UTF */ +#endif /* SUPPORT_PCRE16 */ + +/* Always flip the bytes in the main data block and study blocks. */ + +re->magic_number = REVERSED_MAGIC_NUMBER; +re->size = swap_uint32(re->size); +re->options = swap_uint32(re->options); +re->flags = swap_uint16(re->flags); +re->top_bracket = swap_uint16(re->top_bracket); +re->top_backref = swap_uint16(re->top_backref); +re->first_char = swap_uint16(re->first_char); +re->req_char = swap_uint16(re->req_char); +re->name_table_offset = swap_uint16(re->name_table_offset); +re->name_entry_size = swap_uint16(re->name_entry_size); +re->name_count = swap_uint16(re->name_count); + +if (extra != NULL) + { + pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); + rsd->size = swap_uint32(rsd->size); + rsd->flags = swap_uint32(rsd->flags); + rsd->minlength = swap_uint32(rsd->minlength); + } + +/* In 8-bit mode, that is all we need to do. In 16-bit mode we must swap bytes +in the name table, if present, and then in the pattern itself. */ + +#ifdef SUPPORT_PCRE16 +if (!use_pcre16) return; + +while(TRUE) + { + /* Swap previous characters. */ + while (length-- > 0) + { + *ptr = swap_uint16(*ptr); + ptr++; + } +#ifdef SUPPORT_UTF + if (utf16_char) + { + if ((ptr[-1] & 0xfc00) == 0xd800) + { + /* We know that there is only one extra character in UTF-16. */ + *ptr = swap_uint16(*ptr); + ptr++; + } + } + utf16_char = FALSE; +#endif /* SUPPORT_UTF */ + + /* Get next opcode. */ + + length = 0; + op = *ptr; + *ptr++ = swap_uint16(op); + + switch (op) + { + case OP_END: + return; + +#ifdef SUPPORT_UTF + case OP_CHAR: + case OP_CHARI: + case OP_NOT: + case OP_NOTI: + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_QUERY: + case OP_MINQUERY: + case OP_UPTO: + case OP_MINUPTO: + case OP_EXACT: + case OP_POSSTAR: + case OP_POSPLUS: + case OP_POSQUERY: + case OP_POSUPTO: + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_QUERYI: + case OP_MINQUERYI: + case OP_UPTOI: + case OP_MINUPTOI: + case OP_EXACTI: + case OP_POSSTARI: + case OP_POSPLUSI: + case OP_POSQUERYI: + case OP_POSUPTOI: + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTQUERY: + case OP_NOTMINQUERY: + case OP_NOTUPTO: + case OP_NOTMINUPTO: + case OP_NOTEXACT: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + case OP_NOTPOSQUERY: + case OP_NOTPOSUPTO: + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTQUERYI: + case OP_NOTMINQUERYI: + case OP_NOTUPTOI: + case OP_NOTMINUPTOI: + case OP_NOTEXACTI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + case OP_NOTPOSQUERYI: + case OP_NOTPOSUPTOI: + if (utf) utf16_char = TRUE; +#endif + /* Fall through. */ + + default: + length = OP_lengths16[op] - 1; + break; + + case OP_CLASS: + case OP_NCLASS: + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uint16); + length = 0; + break; + + case OP_XCLASS: + /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ + if (LINK_SIZE > 1) + length = (int)((((unsigned int)(ptr[0]) << 16) | (unsigned int)(ptr[1])) + - (1 + LINK_SIZE + 1)); + else + length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1)); + + /* Reverse the size of the XCLASS instance. */ + *ptr = swap_uint16(*ptr); + ptr++; + if (LINK_SIZE > 1) + { + *ptr = swap_uint16(*ptr); + ptr++; + } + + op = *ptr; + *ptr = swap_uint16(op); + ptr++; + if ((op & XCL_MAP) != 0) + { + /* Skip the character bit map. */ + ptr += 32/sizeof(pcre_uint16); + length -= 32/sizeof(pcre_uint16); + } + break; + } + } +/* Control should never reach here in 16 bit mode. */ +#endif /* SUPPORT_PCRE16 */ +} @@ -1022,7 +2018,7 @@ *************************************************/ static int -check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len, +check_match_limit(pcre *re, pcre_extra *extra, pcre_uint8 *bptr, int len, int start_offset, int options, int *use_offsets, int use_size_offsets, int flag, unsigned long int *limit, int errnumber, const char *msg) { @@ -1037,7 +2033,7 @@ { *limit = mid; - count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, + PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, use_offsets, use_size_offsets); if (count == errnumber) @@ -1082,7 +2078,7 @@ */ static int -strncmpic(uschar *s, uschar *t, int n) +strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n) { while (n--) { @@ -1109,15 +2105,15 @@ */ static int -check_newline(uschar *p, FILE *f) +check_newline(pcre_uint8 *p, FILE *f) { -if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR; -if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF; -if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF; -if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF; -if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY; -if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF; -if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE; +if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR; +if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF; +if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF; +if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF; +if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY; +if (strncmpic(p, (pcre_uint8 *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF; +if (strncmpic(p, (pcre_uint8 *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE; fprintf(f, "Unknown newline type at: <%s\n", p); return 0; } @@ -1133,14 +2129,26 @@ { printf("Usage: pcretest [options] [ []]\n\n"); printf("Input and output default to stdin and stdout.\n"); -#ifdef SUPPORT_LIBREADLINE +#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT) printf("If input is a terminal, readline() is used to read from it.\n"); #else printf("This version of pcretest is not linked with readline().\n"); #endif printf("\nOptions:\n"); -printf(" -b show compiled code (bytecode)\n"); +#ifdef SUPPORT_PCRE16 +printf(" -16 use the 16-bit library\n"); +#endif +printf(" -b show compiled code\n"); printf(" -C show PCRE compile-time options and exit\n"); +printf(" -C arg show a specific compile-time option\n"); +printf(" and exit with its value. The arg can be:\n"); +printf(" linksize internal link size [2, 3, 4]\n"); +printf(" pcre8 8 bit library support enabled [0, 1]\n"); +printf(" pcre16 16 bit library support enabled [0, 1]\n"); +printf(" utf Unicode Transformation Format supported [0, 1]\n"); +printf(" ucp Unicode Properties supported [0, 1]\n"); +printf(" jit Just-in-time compiler supported [0, 1]\n"); +printf(" newline Newline type [CR, LF, CRLF, ANYCRLF, ANY, ???]\n"); printf(" -d debug: show compiled code and information (-b and -i)\n"); #if !defined NODFA printf(" -dfa force DFA matching for all subjects\n"); @@ -1155,7 +2163,12 @@ #endif printf(" -q quiet: do not output PCRE version number at start\n"); printf(" -S set stack size to megabytes\n"); -printf(" -s output store (memory) used information\n" +printf(" -s force each pattern to be studied at basic level\n" + " -s+ force each pattern to be studied, using JIT if available\n" + " -s++ ditto, verifying when JIT was actually used\n" + " -s+n force each pattern to be studied, using JIT if available,\n" + " where 1 <= n <= 7 selects JIT options\n" + " -s++n ditto, verifying when JIT was actually used\n" " -t time compilation and execution\n"); printf(" -t time compilation and execution, repeating times\n"); printf(" -tm time execution (matching) only\n"); @@ -1175,7 +2188,8 @@ int main(int argc, char **argv) { FILE *infile = stdin; -long int options = 0; +const char *version; +int options = 0; int study_options = 0; int default_find_match_limit = FALSE; int op = 1; @@ -1183,34 +2197,56 @@ int timeitm = 0; int showinfo = 0; int showstore = 0; +int force_study = -1; +int force_study_options = 0; int quiet = 0; int size_offsets = 45; int size_offsets_max; int *offsets = NULL; -#if !defined NOPOSIX -int posix = 0; -#endif int debug = 0; int done = 0; int all_use_dfa = 0; +int verify_jit = 0; int yield = 0; int stack_size; -/* These vectors store, end-to-end, a list of captured substring names. Assume -that 1024 is plenty long enough for the few names we'll be testing. */ +#if !defined NOPOSIX +int posix = 0; +#endif +#if !defined NODFA +int *dfa_workspace = NULL; +#endif -uschar copynames[1024]; -uschar getnames[1024]; +pcre_jit_stack *jit_stack = NULL; -uschar *copynamesptr; -uschar *getnamesptr; +/* These vectors store, end-to-end, a list of zero-terminated captured +substring names, each list itself being terminated by an empty name. Assume +that 1024 is plenty long enough for the few names we'll be testing. It is +easiest to keep separate 8-bit and 16-bit versions, using the 16-bit version +for the actual memory, to ensure alignment. */ + +pcre_uint16 copynames[1024]; +pcre_uint16 getnames[1024]; + +#ifdef SUPPORT_PCRE16 +pcre_uint16 *cn16ptr; +pcre_uint16 *gn16ptr; +#endif -/* Get buffers from malloc() so that Electric Fence will check their misuse -when I am debugging. They grow automatically when very long lines are read. */ +#ifdef SUPPORT_PCRE8 +pcre_uint8 *copynames8 = (pcre_uint8 *)copynames; +pcre_uint8 *getnames8 = (pcre_uint8 *)getnames; +pcre_uint8 *cn8ptr; +pcre_uint8 *gn8ptr; +#endif -buffer = (unsigned char *)malloc(buffer_size); -dbuffer = (unsigned char *)malloc(buffer_size); -pbuffer = (unsigned char *)malloc(buffer_size); +/* Get buffers from malloc() so that valgrind will check their misuse when +debugging. They grow automatically when very long lines are read. The 16-bit +buffer (buffer16) is obtained only if needed. */ + +buffer = (pcre_uint8 *)malloc(buffer_size); +dbuffer = (pcre_uint8 *)malloc(buffer_size); +pbuffer = (pcre_uint8 *)malloc(buffer_size); /* The outfile variable is static so that new_malloc can use it. */ @@ -1225,34 +2261,65 @@ _setmode( _fileno( stdout ), _O_BINARY ); #endif +/* Get the version number: both pcre_version() and pcre16_version() give the +same answer. We just need to ensure that we call one that is available. */ + +#ifdef SUPPORT_PCRE8 +version = pcre_version(); +#else +version = pcre16_version(); +#endif + /* Scan options */ while (argc > 1 && argv[op][0] == '-') { - unsigned char *endptr; + pcre_uint8 *endptr; + char *arg = argv[op]; + + if (strcmp(arg, "-m") == 0) showstore = 1; + else if (strcmp(arg, "-s") == 0) force_study = 0; - if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) - showstore = 1; - else if (strcmp(argv[op], "-q") == 0) quiet = 1; - else if (strcmp(argv[op], "-b") == 0) debug = 1; - else if (strcmp(argv[op], "-i") == 0) showinfo = 1; - else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; - else if (strcmp(argv[op], "-M") == 0) default_find_match_limit = TRUE; + else if (strncmp(arg, "-s+", 3) == 0) + { + arg += 3; + if (*arg == '+') { arg++; verify_jit = TRUE; } + force_study = 1; + if (*arg == 0) + force_study_options = jit_study_bits[6]; + else if (*arg >= '1' && *arg <= '7') + force_study_options = jit_study_bits[*arg - '1']; + else goto BAD_ARG; + } + else if (strcmp(arg, "-16") == 0) + { +#ifdef SUPPORT_PCRE16 + use_pcre16 = 1; +#else + printf("** This version of PCRE was built without 16-bit support\n"); + exit(1); +#endif + } + else if (strcmp(arg, "-q") == 0) quiet = 1; + else if (strcmp(arg, "-b") == 0) debug = 1; + else if (strcmp(arg, "-i") == 0) showinfo = 1; + else if (strcmp(arg, "-d") == 0) showinfo = debug = 1; + else if (strcmp(arg, "-M") == 0) default_find_match_limit = TRUE; #if !defined NODFA - else if (strcmp(argv[op], "-dfa") == 0) all_use_dfa = 1; + else if (strcmp(arg, "-dfa") == 0) all_use_dfa = 1; #endif - else if (strcmp(argv[op], "-o") == 0 && argc > 2 && - ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), + else if (strcmp(arg, "-o") == 0 && argc > 2 && + ((size_offsets = get_value((pcre_uint8 *)argv[op+1], &endptr)), *endptr == 0)) { op++; argc--; } - else if (strcmp(argv[op], "-t") == 0 || strcmp(argv[op], "-tm") == 0) + else if (strcmp(arg, "-t") == 0 || strcmp(arg, "-tm") == 0) { - int both = argv[op][2] == 0; + int both = arg[2] == 0; int temp; - if (argc > 2 && (temp = get_value((unsigned char *)argv[op+1], &endptr), + if (argc > 2 && (temp = get_value((pcre_uint8 *)argv[op+1], &endptr), *endptr == 0)) { timeitm = temp; @@ -1262,11 +2329,11 @@ else timeitm = LOOPREPEAT; if (both) timeit = timeitm; } - else if (strcmp(argv[op], "-S") == 0 && argc > 2 && - ((stack_size = get_value((unsigned char *)argv[op+1], &endptr)), + else if (strcmp(arg, "-S") == 0 && argc > 2 && + ((stack_size = get_value((pcre_uint8 *)argv[op+1], &endptr)), *endptr == 0)) { -#if defined(_WIN32) || defined(WIN32) +#if defined(_WIN32) || defined(WIN32) || defined(__minix) printf("PCRE: -S not supported on this OS\n"); exit(1); #else @@ -1285,49 +2352,158 @@ #endif } #if !defined NOPOSIX - else if (strcmp(argv[op], "-p") == 0) posix = 1; + else if (strcmp(arg, "-p") == 0) posix = 1; #endif - else if (strcmp(argv[op], "-C") == 0) + else if (strcmp(arg, "-C") == 0) { int rc; unsigned long int lrc; - printf("PCRE version %s\n", pcre_version()); + + if (argc > 2) + { + if (strcmp(argv[op + 1], "linksize") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); + printf("%d\n", rc); + yield = rc; + goto EXIT; + } + if (strcmp(argv[op + 1], "pcre8") == 0) + { +#ifdef SUPPORT_PCRE8 + printf("1\n"); + yield = 1; +#else + printf("0\n"); + yield = 0; +#endif + goto EXIT; + } + if (strcmp(argv[op + 1], "pcre16") == 0) + { +#ifdef SUPPORT_PCRE16 + printf("1\n"); + yield = 1; +#else + printf("0\n"); + yield = 0; +#endif + goto EXIT; + } + if (strcmp(argv[op + 1], "utf") == 0) + { +#ifdef SUPPORT_PCRE8 + (void)pcre_config(PCRE_CONFIG_UTF8, &rc); + printf("%d\n", rc); + yield = rc; +#else + (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); + printf("%d\n", rc); + yield = rc; +#endif + goto EXIT; + } + if (strcmp(argv[op + 1], "ucp") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); + printf("%d\n", rc); + yield = rc; + goto EXIT; + } + if (strcmp(argv[op + 1], "jit") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc); + printf("%d\n", rc); + yield = rc; + goto EXIT; + } + if (strcmp(argv[op + 1], "newline") == 0) + { + (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); + /* Note that these values are always the ASCII values, even + in EBCDIC environments. CR is 13 and NL is 10. */ + printf("%s\n", (rc == 13)? "CR" : + (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" : + (rc == -2)? "ANYCRLF" : + (rc == -1)? "ANY" : "???"); + goto EXIT; + } + printf("Unknown -C option: %s\n", argv[op + 1]); + goto EXIT; + } + + printf("PCRE version %s\n", version); printf("Compiled with\n"); + +/* At least one of SUPPORT_PCRE8 and SUPPORT_PCRE16 will be set. If both +are set, either both UTFs are supported or both are not supported. */ + +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + printf(" 8-bit and 16-bit support\n"); + (void)pcre_config(PCRE_CONFIG_UTF8, &rc); + if (rc) + printf(" UTF-8 and UTF-16 support\n"); + else + printf(" No UTF-8 or UTF-16 support\n"); +#elif defined SUPPORT_PCRE8 + printf(" 8-bit support only\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf(" %sUTF-8 support\n", rc? "" : "No "); - (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); +#else + printf(" 16-bit support only\n"); + (void)pcre16_config(PCRE_CONFIG_UTF16, &rc); + printf(" %sUTF-16 support\n", rc? "" : "No "); +#endif + + (void)PCRE_CONFIG(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf(" %sUnicode properties support\n", rc? "" : "No "); - (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc); + (void)PCRE_CONFIG(PCRE_CONFIG_JIT, &rc); + if (rc) + { + const char *arch; + (void)PCRE_CONFIG(PCRE_CONFIG_JITTARGET, (void *)(&arch)); + printf(" Just-in-time compiler support: %s\n", arch); + } + else + printf(" No just-in-time compiler support\n"); + (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc); /* Note that these values are always the ASCII values, even in EBCDIC environments. CR is 13 and NL is 10. */ printf(" Newline sequence is %s\n", (rc == 13)? "CR" : (rc == 10)? "LF" : (rc == (13<<8 | 10))? "CRLF" : (rc == -2)? "ANYCRLF" : (rc == -1)? "ANY" : "???"); - (void)pcre_config(PCRE_CONFIG_BSR, &rc); + (void)PCRE_CONFIG(PCRE_CONFIG_BSR, &rc); printf(" \\R matches %s\n", rc? "CR, LF, or CRLF only" : "all Unicode newlines"); - (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc); + (void)PCRE_CONFIG(PCRE_CONFIG_LINK_SIZE, &rc); printf(" Internal link size = %d\n", rc); - (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); + (void)PCRE_CONFIG(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); - (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &lrc); + (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT, &lrc); printf(" Default match limit = %ld\n", lrc); - (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc); + (void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc); printf(" Default recursion depth limit = %ld\n", lrc); - (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); - printf(" Match recursion uses %s\n", rc? "stack" : "heap"); + (void)PCRE_CONFIG(PCRE_CONFIG_STACKRECURSE, &rc); + printf(" Match recursion uses %s", rc? "stack" : "heap"); + if (showstore) + { + PCRE_EXEC(stack_size, NULL, NULL, NULL, -999, -999, 0, NULL, 0); + printf(": %sframe size = %d bytes", rc? "approximate " : "", -stack_size); + } + printf("\n"); goto EXIT; } - else if (strcmp(argv[op], "-help") == 0 || - strcmp(argv[op], "--help") == 0) + else if (strcmp(arg, "-help") == 0 || + strcmp(arg, "--help") == 0) { usage(); goto EXIT; } else { - printf("** Unknown or malformed option %s\n", argv[op]); + BAD_ARG: + printf("** Unknown or malformed option %s\n", arg); usage(); yield = 1; goto EXIT; @@ -1374,14 +2550,23 @@ /* Set alternative malloc function */ +#ifdef SUPPORT_PCRE8 pcre_malloc = new_malloc; pcre_free = new_free; pcre_stack_malloc = stack_malloc; pcre_stack_free = stack_free; +#endif + +#ifdef SUPPORT_PCRE16 +pcre16_malloc = new_malloc; +pcre16_free = new_free; +pcre16_stack_malloc = stack_malloc; +pcre16_stack_free = stack_free; +#endif /* Heading line unless quiet, then prompt for first regex if stdin */ -if (!quiet) fprintf(outfile, "PCRE version %s\n\n", pcre_version()); +if (!quiet) fprintf(outfile, "PCRE version %s\n\n", version); /* Main loop */ @@ -1396,23 +2581,31 @@ #endif const char *error; - unsigned char *markptr; - unsigned char *p, *pp, *ppp; - unsigned char *to_file = NULL; - const unsigned char *tables = NULL; + pcre_uint8 *markptr; + pcre_uint8 *p, *pp, *ppp; + pcre_uint8 *to_file = NULL; + const pcre_uint8 *tables = NULL; + unsigned long int get_options; unsigned long int true_size, true_study_size = 0; size_t size, regex_gotten_store; + int do_allcaps = 0; int do_mark = 0; int do_study = 0; + int no_force_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; + int do_showcaprest = 0; int do_flip = 0; int erroroffset, len, delimiter, poffset; - use_utf8 = 0; +#if !defined NODFA + int dfa_matched = 0; +#endif + + use_utf = 0; debug_lengths = 1; if (extend_inputline(infile, buffer, " re> ") == NULL) break; @@ -1427,11 +2620,18 @@ if (*p == '<' && strchr((char *)(p+1), '<') == NULL) { - unsigned long int magic, get_options; - uschar sbuf[8]; + pcre_uint32 magic; + pcre_uint8 sbuf[8]; FILE *f; p++; + if (*p == '!') + { + do_debug = TRUE; + do_showinfo = TRUE; + p++; + } + pp = p + (int)strlen((char *)p); while (isspace(pp[-1])) pp--; *pp = 0; @@ -1443,6 +2643,7 @@ continue; } + first_gotten_store = 0; if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; true_size = @@ -1450,15 +2651,15 @@ true_study_size = (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; - re = (real_pcre *)new_malloc(true_size); - regex_gotten_store = gotten_store; + re = (pcre *)new_malloc(true_size); + regex_gotten_store = first_gotten_store; if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; - magic = ((real_pcre *)re)->magic_number; + magic = ((REAL_PCRE *)re)->magic_number; if (magic != MAGIC_NUMBER) { - if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER) + if (swap_uint32(magic) == MAGIC_NUMBER) { do_flip = 1; } @@ -1470,15 +2671,11 @@ } } - fprintf(outfile, "Compiled regex%s loaded from %s\n", - do_flip? " (byte-inverted)" : "", p); - - /* Need to know if UTF-8 for printing data strings */ + /* We hide the byte-invert info for little and big endian tests. */ + fprintf(outfile, "Compiled pattern%s loaded from %s\n", + do_flip && (p[-1] == '<') ? " (byte-inverted)" : "", p); - new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); - use_utf8 = (get_options & PCRE_UTF8) != 0; - - /* Now see if there is any following study data */ + /* Now see if there is any following study data. */ if (true_study_size != 0) { @@ -1494,7 +2691,10 @@ { FAIL_READ: fprintf(outfile, "Failed to read data from %s\n", p); - if (extra != NULL) new_free(extra); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } if (re != NULL) new_free(re); fclose(f); continue; @@ -1504,12 +2704,33 @@ } else fprintf(outfile, "No study data\n"); + /* Flip the necessary bytes. */ + if (do_flip) + { + int rc; + PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, NULL); + if (rc == PCRE_ERROR_BADMODE) + { + /* Simulate the result of the function call below. */ + fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc, + use_pcre16? "16" : "", PCRE_INFO_OPTIONS); + fprintf(outfile, "Running in %s-bit mode but pattern was compiled in " + "%s-bit mode\n", use_pcre16? "16":"8", use_pcre16? "8":"16"); + continue; + } + } + + /* Need to know if UTF-8 for printing data strings. */ + + if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0) continue; + use_utf = (get_options & PCRE_UTF8) != 0; + fclose(f); goto SHOW_INFO; } /* In-line pattern (the usual case). Get the delimiter and seek the end of - the pattern; if is isn't complete, read more. */ + the pattern; if it isn't complete, read more. */ delimiter = *p++; @@ -1574,7 +2795,11 @@ case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; - case '+': do_showrest = 1; break; + case '+': + if (do_showrest) do_showcaprest = 1; else do_showrest = 1; + break; + + case '=': do_allcaps = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'B': do_debug = 1; break; case 'C': options |= PCRE_AUTO_CALLOUT; break; @@ -1592,13 +2817,36 @@ case 'P': do_posix = 1; break; #endif - case 'S': do_study = 1; break; + case 'S': + if (do_study == 0) + { + do_study = 1; + if (*pp == '+') + { + if (*(++pp) == '+') + { + verify_jit = TRUE; + pp++; + } + if (*pp >= '1' && *pp <= '7') + study_options |= jit_study_bits[*pp++ - '1']; + else + study_options |= jit_study_bits[6]; + } + } + else + { + do_study = 0; + no_force_study = 1; + } + break; + case 'U': options |= PCRE_UNGREEDY; break; case 'W': options |= PCRE_UCP; break; case 'X': options |= PCRE_EXTRA; break; case 'Y': options |= PCRE_NO_START_OPTIMISE; break; case 'Z': debug_lengths = 0; break; - case '8': options |= PCRE_UTF8; use_utf8 = 1; break; + case '8': options |= PCRE_UTF8; use_utf = 1; break; case '?': options |= PCRE_NO_UTF8_CHECK; break; case 'T': @@ -1632,7 +2880,7 @@ goto SKIP_DATA; } locale_set = 1; - tables = pcre_maketables(); + tables = PCRE_MAKETABLES; pp = ppp; break; @@ -1645,7 +2893,7 @@ case '<': { - if (strncmpic(pp, (uschar *)"JS>", 3) == 0) + if (strncmpic(pp, (pcre_uint8 *)"JS>", 3) == 0) { options |= PCRE_JAVASCRIPT_COMPAT; pp += 3; @@ -1673,7 +2921,7 @@ /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over - local character tables. */ + local character tables. Neither does it have 16-bit support. */ #if !defined NOPOSIX if (posix || do_posix) @@ -1689,6 +2937,7 @@ if ((options & PCRE_UCP) != 0) cflags |= REG_UCP; if ((options & PCRE_UNGREEDY) != 0) cflags |= REG_UNGREEDY; + first_gotten_store = 0; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line @@ -1708,7 +2957,36 @@ #endif /* !defined NOPOSIX */ { - unsigned long int get_options; + /* In 16-bit mode, convert the input. */ + +#ifdef SUPPORT_PCRE16 + if (use_pcre16) + { + switch(to16(FALSE, p, options & PCRE_UTF8, (int)strlen((char *)p))) + { + case -1: + fprintf(outfile, "**Failed: invalid UTF-8 string cannot be " + "converted to UTF-16\n"); + goto SKIP_DATA; + + case -2: + fprintf(outfile, "**Failed: character value greater than 0x10ffff " + "cannot be converted to UTF-16\n"); + goto SKIP_DATA; + + case -3: /* "Impossible error" when to16 is called arg1 FALSE */ + fprintf(outfile, "**Failed: character value greater than 0xffff " + "cannot be converted to 16-bit in non-UTF mode\n"); + goto SKIP_DATA; + + default: + break; + } + p = (pcre_uint8 *)buffer16; + } +#endif + + /* Compile many times when timing */ if (timeit > 0) { @@ -1717,7 +2995,7 @@ clock_t start_time = clock(); for (i = 0; i < timeit; i++) { - re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; @@ -1726,7 +3004,8 @@ (double)CLOCKS_PER_SEC); } - re = pcre_compile((char *)p, options, &error, &erroroffset, tables); + first_gotten_store = 0; + PCRE_COMPILE(re, p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ @@ -1757,29 +3036,30 @@ within the regex; check for this so that we know how to process the data lines. */ - new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); - if ((get_options & PCRE_UTF8) != 0) use_utf8 = 1; - - /* Print information if required. There are now two info-returning - functions. The old one has a limited interface and returns only limited - data. Check that it agrees with the newer one. */ - - if (log_store) - fprintf(outfile, "Memory allocation (code space): %d\n", - (int)(gotten_store - - sizeof(real_pcre) - - ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size)); + if (new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options) < 0) + goto SKIP_DATA; + if ((get_options & PCRE_UTF8) != 0) use_utf = 1; /* Extract the size for possible writing before possibly flipping it, and remember the store that was got. */ - true_size = ((real_pcre *)re)->size; - regex_gotten_store = gotten_store; + true_size = ((REAL_PCRE *)re)->size; + regex_gotten_store = first_gotten_store; + + /* Output code size information if requested */ - /* If /S was present, study the regexp to generate additional info to - help with the matching. */ + if (log_store) + fprintf(outfile, "Memory allocation (code space): %d\n", + (int)(first_gotten_store - + sizeof(REAL_PCRE) - + ((REAL_PCRE *)re)->name_count * ((REAL_PCRE *)re)->name_entry_size)); + + /* If -s or /S was present, study the regex to generate additional info to + help with the matching, unless the pattern has the SS option, which + suppresses the effect of /S (used for a few test patterns where studying is + never sensible). */ - if (do_study) + if (do_study || (force_study >= 0 && !no_force_study)) { if (timeit > 0) { @@ -1787,18 +3067,32 @@ clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < timeit; i++) - extra = pcre_study(re, study_options, &error); + { + PCRE_STUDY(extra, re, study_options | force_study_options, &error); + } time_taken = clock() - start_time; - if (extra != NULL) free(extra); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } fprintf(outfile, " Study time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeit) / (double)CLOCKS_PER_SEC); } - extra = pcre_study(re, study_options, &error); + PCRE_STUDY(extra, re, study_options | force_study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra != NULL) + { true_study_size = ((pcre_study_data *)(extra->study_data))->size; + if (log_store) + { + size_t jitsize; + if (new_info(re, extra, PCRE_INFO_JITSIZE, &jitsize) == 0 && + jitsize != 0) + fprintf(outfile, "Memory allocation (JIT code): %d\n", (int)jitsize); + } + } } /* If /K was present, we set up for handling MARK data. */ @@ -1814,51 +3108,14 @@ extra->flags |= PCRE_EXTRA_MARK; } - /* If the 'F' option was present, we flip the bytes of all the integer - fields in the regex data block and the study block. This is to make it - possible to test PCRE's handling of byte-flipped patterns, e.g. those - compiled on a different architecture. */ - - if (do_flip) - { - real_pcre *rre = (real_pcre *)re; - rre->magic_number = - byteflip(rre->magic_number, sizeof(rre->magic_number)); - rre->size = byteflip(rre->size, sizeof(rre->size)); - rre->options = byteflip(rre->options, sizeof(rre->options)); - rre->flags = (pcre_uint16)byteflip(rre->flags, sizeof(rre->flags)); - rre->top_bracket = - (pcre_uint16)byteflip(rre->top_bracket, sizeof(rre->top_bracket)); - rre->top_backref = - (pcre_uint16)byteflip(rre->top_backref, sizeof(rre->top_backref)); - rre->first_byte = - (pcre_uint16)byteflip(rre->first_byte, sizeof(rre->first_byte)); - rre->req_byte = - (pcre_uint16)byteflip(rre->req_byte, sizeof(rre->req_byte)); - rre->name_table_offset = (pcre_uint16)byteflip(rre->name_table_offset, - sizeof(rre->name_table_offset)); - rre->name_entry_size = (pcre_uint16)byteflip(rre->name_entry_size, - sizeof(rre->name_entry_size)); - rre->name_count = (pcre_uint16)byteflip(rre->name_count, - sizeof(rre->name_count)); - - if (extra != NULL) - { - pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); - rsd->size = byteflip(rsd->size, sizeof(rsd->size)); - rsd->flags = byteflip(rsd->flags, sizeof(rsd->flags)); - rsd->minlength = byteflip(rsd->minlength, sizeof(rsd->minlength)); - } - } - - /* Extract information from the compiled data if required */ + /* Extract and display information from the compiled data if required. */ SHOW_INFO: if (do_debug) { fprintf(outfile, "------------------------------------------------------------------\n"); - pcre_printint(re, outfile, debug_lengths); + PCRE_PRINTINT(re, outfile, debug_lengths); } /* We already have the options in get_options (see above) */ @@ -1866,45 +3123,25 @@ if (do_showinfo) { unsigned long int all_options; -#if !defined NOINFOCHECK - int old_first_char, old_options, old_count; -#endif int count, backrefmax, first_char, need_char, okpartial, jchanged, - hascrorlf; + hascrorlf, maxlookbehind; int nameentrysize, namecount; - const uschar *nametable; + const pcre_uint8 *nametable; - new_info(re, NULL, PCRE_INFO_SIZE, &size); - new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); - new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); - new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char); - new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); - new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); - new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); - new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); - new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial); - new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged); - new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf); - -#if !defined NOINFOCHECK - old_count = pcre_info(re, &old_options, &old_first_char); - if (count < 0) fprintf(outfile, - "Error %d from pcre_info()\n", count); - else - { - if (old_count != count) fprintf(outfile, - "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, - old_count); - - if (old_first_char != first_char) fprintf(outfile, - "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", - first_char, old_first_char); - - if (old_options != (int)get_options) fprintf(outfile, - "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", - get_options, old_options); - } -#endif + if (new_info(re, NULL, PCRE_INFO_SIZE, &size) + + new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) + + new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax) + + new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char) + + new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char) + + new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize) + + new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount) + + new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable) + + new_info(re, NULL, PCRE_INFO_OKPARTIAL, &okpartial) + + new_info(re, NULL, PCRE_INFO_JCHANGED, &jchanged) + + new_info(re, NULL, PCRE_INFO_HASCRORLF, &hascrorlf) + + new_info(re, NULL, PCRE_INFO_MAXLOOKBEHIND, &maxlookbehind) + != 0) + goto SKIP_DATA; if (size != regex_gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", @@ -1919,18 +3156,36 @@ fprintf(outfile, "Named capturing subpatterns:\n"); while (namecount-- > 0) { - fprintf(outfile, " %s %*s%3d\n", nametable + 2, - nameentrysize - 3 - (int)strlen((char *)nametable + 2), "", - GET2(nametable, 0)); +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + int imm2_size = use_pcre16 ? 1 : 2; +#else + int imm2_size = IMM2_SIZE; +#endif + int length = (int)STRLEN(nametable + imm2_size); + fprintf(outfile, " "); + PCHARSV(nametable, imm2_size, length, outfile); + while (length++ < nameentrysize - imm2_size) putc(' ', outfile); +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + fprintf(outfile, "%3d\n", use_pcre16? + (int)(((PCRE_SPTR16)nametable)[0]) + :((int)nametable[0] << 8) | (int)nametable[1]); + nametable += nameentrysize * (use_pcre16 ? 2 : 1); +#else + fprintf(outfile, "%3d\n", GET2(nametable, 0)); +#ifdef SUPPORT_PCRE8 nametable += nameentrysize; +#else + nametable += nameentrysize * 2; +#endif +#endif } } if (!okpartial) fprintf(outfile, "Partial matching not supported\n"); if (hascrorlf) fprintf(outfile, "Contains explicit CR or LF match\n"); - all_options = ((real_pcre *)re)->options; - if (do_flip) all_options = byteflip(all_options, sizeof(all_options)); + all_options = ((REAL_PCRE *)re)->options; + if (do_flip) all_options = swap_uint32(all_options); if (get_options == 0) fprintf(outfile, "No options\n"); else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", @@ -1946,9 +3201,9 @@ ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "", - ((get_options & PCRE_UTF8) != 0)? " utf8" : "", + ((get_options & PCRE_UTF8) != 0)? " utf" : "", ((get_options & PCRE_UCP) != 0)? " ucp" : "", - ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : "", + ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf_check" : "", ((get_options & PCRE_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "", ((get_options & PCRE_DUPNAMES) != 0)? " dupnames" : ""); @@ -1990,13 +3245,18 @@ } else { - int ch = first_char & 255; - const char *caseless = ((first_char & REQ_CASELESS) == 0)? + const char *caseless = + ((((REAL_PCRE *)re)->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)"; - if (PRINTHEX(ch)) - fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); + + if (PRINTOK(first_char)) + fprintf(outfile, "First char = \'%c\'%s\n", first_char, caseless); else - fprintf(outfile, "First char = %d%s\n", ch, caseless); + { + fprintf(outfile, "First char = "); + pchar(first_char, outfile); + fprintf(outfile, "%s\n", caseless); + } } if (need_char < 0) @@ -2005,62 +3265,93 @@ } else { - int ch = need_char & 255; - const char *caseless = ((need_char & REQ_CASELESS) == 0)? + const char *caseless = + ((((REAL_PCRE *)re)->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)"; - if (PRINTHEX(ch)) - fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); + + if (PRINTOK(need_char)) + fprintf(outfile, "Need char = \'%c\'%s\n", need_char, caseless); else - fprintf(outfile, "Need char = %d%s\n", ch, caseless); + { + fprintf(outfile, "Need char = "); + pchar(need_char, outfile); + fprintf(outfile, "%s\n", caseless); + } } + if (maxlookbehind > 0) + fprintf(outfile, "Max lookbehind = %d\n", maxlookbehind); + /* Don't output study size; at present it is in any case a fixed value, but it varies, depending on the computer architecture, and so messes up the test suite. (And with the /F option, it might be - flipped.) */ + flipped.) If study was forced by an external -s, don't show this + information unless -i or -d was also present. This means that, except + when auto-callouts are involved, the output from runs with and without + -s should be identical. */ - if (do_study) + if (do_study || (force_study >= 0 && showinfo && !no_force_study)) { if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else { - uschar *start_bits = NULL; + pcre_uint8 *start_bits = NULL; int minlength; - new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength); - fprintf(outfile, "Subject length lower bound = %d\n", minlength); + if (new_info(re, extra, PCRE_INFO_MINLENGTH, &minlength) == 0) + fprintf(outfile, "Subject length lower bound = %d\n", minlength); - new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); - if (start_bits == NULL) - fprintf(outfile, "No set of starting bytes\n"); - else + if (new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits) == 0) { - int i; - int c = 24; - fprintf(outfile, "Starting byte set: "); - for (i = 0; i < 256; i++) + if (start_bits == NULL) + fprintf(outfile, "No set of starting bytes\n"); + else { - if ((start_bits[i/8] & (1<<(i&7))) != 0) + int i; + int c = 24; + fprintf(outfile, "Starting byte set: "); + for (i = 0; i < 256; i++) { - if (c > 75) - { - fprintf(outfile, "\n "); - c = 2; - } - if (PRINTHEX(i) && i != ' ') + if ((start_bits[i/8] & (1<<(i&7))) != 0) { - fprintf(outfile, "%c ", i); - c += 2; - } - else - { - fprintf(outfile, "\\x%02x ", i); - c += 5; + if (c > 75) + { + fprintf(outfile, "\n "); + c = 2; + } + if (PRINTOK(i) && i != ' ') + { + fprintf(outfile, "%c ", i); + c += 2; + } + else + { + fprintf(outfile, "\\x%02x ", i); + c += 5; + } } } + fprintf(outfile, "\n"); } - fprintf(outfile, "\n"); + } + } + + /* Show this only if the JIT was set by /S, not by -s. */ + + if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0) + { + int jit; + if (new_info(re, extra, PCRE_INFO_JIT, &jit) == 0) + { + if (jit) + fprintf(outfile, "JIT study was successful\n"); + else +#ifdef SUPPORT_JIT + fprintf(outfile, "JIT study was not successful\n"); +#else + fprintf(outfile, "JIT support is not available in this version of PCRE\n"); +#endif } } } @@ -2079,16 +3370,17 @@ } else { - uschar sbuf[8]; - sbuf[0] = (uschar)((true_size >> 24) & 255); - sbuf[1] = (uschar)((true_size >> 16) & 255); - sbuf[2] = (uschar)((true_size >> 8) & 255); - sbuf[3] = (uschar)((true_size) & 255); - - sbuf[4] = (uschar)((true_study_size >> 24) & 255); - sbuf[5] = (uschar)((true_study_size >> 16) & 255); - sbuf[6] = (uschar)((true_study_size >> 8) & 255); - sbuf[7] = (uschar)((true_study_size) & 255); + pcre_uint8 sbuf[8]; + + if (do_flip) regexflip(re, extra); + sbuf[0] = (pcre_uint8)((true_size >> 24) & 255); + sbuf[1] = (pcre_uint8)((true_size >> 16) & 255); + sbuf[2] = (pcre_uint8)((true_size >> 8) & 255); + sbuf[3] = (pcre_uint8)((true_size) & 255); + sbuf[4] = (pcre_uint8)((true_study_size >> 24) & 255); + sbuf[5] = (pcre_uint8)((true_study_size >> 16) & 255); + sbuf[6] = (pcre_uint8)((true_study_size >> 8) & 255); + sbuf[7] = (pcre_uint8)((true_study_size) & 255); if (fwrite(sbuf, 1, 8, f) < 8 || fwrite(re, 1, true_size, f) < true_size) @@ -2097,7 +3389,10 @@ } else { - fprintf(outfile, "Compiled regex written to %s\n", to_file); + fprintf(outfile, "Compiled pattern written to %s\n", to_file); + + /* If there is study data, write it. */ + if (extra != NULL) { if (fwrite(extra->study_data, 1, true_study_size, f) < @@ -2107,14 +3402,16 @@ strerror(errno)); } else fprintf(outfile, "Study data written to %s\n", to_file); - } } fclose(f); } new_free(re); - if (extra != NULL) new_free(extra); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } if (locale_set) { new_free((void *)tables); @@ -2129,8 +3426,8 @@ for (;;) { - uschar *q; - uschar *bptr; + pcre_uint8 *q; + pcre_uint8 *bptr; int *use_offsets = offsets; int use_size_offsets = size_offsets; int callout_data = 0; @@ -2146,21 +3443,27 @@ int g_notempty = 0; int use_dfa = 0; - options = 0; - *copynames = 0; *getnames = 0; - copynamesptr = copynames; - getnamesptr = getnames; +#ifdef SUPPORT_PCRE16 + cn16ptr = copynames; + gn16ptr = getnames; +#endif +#ifdef SUPPORT_PCRE8 + cn8ptr = copynames8; + gn8ptr = getnames8; +#endif - pcre_callout = callout; + SET_PCRE_CALLOUT(callout); first_callout = 1; + last_callout_mark = NULL; callout_extra = 0; callout_count = 0; callout_fail_count = 999999; callout_fail_id = -1; show_malloc = 0; + options = 0; if (extra != NULL) extra->flags &= ~(PCRE_EXTRA_MATCH_LIMIT|PCRE_EXTRA_MATCH_LIMIT_RECURSION); @@ -2196,7 +3499,23 @@ int i = 0; int n = 0; - if (c == '\\') switch ((c = *p++)) + /* In UTF mode, input can be UTF-8, so just copy all non-backslash bytes. + In non-UTF mode, allow the value of the byte to fall through to later, + where values greater than 127 are turned into UTF-8 when running in + 16-bit mode. */ + + if (c != '\\') + { + if (use_utf) + { + *q++ = c; + continue; + } + } + + /* Handle backslash escapes */ + + else switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; @@ -2212,62 +3531,51 @@ c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; - -#if !defined NOUTF8 - if (use_utf8 && c > 255) - { - unsigned char buff8[8]; - int ii, utn; - utn = ord2utf8(c, buff8); - for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; - c = buff8[ii]; /* Last byte */ - } -#endif break; case 'x': - - /* Handle \x{..} specially - new Perl thing for utf8 */ - -#if !defined NOUTF8 if (*p == '{') { - unsigned char *pt = p; + pcre_uint8 *pt = p; c = 0; - while (isxdigit(*(++pt))) - c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); + + /* We used to have "while (isxdigit(*(++pt)))" here, but it fails + when isxdigit() is a macro that refers to its argument more than + once. This is banned by the C Standard, but apparently happens in at + least one MacOS environment. */ + + for (pt++; isxdigit(*pt); pt++) + { + if (++i == 9) + fprintf(outfile, "** Too many hex digits in \\x{...} item; " + "using only the first eight.\n"); + else c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'a' - 10); + } if (*pt == '}') { - unsigned char buff8[8]; - int ii, utn; - if (use_utf8) - { - utn = ord2utf8(c, buff8); - for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; - c = buff8[ii]; /* Last byte */ - } - else - { - if (c > 255) - fprintf(outfile, "** Character \\x{%x} is greater than 255 and " - "UTF-8 mode is not enabled.\n" - "** Truncation will probably give the wrong result.\n", c); - } p = pt + 1; break; } - /* Not correct form; fall through */ + /* Not correct form for \x{...}; fall through */ } -#endif - /* Ordinary \x */ + /* \x without {} always defines just one byte in 8-bit mode. This + allows UTF-8 characters to be constructed byte by byte, and also allows + invalid UTF-8 sequences to be made. Just copy the byte in UTF mode. + Otherwise, pass it down to later code so that it can be turned into + UTF-8 when running in 16-bit mode. */ c = 0; while (i++ < 2 && isxdigit(*p)) { - c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); + c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'a' - 10); p++; } + if (use_utf) + { + *q++ = c; + continue; + } break; case 0: /* \ followed by EOF allows for an empty line */ @@ -2300,14 +3608,7 @@ } else if (isalnum(*p)) { - uschar *npp = copynamesptr; - while (isalnum(*p)) *npp++ = *p++; - *npp++ = 0; - *npp = 0; - n = pcre_get_stringnumber(re, (char *)copynamesptr); - if (n < 0) - fprintf(outfile, "no parentheses with name \"%s\"\n", copynamesptr); - copynamesptr = npp; + READ_CAPTURE_NAME(p, &cn8ptr, &cn16ptr, re); } else if (*p == '+') { @@ -2316,7 +3617,7 @@ } else if (*p == '-') { - pcre_callout = NULL; + SET_PCRE_CALLOUT(NULL); p++; } else if (*p == '!') @@ -2370,14 +3671,19 @@ } else if (isalnum(*p)) { - uschar *npp = getnamesptr; - while (isalnum(*p)) *npp++ = *p++; - *npp++ = 0; - *npp = 0; - n = pcre_get_stringnumber(re, (char *)getnamesptr); - if (n < 0) - fprintf(outfile, "no parentheses with name \"%s\"\n", getnamesptr); - getnamesptr = npp; + READ_CAPTURE_NAME(p, &gn8ptr, &gn16ptr, re); + } + continue; + + case 'J': + while(isdigit(*p)) n = n * 10 + *p++ - '0'; + if (extra != NULL + && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 + && extra->executable_jit != NULL) + { + if (jit_stack != NULL) { PCRE_JIT_STACK_FREE(jit_stack); } + jit_stack = PCRE_JIT_STACK_ALLOC(1, n * 1024); + PCRE_ASSIGN_JIT_STACK(extra, jit_callback, jit_stack); } continue; @@ -2413,6 +3719,7 @@ } use_size_offsets = n; if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ + else use_offsets = offsets + size_offsets_max - n; /* To catch overruns */ continue; case 'P': @@ -2473,8 +3780,38 @@ } continue; } - *q++ = c; + + /* We now have a character value in c that may be greater than 255. In + 16-bit mode, we always convert characters to UTF-8 so that values greater + than 255 can be passed to non-UTF 16-bit strings. In 8-bit mode we + convert to UTF-8 if we are in UTF mode. Values greater than 127 in UTF + mode must have come from \x{...} or octal constructs because values from + \x.. get this far only in non-UTF mode. */ + +#if !defined NOUTF || defined SUPPORT_PCRE16 + if (use_pcre16 || use_utf) + { + pcre_uint8 buff8[8]; + int ii, utn; + utn = ord2utf8(c, buff8); + for (ii = 0; ii < utn; ii++) *q++ = buff8[ii]; + } + else +#endif + { + if (c > 255) + { + fprintf(outfile, "** Character \\x{%x} is greater than 255 " + "and UTF-8 mode is not enabled.\n", c); + fprintf(outfile, "** Truncation will probably give the wrong " + "result.\n"); + } + *q++ = c; + } } + + /* Reached end of subject string */ + *q = 0; len = (int)(q - dbuffer); @@ -2536,13 +3873,13 @@ if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); - (void)pchars(dbuffer + pmatch[i].rm_so, + PCHARSV(dbuffer, pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, outfile); fprintf(outfile, "\n"); - if (i == 0 && do_showrest) + if (do_showcaprest || (i == 0 && do_showrest)) { - fprintf(outfile, " 0+ "); - (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, + fprintf(outfile, "%2d+ ", (int)i); + PCHARSV(dbuffer, pmatch[i].rm_eo, len - pmatch[i].rm_eo, outfile); fprintf(outfile, "\n"); } @@ -2550,16 +3887,51 @@ } } free(pmatch); + goto NEXT_DATA; } +#endif /* !defined NOPOSIX */ + /* Handle matching via the native interface - repeats for /g and /G */ - else -#endif /* !defined NOPOSIX */ +#ifdef SUPPORT_PCRE16 + if (use_pcre16) + { + len = to16(TRUE, bptr, (((REAL_PCRE *)re)->options) & PCRE_UTF8, len); + switch(len) + { + case -1: + fprintf(outfile, "**Failed: invalid UTF-8 string cannot be " + "converted to UTF-16\n"); + goto NEXT_DATA; + + case -2: + fprintf(outfile, "**Failed: character value greater than 0x10ffff " + "cannot be converted to UTF-16\n"); + goto NEXT_DATA; + + case -3: + fprintf(outfile, "**Failed: character value greater than 0xffff " + "cannot be converted to 16-bit in non-UTF mode\n"); + goto NEXT_DATA; + + default: + break; + } + bptr = (pcre_uint8 *)buffer16; + } +#endif + + /* Ensure that there is a JIT callback if we want to verify that JIT was + actually used. If jit_stack == NULL, no stack has yet been assigned. */ + + if (verify_jit && jit_stack == NULL && extra != NULL) + { PCRE_ASSIGN_JIT_STACK(extra, jit_callback, jit_stack); } for (;; gmatched++) /* Loop for /g or /G */ { markptr = NULL; + jit_was_used = FALSE; if (timeitm > 0) { @@ -2570,19 +3942,28 @@ #if !defined NODFA if (all_use_dfa || use_dfa) { - int workspace[1000]; + if ((options & PCRE_DFA_RESTART) != 0) + { + fprintf(outfile, "Timing DFA restarts is not supported\n"); + break; + } + if (dfa_workspace == NULL) + dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); for (i = 0; i < timeitm; i++) - count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, - options | g_notempty, use_offsets, use_size_offsets, workspace, - sizeof(workspace)/sizeof(int)); + { + PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, + (options | g_notempty), use_offsets, use_size_offsets, + dfa_workspace, DFA_WS_DIMENSION); + } } else #endif for (i = 0; i < timeitm; i++) - count = pcre_exec(re, extra, (char *)bptr, len, - start_offset, options | g_notempty, use_offsets, use_size_offsets); - + { + PCRE_EXEC(count, re, extra, bptr, len, start_offset, + (options | g_notempty), use_offsets, use_size_offsets); + } time_taken = clock() - start_time; fprintf(outfile, "Execute time %.4f milliseconds\n", (((double)time_taken * 1000.0) / (double)timeitm) / @@ -2591,7 +3972,10 @@ /* If find_match_limit is set, we want to do repeated matches with varying limits in order to find the minimum value for the match limit and - for the recursion limit. */ + for the recursion limit. The match limits are relevant only to the normal + running of pcre_exec(), so disable the JIT optimization. This makes it + possible to run the same set of tests with and without JIT externally + requested. */ if (find_match_limit) { @@ -2600,6 +3984,7 @@ extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } + else extra->flags &= ~PCRE_EXTRA_EXECUTABLE_JIT; (void)check_match_limit(re, extra, bptr, len, start_offset, options|g_notempty, use_offsets, use_size_offsets, @@ -2623,7 +4008,7 @@ } extra->flags |= PCRE_EXTRA_CALLOUT_DATA; extra->callout_data = &callout_data; - count = pcre_exec(re, extra, (char *)bptr, len, start_offset, + PCRE_EXEC(count, re, extra, bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; } @@ -2634,10 +4019,13 @@ #if !defined NODFA else if (all_use_dfa || use_dfa) { - int workspace[1000]; - count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, - options | g_notempty, use_offsets, use_size_offsets, workspace, - sizeof(workspace)/sizeof(int)); + if (dfa_workspace == NULL) + dfa_workspace = (int *)malloc(DFA_WS_DIMENSION*sizeof(int)); + if (dfa_matched++ == 0) + dfa_workspace[0] = -1; /* To catch bad restart */ + PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, + (options | g_notempty), use_offsets, use_size_offsets, dfa_workspace, + DFA_WS_DIMENSION); if (count == 0) { fprintf(outfile, "Matched, but too many subsidiary matches\n"); @@ -2648,8 +4036,8 @@ else { - count = pcre_exec(re, extra, (char *)bptr, len, - start_offset, options | g_notempty, use_offsets, use_size_offsets); + PCRE_EXEC(count, re, extra, bptr, len, start_offset, + options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); @@ -2662,6 +4050,7 @@ if (count >= 0) { int i, maxcount; + void *cnptr, *gnptr; #if !defined NODFA if (all_use_dfa || use_dfa) maxcount = use_size_offsets/2; else @@ -2683,106 +4072,183 @@ } } + /* do_allcaps requests showing of all captures in the pattern, to check + unset ones at the end. */ + + if (do_allcaps) + { + if (new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count) < 0) + goto SKIP_DATA; + count++; /* Allow for full match */ + if (count * 2 > use_size_offsets) count = use_size_offsets/2; + } + + /* Output the captured substrings */ + for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) + { + if (use_offsets[i] != -1) + fprintf(outfile, "ERROR: bad negative value %d for offset %d\n", + use_offsets[i], i); + if (use_offsets[i+1] != -1) + fprintf(outfile, "ERROR: bad negative value %d for offset %d\n", + use_offsets[i+1], i+1); fprintf(outfile, "%2d: \n", i/2); + } else { fprintf(outfile, "%2d: ", i/2); - (void)pchars(bptr + use_offsets[i], + PCHARSV(bptr, use_offsets[i], use_offsets[i+1] - use_offsets[i], outfile); + if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); - if (i == 0) + if (do_showcaprest || (i == 0 && do_showrest)) { - if (do_showrest) - { - fprintf(outfile, " 0+ "); - (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], - outfile); - fprintf(outfile, "\n"); - } + fprintf(outfile, "%2d+ ", i/2); + PCHARSV(bptr, use_offsets[i+1], len - use_offsets[i+1], + outfile); + fprintf(outfile, "\n"); } } } - if (markptr != NULL) fprintf(outfile, "MK: %s\n", markptr); + if (markptr != NULL) + { + fprintf(outfile, "MK: "); + PCHARSV(markptr, 0, -1, outfile); + fprintf(outfile, "\n"); + } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { + int rc; char copybuffer[256]; - int rc = pcre_copy_substring((char *)bptr, use_offsets, count, - i, copybuffer, sizeof(copybuffer)); + PCRE_COPY_SUBSTRING(rc, bptr, use_offsets, count, i, + copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else - fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); + { + fprintf(outfile, "%2dC ", i); + PCHARSV(copybuffer, 0, rc, outfile); + fprintf(outfile, " (%d)\n", rc); + } } } - for (copynamesptr = copynames; - *copynamesptr != 0; - copynamesptr += (int)strlen((char*)copynamesptr) + 1) + cnptr = copynames; + for (;;) { + int rc; char copybuffer[256]; - int rc = pcre_copy_named_substring(re, (char *)bptr, use_offsets, - count, (char *)copynamesptr, copybuffer, sizeof(copybuffer)); + + if (use_pcre16) + { + if (*(pcre_uint16 *)cnptr == 0) break; + } + else + { + if (*(pcre_uint8 *)cnptr == 0) break; + } + + PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, + cnptr, copybuffer, sizeof(copybuffer)); + if (rc < 0) - fprintf(outfile, "copy substring %s failed %d\n", copynamesptr, rc); + { + fprintf(outfile, "copy substring "); + PCHARSV(cnptr, 0, -1, outfile); + fprintf(outfile, " failed %d\n", rc); + } else - fprintf(outfile, " C %s (%d) %s\n", copybuffer, rc, copynamesptr); + { + fprintf(outfile, " C "); + PCHARSV(copybuffer, 0, rc, outfile); + fprintf(outfile, " (%d) ", rc); + PCHARSV(cnptr, 0, -1, outfile); + putc('\n', outfile); + } + + cnptr = (char *)cnptr + (STRLEN(cnptr) + 1) * CHAR_SIZE; } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { + int rc; const char *substring; - int rc = pcre_get_substring((char *)bptr, use_offsets, count, - i, &substring); + PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { - fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); - pcre_free_substring(substring); + fprintf(outfile, "%2dG ", i); + PCHARSV(substring, 0, rc, outfile); + fprintf(outfile, " (%d)\n", rc); + PCRE_FREE_SUBSTRING(substring); } } } - for (getnamesptr = getnames; - *getnamesptr != 0; - getnamesptr += (int)strlen((char*)getnamesptr) + 1) + gnptr = getnames; + for (;;) { + int rc; const char *substring; - int rc = pcre_get_named_substring(re, (char *)bptr, use_offsets, - count, (char *)getnamesptr, &substring); + + if (use_pcre16) + { + if (*(pcre_uint16 *)gnptr == 0) break; + } + else + { + if (*(pcre_uint8 *)gnptr == 0) break; + } + + PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, use_offsets, count, + gnptr, &substring); if (rc < 0) - fprintf(outfile, "copy substring %s failed %d\n", getnamesptr, rc); + { + fprintf(outfile, "get substring "); + PCHARSV(gnptr, 0, -1, outfile); + fprintf(outfile, " failed %d\n", rc); + } else { - fprintf(outfile, " G %s (%d) %s\n", substring, rc, getnamesptr); - pcre_free_substring(substring); + fprintf(outfile, " G "); + PCHARSV(substring, 0, rc, outfile); + fprintf(outfile, " (%d) ", rc); + PCHARSV(gnptr, 0, -1, outfile); + PCRE_FREE_SUBSTRING(substring); + putc('\n', outfile); } + + gnptr = (char *)gnptr + (STRLEN(gnptr) + 1) * CHAR_SIZE; } if (getlist) { + int rc; const char **stringlist; - int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, - &stringlist); + PCRE_GET_SUBSTRING_LIST(rc, bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) - fprintf(outfile, "%2dL %s\n", i, stringlist[i]); + { + fprintf(outfile, "%2dL ", i); + PCHARSV(stringlist[i], 0, -1, outfile); + putc('\n', outfile); + } if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); - /* free((void *)stringlist); */ - pcre_free_substring_list(stringlist); + PCRE_FREE_SUBSTRING_LIST(stringlist); } } } @@ -2792,13 +4258,18 @@ else if (count == PCRE_ERROR_PARTIAL) { if (markptr == NULL) fprintf(outfile, "Partial match"); - else fprintf(outfile, "Partial match, mark=%s", markptr); + else + { + fprintf(outfile, "Partial match, mark="); + PCHARSV(markptr, 0, -1, outfile); + } if (use_size_offsets > 1) { fprintf(outfile, ": "); - pchars(bptr + use_offsets[0], use_offsets[1] - use_offsets[0], + PCHARSV(bptr, use_offsets[0], use_offsets[1] - use_offsets[0], outfile); } + if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); break; /* Out of the /g loop */ } @@ -2813,7 +4284,7 @@ terminated by CRLF, an advance of one character just passes the \r, whereas we should prefer the longer newline sequence, as does the code in pcre_exec(). Fudge the offset value to achieve this. We check for a - newline setting in the pattern; if none was set, use pcre_config() to + newline setting in the pattern; if none was set, use PCRE_CONFIG() to find the default. Otherwise, in the case of UTF-8 matching, the advance must be one @@ -2824,12 +4295,12 @@ if (g_notempty != 0) { int onechar = 1; - unsigned int obits = ((real_pcre *)re)->options; + unsigned int obits = ((REAL_PCRE *)re)->options; use_offsets[0] = start_offset; if ((obits & PCRE_NEWLINE_BITS) == 0) { int d; - (void)pcre_config(PCRE_CONFIG_NEWLINE, &d); + (void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &d); /* Note that these values are always the ASCII ones, even in EBCDIC environments. CR = 13, NL = 10. */ obits = (d == 13)? PCRE_NEWLINE_CR : @@ -2843,10 +4314,23 @@ (obits & PCRE_NEWLINE_BITS) == PCRE_NEWLINE_ANYCRLF) && start_offset < len - 1 && - bptr[start_offset] == '\r' && - bptr[start_offset+1] == '\n') +#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16 + (use_pcre16? + ((PCRE_SPTR16)bptr)[start_offset] == '\r' + && ((PCRE_SPTR16)bptr)[start_offset + 1] == '\n' + : + bptr[start_offset] == '\r' + && bptr[start_offset + 1] == '\n') +#elif defined SUPPORT_PCRE16 + ((PCRE_SPTR16)bptr)[start_offset] == '\r' + && ((PCRE_SPTR16)bptr)[start_offset + 1] == '\n' +#else + bptr[start_offset] == '\r' + && bptr[start_offset + 1] == '\n' +#endif + ) onechar++; - else if (use_utf8) + else if (use_utf) { while (start_offset + onechar < len) { @@ -2858,15 +4342,50 @@ } else { - if (count == PCRE_ERROR_NOMATCH) + switch(count) { + case PCRE_ERROR_NOMATCH: if (gmatched == 0) { - if (markptr == NULL) fprintf(outfile, "No match\n"); - else fprintf(outfile, "No match, mark = %s\n", markptr); + if (markptr == NULL) + { + fprintf(outfile, "No match"); + } + else + { + fprintf(outfile, "No match, mark = "); + PCHARSV(markptr, 0, -1, outfile); + } + if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)"); + putc('\n', outfile); } + break; + + case PCRE_ERROR_BADUTF8: + case PCRE_ERROR_SHORTUTF8: + fprintf(outfile, "Error %d (%s UTF-%s string)", count, + (count == PCRE_ERROR_BADUTF8)? "bad" : "short", + use_pcre16? "16" : "8"); + if (use_size_offsets >= 2) + fprintf(outfile, " offset=%d reason=%d", use_offsets[0], + use_offsets[1]); + fprintf(outfile, "\n"); + break; + + case PCRE_ERROR_BADUTF8_OFFSET: + fprintf(outfile, "Error %d (bad UTF-%s offset)\n", count, + use_pcre16? "16" : "8"); + break; + + default: + if (count < 0 && + (-count) < (int)(sizeof(errtexts)/sizeof(const char *))) + fprintf(outfile, "Error %d (%s)\n", count, errtexts[-count]); + else + fprintf(outfile, "Error %d (Unexpected value)\n", count); + break; } - else fprintf(outfile, "Error %d\n", count); + break; /* Out of the /g loop */ } } @@ -2898,7 +4417,7 @@ else { - bptr += use_offsets[1]; + bptr += use_offsets[1] * CHAR_SIZE; len -= use_offsets[1]; } } /* End of loop for /g and /G */ @@ -2913,13 +4432,21 @@ #endif if (re != NULL) new_free(re); - if (extra != NULL) new_free(extra); + if (extra != NULL) + { + PCRE_FREE_STUDY(extra); + } if (locale_set) { new_free((void *)tables); setlocale(LC_CTYPE, "C"); locale_set = 0; } + if (jit_stack != NULL) + { + PCRE_JIT_STACK_FREE(jit_stack); + jit_stack = NULL; + } } if (infile == stdin) fprintf(outfile, "\n"); @@ -2934,6 +4461,10 @@ free(pbuffer); free(offsets); +#ifdef SUPPORT_PCRE16 +if (buffer16 != NULL) free(buffer16); +#endif + return yield; } diff -Nru pcre3-8.12/perltest.pl pcre3-8.31/perltest.pl --- pcre3-8.12/perltest.pl 2010-05-12 10:24:04.000000000 +0000 +++ pcre3-8.31/perltest.pl 2012-01-21 16:00:28.000000000 +0000 @@ -1,16 +1,18 @@ #! /usr/bin/env perl # Program for testing regular expressions with perl to check that PCRE handles -# them the same. This is the version that supports /8 for UTF-8 testing. As it -# stands, it requires at least Perl 5.8 for UTF-8 support. However, it needs to -# have "use utf8" at the start for running the UTF-8 tests, but *not* for the -# other tests. The only way I've found for doing this is to cat this line in -# explicitly in the RunPerlTest script. +# them the same. This version supports /8 for UTF-8 testing. However, it needs +# to have "use utf8" at the start for running the UTF-8 tests, but *not* for +# the other tests. The only way I've found for doing this is to cat this line +# in explicitly in the RunPerlTest script. I've also used this method to supply +# "require Encode" for the UTF-8 tests, so that the main test will still run +# where Encode is not installed. # use locale; # With this included, \x0b matches \s! -# Function for turning a string into a string of printing chars. There are -# currently problems with UTF-8 strings; this fudges round them. +# Function for turning a string into a string of printing chars. + +#require Encode; sub pchars { my($t) = ""; @@ -21,10 +23,10 @@ foreach $c (@p) { if ($c >= 32 && $c < 127) { $t .= chr $c; } - else { $t .= sprintf("\\x{%02x}", $c); } + else { $t .= sprintf("\\x{%02x}", $c); + } } } - else { foreach $c (split(//, $_[0])) @@ -87,6 +89,10 @@ $showrest = ($pattern =~ s/\+(?=[a-zA-Z]*$)//); + # A doubled version is used by pcretest to print remainders after captures + + $pattern =~ s/\+(?=[a-zA-Z]*$)//; + # Remove /8 from a UTF-8 pattern. $utf8 = $pattern =~ s/8(?=[a-zA-Z]*$)//; @@ -103,6 +109,14 @@ $pattern =~ s/W(?=[a-zA-Z]*$)//; + # Remove /S or /SS from a pattern (asks pcretest to study or not to study) + + $pattern =~ s/S(?=[a-zA-Z]*$)//g; + + # Remove /Y from a pattern (asks pcretest to disable PCRE optimization) + + $pattern =~ s/Y(?=[a-zA-Z]*$)//; + # Check that the pattern is valid eval "\$_ =~ ${pattern}"; @@ -180,7 +194,7 @@ { printf $outfile "No match"; if (defined $REGERROR && $REGERROR != 1) - { print $outfile (", mark = $REGERROR"); } + { printf $outfile (", mark = %s", &pchars($REGERROR)); } printf $outfile "\n"; } else @@ -202,8 +216,17 @@ } splice(@subs, 0, 18); } + + # It seems that $REGMARK is not marked as UTF-8 even when use utf8 is + # set and the input pattern was a UTF-8 string. We can, however, force + # it to be so marked. + if (defined $REGMARK && $REGMARK != 1) - { print $outfile ("MK: $REGMARK\n"); } + { + $xx = $REGMARK; + $xx = Encode::decode_utf8($xx) if $utf8; + printf $outfile ("MK: %s\n", &pchars($xx)); + } } } } diff -Nru pcre3-8.12/sljit/sljitConfig.h pcre3-8.31/sljit/sljitConfig.h --- pcre3-8.12/sljit/sljitConfig.h 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitConfig.h 2012-03-17 12:18:50.000000000 +0000 @@ -0,0 +1,109 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +#ifndef _SLJIT_CONFIG_H_ +#define _SLJIT_CONFIG_H_ + +/* --------------------------------------------------------------------- */ +/* Custom defines */ +/* --------------------------------------------------------------------- */ + +/* Put your custom defines here. This empty section will never change + which helps maintaining patches (with diff / patch utilities). */ + +/* --------------------------------------------------------------------- */ +/* Architecture */ +/* --------------------------------------------------------------------- */ + +/* Architecture selection. */ +/* #define SLJIT_CONFIG_X86_32 1 */ +/* #define SLJIT_CONFIG_X86_64 1 */ +/* #define SLJIT_CONFIG_ARM_V5 1 */ +/* #define SLJIT_CONFIG_ARM_V7 1 */ +/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ +/* #define SLJIT_CONFIG_PPC_32 1 */ +/* #define SLJIT_CONFIG_PPC_64 1 */ +/* #define SLJIT_CONFIG_MIPS_32 1 */ + +/* #define SLJIT_CONFIG_AUTO 1 */ +/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ + +/* --------------------------------------------------------------------- */ +/* Utilities */ +/* --------------------------------------------------------------------- */ + +/* Useful for thread-safe compiling of global functions. */ +#ifndef SLJIT_UTIL_GLOBAL_LOCK +/* Enabled by default */ +#define SLJIT_UTIL_GLOBAL_LOCK 1 +#endif + +/* Implements a stack like data structure (by using mmap / VirtualAlloc). */ +#ifndef SLJIT_UTIL_STACK +/* Enabled by default */ +#define SLJIT_UTIL_STACK 1 +#endif + +/* Single threaded application. Does not require any locks. */ +#ifndef SLJIT_SINGLE_THREADED +/* Disabled by default. */ +#define SLJIT_SINGLE_THREADED 0 +#endif + +/* --------------------------------------------------------------------- */ +/* Configuration */ +/* --------------------------------------------------------------------- */ + +/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should + define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */ +#ifndef SLJIT_STD_MACROS_DEFINED +/* Disabled by default. */ +#define SLJIT_STD_MACROS_DEFINED 0 +#endif + +/* Executable code allocation: + If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should + define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */ +#ifndef SLJIT_EXECUTABLE_ALLOCATOR +/* Enabled by default. */ +#define SLJIT_EXECUTABLE_ALLOCATOR 1 +#endif + +/* Debug checks (assertions, etc.). */ +#ifndef SLJIT_DEBUG +/* Enabled by default */ +#define SLJIT_DEBUG 1 +#endif + +/* Verbose operations */ +#ifndef SLJIT_VERBOSE +/* Enabled by default */ +#define SLJIT_VERBOSE 1 +#endif + +/* See the beginning of sljitConfigInternal.h */ + +#endif diff -Nru pcre3-8.12/sljit/sljitConfigInternal.h pcre3-8.31/sljit/sljitConfigInternal.h --- pcre3-8.12/sljit/sljitConfigInternal.h 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitConfigInternal.h 2012-05-14 11:01:04.000000000 +0000 @@ -0,0 +1,432 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +#ifndef _SLJIT_CONFIG_INTERNAL_H_ +#define _SLJIT_CONFIG_INTERNAL_H_ + +/* + SLJIT defines the following macros depending on the target architecture: + + Feature detection (boolean) macros: + SLJIT_32BIT_ARCHITECTURE : 32 bit architecture + SLJIT_64BIT_ARCHITECTURE : 64 bit architecture + SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index + SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index + SLJIT_LITTLE_ENDIAN : little endian architecture + SLJIT_BIG_ENDIAN : big endian architecture + SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) + SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information + + Types and useful macros: + sljit_b, sljit_ub : signed and unsigned 8 bit byte + sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type + sljit_i, sljit_ui : signed and unsigned 32 bit integer type + sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t) + SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT + SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) +*/ + +#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) +#error "An architecture must be selected" +#endif + +/* Sanity check. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ + + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 +#error "Multiple architectures are selected" +#endif + +/* Auto select option (requires compiler support) */ +#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) + +#ifndef _WIN32 + +#if defined(__i386__) || defined(__i386) +#define SLJIT_CONFIG_X86_32 1 +#elif defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(__arm__) || defined(__ARM__) +#ifdef __thumb2__ +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) +#define SLJIT_CONFIG_ARM_V7 1 +#else +#define SLJIT_CONFIG_ARM_V5 1 +#endif +#elif defined(__ppc64__) || defined(__powerpc64__) +#define SLJIT_CONFIG_PPC_64 1 +#elif defined(__ppc__) || defined(__powerpc__) +#define SLJIT_CONFIG_PPC_32 1 +#elif defined(__mips__) +#define SLJIT_CONFIG_MIPS_32 1 +#else +/* Unsupported architecture */ +#define SLJIT_CONFIG_UNSUPPORTED 1 +#endif + +#else /* !_WIN32 */ + +#if defined(_M_X64) || defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(_ARM_) +#define SLJIT_CONFIG_ARM_V5 1 +#else +#define SLJIT_CONFIG_X86_32 1 +#endif + +#endif /* !WIN32 */ +#endif /* SLJIT_CONFIG_AUTO */ + +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +#undef SLJIT_EXECUTABLE_ALLOCATOR +#endif + +#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) + +/* These libraries are needed for the macros below. */ +#include +#include + +#endif /* STD_MACROS_DEFINED */ + +/* General macros: + Note: SLJIT is designed to be independent from them as possible. + + In release mode (SLJIT_DEBUG is not defined) only the following macros are needed: +*/ + +#ifndef SLJIT_MALLOC +#define SLJIT_MALLOC(size) malloc(size) +#endif + +#ifndef SLJIT_FREE +#define SLJIT_FREE(ptr) free(ptr) +#endif + +#ifndef SLJIT_MEMMOVE +#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) +#endif + +#ifndef SLJIT_ZEROMEM +#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) +#endif + +#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) + +#if defined(__GNUC__) && (__GNUC__ >= 3) +#define SLJIT_LIKELY(x) __builtin_expect((x), 1) +#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0) +#else +#define SLJIT_LIKELY(x) (x) +#define SLJIT_UNLIKELY(x) (x) +#endif + +#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ + +#ifndef SLJIT_INLINE +/* Inline functions. */ +#define SLJIT_INLINE __inline +#endif + +#ifndef SLJIT_CONST +/* Const variables. */ +#define SLJIT_CONST const +#endif + +#ifndef SLJIT_UNUSED_ARG +/* Unused arguments. */ +#define SLJIT_UNUSED_ARG(arg) (void)arg +#endif + +#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) +/* Static ABI functions. For all-in-one programs. */ + +#if defined(__GNUC__) +/* Disable unused warnings in gcc. */ +#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused)) +#else +#define SLJIT_API_FUNC_ATTRIBUTE static +#endif + +#else +#define SLJIT_API_FUNC_ATTRIBUTE +#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ + +#ifndef SLJIT_CACHE_FLUSH + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +/* Not required to implement on archs with unified caches. */ +#define SLJIT_CACHE_FLUSH(from, to) + +#elif defined __APPLE__ + +/* Supported by all macs since Mac OS 10.5. + However, it does not work on non-jailbroken iOS devices, + although the compilation is successful. */ + +#define SLJIT_CACHE_FLUSH(from, to) \ + sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) + +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + +/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + ppc_cache_flush((from), (to)) + +#else + +/* Calls __ARM_NR_cacheflush on ARM-Linux. */ +#define SLJIT_CACHE_FLUSH(from, to) \ + __clear_cache((char*)(from), (char*)(to)) + +#endif + +#endif /* !SLJIT_CACHE_FLUSH */ + +/* 8 bit byte type. */ +typedef unsigned char sljit_ub; +typedef signed char sljit_b; + +/* 16 bit half-word type. */ +typedef unsigned short int sljit_uh; +typedef signed short int sljit_h; + +/* 32 bit integer type. */ +typedef unsigned int sljit_ui; +typedef signed int sljit_i; + +/* Machine word type. Can encapsulate a pointer. + 32 bit for 32 bit machines. + 64 bit for 64 bit machines. */ +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +/* Just to have something. */ +#define SLJIT_WORD_SHIFT 0 +typedef unsigned long int sljit_uw; +typedef long int sljit_w; +#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_32BIT_ARCHITECTURE 1 +#define SLJIT_WORD_SHIFT 2 +typedef unsigned int sljit_uw; +typedef int sljit_w; +#else +#define SLJIT_64BIT_ARCHITECTURE 1 +#define SLJIT_WORD_SHIFT 3 +#ifdef _WIN32 +typedef unsigned __int64 sljit_uw; +typedef __int64 sljit_w; +#else +typedef unsigned long int sljit_uw; +typedef long int sljit_w; +#endif +#endif + +/* Double precision. */ +#define SLJIT_FLOAT_SHIFT 3 + +#ifndef SLJIT_W + +/* Defining long constants. */ +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#define SLJIT_W(w) (w##ll) +#else +#define SLJIT_W(w) (w) +#endif + +#endif /* !SLJIT_W */ + +#ifndef SLJIT_CALL + +/* ABI (Application Binary Interface) types. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +#if defined(__GNUC__) + +#define SLJIT_CALL __attribute__ ((fastcall)) +#define SLJIT_X86_32_FASTCALL 1 + +#elif defined(_WIN32) + +#ifdef __BORLANDC__ +#define SLJIT_CALL __msfastcall +#else /* __BORLANDC__ */ +#define SLJIT_CALL __fastcall +#endif /* __BORLANDC__ */ +#define SLJIT_X86_32_FASTCALL 1 + +#else /* defined(_WIN32) */ +#define SLJIT_CALL __stdcall +#endif + +#else /* Other architectures. */ + +#define SLJIT_CALL + +#endif /* SLJIT_CONFIG_X86_32 */ + +#endif /* !SLJIT_CALL */ + +#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) + +/* These macros are useful for the application. */ +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_BIG_ENDIAN 1 + +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + +#ifdef __MIPSEL__ +#define SLJIT_LITTLE_ENDIAN 1 +#else +#define SLJIT_BIG_ENDIAN 1 +#endif + +#else +#define SLJIT_LITTLE_ENDIAN 1 +#endif + +#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */ + +/* Sanity check. */ +#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#error "Exactly one endianness must be selected" +#endif + +#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#error "Exactly one endianness must be selected" +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +/* It seems ppc64 compilers use an indirect addressing for functions. + It makes things really complicated. */ +#define SLJIT_INDIRECT_CALL 1 +#endif + +#ifndef SLJIT_SSE2 + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +/* Turn on SSE2 support on x86. */ +#define SLJIT_SSE2 1 + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +/* Auto detect SSE2 support using CPUID. + On 64 bit x86 cpus, sse2 must be present. */ +#define SLJIT_DETECT_SSE2 1 +#endif + +#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */ + +#endif /* !SLJIT_SSE2 */ + +#ifndef SLJIT_UNALIGNED + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_UNALIGNED 1 +#endif + +#endif /* !SLJIT_UNALIGNED */ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); +#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) +#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#include +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + +/* Feel free to redefine these two macros. */ +#ifndef SLJIT_ASSERT + +#define SLJIT_HALT_PROCESS() \ + *((int*)0) = 0 + +#define SLJIT_ASSERT(x) \ + do { \ + if (SLJIT_UNLIKELY(!(x))) { \ + printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ + SLJIT_HALT_PROCESS(); \ + } \ + } while (0) + +#endif /* !SLJIT_ASSERT */ + +#ifndef SLJIT_ASSERT_STOP + +#define SLJIT_ASSERT_STOP() \ + do { \ + printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ + SLJIT_HALT_PROCESS(); \ + } while (0) + +#endif /* !SLJIT_ASSERT_STOP */ + +#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ + +#undef SLJIT_ASSERT +#undef SLJIT_ASSERT_STOP + +#define SLJIT_ASSERT(x) \ + do { } while (0) +#define SLJIT_ASSERT_STOP() \ + do { } while (0) + +#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ + +#ifndef SLJIT_COMPILE_ASSERT + +/* Should be improved eventually. */ +#define SLJIT_COMPILE_ASSERT(x, description) \ + SLJIT_ASSERT(x) + +#endif /* !SLJIT_COMPILE_ASSERT */ + +#endif diff -Nru pcre3-8.12/sljit/sljitExecAllocator.c pcre3-8.31/sljit/sljitExecAllocator.c --- pcre3-8.12/sljit/sljitExecAllocator.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitExecAllocator.c 2011-12-28 16:57:57.000000000 +0000 @@ -0,0 +1,277 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple executable memory allocator + + It is assumed, that executable code blocks are usually medium (or sometimes + large) memory blocks, and the allocator is not too frequently called (less + optimized than other allocators). Thus, using it as a generic allocator is + not suggested. + + How does it work: + Memory is allocated in continuous memory areas called chunks by alloc_chunk() + Chunk format: + [ block ][ block ] ... [ block ][ block terminator ] + + All blocks and the block terminator is started with block_header. The block + header contains the size of the previous and the next block. These sizes + can also contain special values. + Block size: + 0 - The block is a free_block, with a different size member. + 1 - The block is a block terminator. + n - The block is used at the moment, and the value contains its size. + Previous block size: + 0 - This is the first block of the memory chunk. + n - The size of the previous block. + + Using these size values we can go forward or backward on the block chain. + The unused blocks are stored in a chain list pointed by free_blocks. This + list is useful if we need to find a suitable memory area when the allocator + is called. + + When a block is freed, the new free block is connected to its adjacent free + blocks if possible. + + [ free block ][ used block ][ free block ] + and "used block" is freed, the three blocks are connected together: + [ one big free block ] +*/ + +/* --------------------------------------------------------------------- */ +/* System (OS) functions */ +/* --------------------------------------------------------------------- */ + +/* 64 KByte. */ +#define CHUNK_SIZE 0x10000 + +/* + alloc_chunk / free_chunk : + * allocate executable system memory chunks + * the size is always divisible by CHUNK_SIZE + allocator_grab_lock / allocator_release_lock : + * make the allocator thread safe + * can be empty if the OS (or the application) does not support threading + * only the allocator requires this lock, sljit is fully thread safe + as it only uses local variables +*/ + +#ifdef _WIN32 + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +} + +static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) +{ + SLJIT_UNUSED_ARG(size); + VirtualFree(chunk, 0, MEM_RELEASE); +} + +#else + +#include + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); + return (retval != MAP_FAILED) ? retval : NULL; +} + +static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#endif + +/* --------------------------------------------------------------------- */ +/* Common functions */ +/* --------------------------------------------------------------------- */ + +#define CHUNK_MASK (~(CHUNK_SIZE - 1)) + +struct block_header { + sljit_uw size; + sljit_uw prev_size; +}; + +struct free_block { + struct block_header header; + struct free_block *next; + struct free_block *prev; + sljit_uw size; +}; + +#define AS_BLOCK_HEADER(base, offset) \ + ((struct block_header*)(((sljit_ub*)base) + offset)) +#define AS_FREE_BLOCK(base, offset) \ + ((struct free_block*)(((sljit_ub*)base) + offset)) +#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) +#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) + +static struct free_block* free_blocks; +static sljit_uw allocated_size; +static sljit_uw total_size; + +static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) +{ + free_block->header.size = 0; + free_block->size = size; + + free_block->next = free_blocks; + free_block->prev = 0; + if (free_blocks) + free_blocks->prev = free_block; + free_blocks = free_block; +} + +static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) +{ + if (free_block->next) + free_block->next->prev = free_block->prev; + + if (free_block->prev) + free_block->prev->next = free_block->next; + else { + SLJIT_ASSERT(free_blocks == free_block); + free_blocks = free_block->next; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + struct block_header *header; + struct block_header *next_header; + struct free_block *free_block; + sljit_uw chunk_size; + + allocator_grab_lock(); + if (size < sizeof(struct free_block)) + size = sizeof(struct free_block); + size = ALIGN_SIZE(size); + + free_block = free_blocks; + while (free_block) { + if (free_block->size >= size) { + chunk_size = free_block->size; + if (chunk_size > size + 64) { + /* We just cut a block from the end of the free block. */ + chunk_size -= size; + free_block->size = chunk_size; + header = AS_BLOCK_HEADER(free_block, chunk_size); + header->prev_size = chunk_size; + AS_BLOCK_HEADER(header, size)->prev_size = size; + } + else { + sljit_remove_free_block(free_block); + header = (struct block_header*)free_block; + size = chunk_size; + } + allocated_size += size; + header->size = size; + allocator_release_lock(); + return MEM_START(header); + } + free_block = free_block->next; + } + + chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; + header = (struct block_header*)alloc_chunk(chunk_size); + PTR_FAIL_IF(!header); + + chunk_size -= sizeof(struct block_header); + total_size += chunk_size; + + header->prev_size = 0; + if (chunk_size > size + 64) { + /* Cut the allocated space into a free and a used block. */ + allocated_size += size; + header->size = size; + chunk_size -= size; + + free_block = AS_FREE_BLOCK(header, size); + free_block->header.prev_size = size; + sljit_insert_free_block(free_block, chunk_size); + next_header = AS_BLOCK_HEADER(free_block, chunk_size); + } + else { + /* All space belongs to this allocation. */ + allocated_size += chunk_size; + header->size = chunk_size; + next_header = AS_BLOCK_HEADER(header, chunk_size); + } + next_header->size = 1; + next_header->prev_size = chunk_size; + allocator_release_lock(); + return MEM_START(header); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + struct block_header *header; + struct free_block* free_block; + + allocator_grab_lock(); + header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header)); + allocated_size -= header->size; + + /* Connecting free blocks together if possible. */ + + /* If header->prev_size == 0, free_block will equal to header. + In this case, free_block->header.size will be > 0. */ + free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size); + if (SLJIT_UNLIKELY(!free_block->header.size)) { + free_block->size += header->size; + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + else { + free_block = (struct free_block*)header; + sljit_insert_free_block(free_block, header->size); + } + + header = AS_BLOCK_HEADER(free_block, free_block->size); + if (SLJIT_UNLIKELY(!header->size)) { + free_block->size += ((struct free_block*)header)->size; + sljit_remove_free_block((struct free_block*)header); + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + + /* The whole chunk is free. */ + if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { + /* If this block is freed, we still have (allocated_size / 2) free space. */ + if (total_size - free_block->size > (allocated_size * 3 / 2)) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + sizeof(struct block_header)); + } + } + + allocator_release_lock(); +} diff -Nru pcre3-8.12/sljit/sljitLir.c pcre3-8.31/sljit/sljitLir.c --- pcre3-8.12/sljit/sljitLir.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitLir.c 2012-06-01 16:19:45.000000000 +0000 @@ -0,0 +1,1678 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +#include "sljitLir.h" + +#define CHECK_ERROR() \ + do { \ + if (SLJIT_UNLIKELY(compiler->error)) \ + return compiler->error; \ + } while (0) + +#define CHECK_ERROR_PTR() \ + do { \ + if (SLJIT_UNLIKELY(compiler->error)) \ + return NULL; \ + } while (0) + +#define CHECK_ERROR_VOID() \ + do { \ + if (SLJIT_UNLIKELY(compiler->error)) \ + return; \ + } while (0) + +#define FAIL_IF(expr) \ + do { \ + if (SLJIT_UNLIKELY(expr)) \ + return compiler->error; \ + } while (0) + +#define PTR_FAIL_IF(expr) \ + do { \ + if (SLJIT_UNLIKELY(expr)) \ + return NULL; \ + } while (0) + +#define FAIL_IF_NULL(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_ALLOC_FAILED; \ + return SLJIT_ERR_ALLOC_FAILED; \ + } \ + } while (0) + +#define PTR_FAIL_IF_NULL(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_ALLOC_FAILED; \ + return NULL; \ + } \ + } while (0) + +#define PTR_FAIL_WITH_EXEC_IF(ptr) \ + do { \ + if (SLJIT_UNLIKELY(!(ptr))) { \ + compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \ + return NULL; \ + } \ + } while (0) + +#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + +#define GET_OPCODE(op) \ + ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + +#define GET_FLAGS(op) \ + ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) + +#define GET_ALL_FLAGS(op) \ + ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + +#define BUF_SIZE 4096 + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) +#define ABUF_SIZE 2048 +#else +#define ABUF_SIZE 4096 +#endif + +/* Jump flags. */ +#define JUMP_LABEL 0x1 +#define JUMP_ADDR 0x2 +/* SLJIT_REWRITABLE_JUMP is 0x1000. */ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + #define PATCH_MB 0x4 + #define PATCH_MW 0x8 +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + #define PATCH_MD 0x10 +#endif +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + #define IS_BL 0x4 + #define PATCH_B 0x8 +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + #define CPOOL_SIZE 512 +#endif + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + #define IS_CONDITIONAL 0x04 + #define IS_BL 0x08 + /* cannot be encoded as branch */ + #define B_TYPE0 0x00 + /* conditional + imm8 */ + #define B_TYPE1 0x10 + /* conditional + imm20 */ + #define B_TYPE2 0x20 + /* IT + imm24 */ + #define B_TYPE3 0x30 + /* imm11 */ + #define B_TYPE4 0x40 + /* imm24 */ + #define B_TYPE5 0x50 + /* BL + imm24 */ + #define BL_TYPE6 0x60 + /* 0xf00 cc code for branches */ +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + #define UNCOND_B 0x04 + #define PATCH_B 0x08 + #define ABSOLUTE_B 0x10 +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #define IS_MOVABLE 0x04 + #define IS_JAL 0x08 + #define IS_BIT26_COND 0x10 + #define IS_BIT16_COND 0x20 + + #define IS_COND (IS_BIT26_COND | IS_BIT16_COND) + + #define PATCH_B 0x40 + #define PATCH_J 0x80 + + /* instruction types */ + #define UNMOVABLE_INS 0 + /* 1 - 31 last destination register */ + #define FCSR_FCC 32 + /* no destination (i.e: store) */ + #define MOVABLE_INS 33 +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1 +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#ifdef _WIN64 +#define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) +#else +#define FIXED_LOCALS_OFFSET (sizeof(sljit_w)) +#endif +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_w)) +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET ((7 + 8) * sizeof(sljit_w)) +#endif + +#if (defined SLJIT_HAS_VARIABLE_LOCALS_OFFSET && SLJIT_HAS_VARIABLE_LOCALS_OFFSET) + +#define ADJUST_LOCAL_OFFSET(p, i) \ + if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ + (i) += compiler->locals_offset; + +#elif (defined SLJIT_HAS_FIXED_LOCALS_OFFSET && SLJIT_HAS_FIXED_LOCALS_OFFSET) + +#define ADJUST_LOCAL_OFFSET(p, i) \ + if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ + (i) += FIXED_LOCALS_OFFSET; + +#else + +#define ADJUST_LOCAL_OFFSET(p, i) + +#endif + +#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */ + +/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */ +#include "sljitUtils.c" + +#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +#include "sljitExecAllocator.c" +#endif + +#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2) +#error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2 +#endif + +/* --------------------------------------------------------------------- */ +/* Public functions */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64))) +#define SLJIT_NEEDS_COMPILER_INIT 1 +static int compiler_initialized = 0; +/* A thread safe initialization. */ +static void init_compiler(void); +#endif + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) +{ + struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler)); + if (!compiler) + return NULL; + SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); + + SLJIT_COMPILE_ASSERT( + sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1 + && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2 + && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4 + && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)), + invalid_integer_types); + + /* Only the non-zero members must be set. */ + compiler->error = SLJIT_SUCCESS; + + compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE); + compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE); + + if (!compiler->buf || !compiler->abuf) { + if (compiler->buf) + SLJIT_FREE(compiler->buf); + if (compiler->abuf) + SLJIT_FREE(compiler->abuf); + SLJIT_FREE(compiler); + return NULL; + } + + compiler->buf->next = NULL; + compiler->buf->used_size = 0; + compiler->abuf->next = NULL; + compiler->abuf->used_size = 0; + + compiler->temporaries = -1; + compiler->saveds = -1; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->args = -1; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub)); + if (!compiler->cpool) { + SLJIT_FREE(compiler->buf); + SLJIT_FREE(compiler->abuf); + SLJIT_FREE(compiler); + return NULL; + } + compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); + compiler->cpool_diff = 0xffffffff; +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + compiler->delay_slot = UNMOVABLE_INS; +#endif + +#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) + if (!compiler_initialized) { + init_compiler(); + compiler_initialized = 1; + } +#endif + + return compiler; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + struct sljit_memory_fragment *curr; + + buf = compiler->buf; + while (buf) { + curr = buf; + buf = buf->next; + SLJIT_FREE(curr); + } + + buf = compiler->abuf; + while (buf) { + curr = buf; + buf = buf->next; + SLJIT_FREE(curr); + } + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + SLJIT_FREE(compiler->cpool); +#endif + SLJIT_FREE(compiler); +} + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + /* Remove thumb mode flag. */ + SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); +} +#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + /* Resolve indirection. */ + code = (void*)(*(sljit_uw*)code); + SLJIT_FREE_EXEC(code); +} +#else +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + SLJIT_FREE_EXEC(code); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) +{ + if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) { + jump->flags &= ~JUMP_ADDR; + jump->flags |= JUMP_LABEL; + jump->u.label = label; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) +{ + if (SLJIT_LIKELY(!!jump)) { + SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP); + + jump->flags &= ~JUMP_LABEL; + jump->flags |= JUMP_ADDR; + jump->u.target = target; + } +} + +/* --------------------------------------------------------------------- */ +/* Private functions */ +/* --------------------------------------------------------------------- */ + +static void* ensure_buf(struct sljit_compiler *compiler, int size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { + ret = compiler->buf->memory + compiler->buf->used_size; + compiler->buf->used_size += size; + return ret; + } + new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE); + PTR_FAIL_IF_NULL(new_frag); + new_frag->next = compiler->buf; + compiler->buf = new_frag; + new_frag->used_size = size; + return new_frag->memory; +} + +static void* ensure_abuf(struct sljit_compiler *compiler, int size) +{ + sljit_ub *ret; + struct sljit_memory_fragment *new_frag; + + if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { + ret = compiler->abuf->memory + compiler->abuf->used_size; + compiler->abuf->used_size += size; + return ret; + } + new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE); + PTR_FAIL_IF_NULL(new_frag); + new_frag->next = compiler->abuf; + compiler->abuf = new_frag; + new_frag->used_size = size; + return new_frag->memory; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) +{ + CHECK_ERROR_PTR(); + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + if (size <= 0 || size > 128) + return NULL; + size = (size + 7) & ~7; +#else + if (size <= 0 || size > 64) + return NULL; + size = (size + 3) & ~3; +#endif + return ensure_abuf(compiler, size); +} + +static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf = compiler->buf; + struct sljit_memory_fragment *prev = NULL; + struct sljit_memory_fragment *tmp; + + do { + tmp = buf->next; + buf->next = prev; + prev = buf; + buf = tmp; + } while (buf != NULL); + + compiler->buf = prev; +} + +static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) +{ + label->next = NULL; + label->size = compiler->size; + if (compiler->last_label) + compiler->last_label->next = label; + else + compiler->labels = label; + compiler->last_label = label; +} + +static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags) +{ + jump->next = NULL; + jump->flags = flags; + if (compiler->last_jump) + compiler->last_jump->next = jump; + else + compiler->jumps = jump; + compiler->last_jump = jump; +} + +static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler) +{ + const_->next = NULL; + const_->addr = compiler->size; + if (compiler->last_const) + compiler->last_const->next = const_; + else + compiler->consts = const_; + compiler->last_const = const_; +} + +#define ADDRESSING_DEPENDS_ON(exp, reg) \ + (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg)) + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) +#define FUNCTION_CHECK_OP() \ + SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ + switch (GET_OPCODE(op)) { \ + case SLJIT_NOT: \ + case SLJIT_CLZ: \ + case SLJIT_AND: \ + case SLJIT_OR: \ + case SLJIT_XOR: \ + case SLJIT_SHL: \ + case SLJIT_LSHR: \ + case SLJIT_ASHR: \ + SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \ + break; \ + case SLJIT_NEG: \ + SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ + break; \ + case SLJIT_MUL: \ + SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ + break; \ + case SLJIT_FCMP: \ + SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ + break; \ + case SLJIT_ADD: \ + SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \ + break; \ + case SLJIT_SUB: \ + break; \ + case SLJIT_ADDC: \ + case SLJIT_SUBC: \ + SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \ + break; \ + default: \ + /* Nothing allowed */ \ + SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + break; \ + } + +#define FUNCTION_CHECK_IS_REG(r) \ + ((r) == SLJIT_UNUSED || \ + ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \ + ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) + +#define FUNCTION_CHECK_SRC(p, i) \ + SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ + if (FUNCTION_CHECK_IS_REG(p)) \ + SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \ + else if ((p) == SLJIT_IMM) \ + ; \ + else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ + SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \ + else if ((p) & SLJIT_MEM) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ + if ((p) & 0xf0) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ + SLJIT_ASSERT(!((i) & ~0x3)); \ + } \ + SLJIT_ASSERT(((p) >> 9) == 0); \ + } \ + else \ + SLJIT_ASSERT_STOP(); + +#define FUNCTION_CHECK_DST(p, i) \ + SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ + if (FUNCTION_CHECK_IS_REG(p)) \ + SLJIT_ASSERT((i) == 0); \ + else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ + SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \ + else if ((p) & SLJIT_MEM) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ + if ((p) & 0xf0) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ + SLJIT_ASSERT(!((i) & ~0x3)); \ + } \ + SLJIT_ASSERT(((p) >> 9) == 0); \ + } \ + else \ + SLJIT_ASSERT_STOP(); + +#define FUNCTION_FCHECK(p, i) \ + if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \ + SLJIT_ASSERT(i == 0); \ + else if ((p) & SLJIT_MEM) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ + if ((p) & 0xf0) { \ + SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \ + SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \ + } else \ + SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \ + SLJIT_ASSERT(((p) >> 9) == 0); \ + } \ + else \ + SLJIT_ASSERT_STOP(); + +#define FUNCTION_CHECK_OP1() \ + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ + SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \ + } \ + if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ + SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \ + SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \ + if ((src & SLJIT_MEM) && (src & 0xf)) \ + SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \ + } + +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) +{ + compiler->verbose = verbose; +} + +static char* reg_names[] = { + (char*)"", (char*)"t1", (char*)"t2", (char*)"t3", + (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2", + (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr" +}; + +static char* freg_names[] = { + (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4" +}; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#ifdef _WIN64 + #define SLJIT_PRINT_D "I64" +#else + #define SLJIT_PRINT_D "l" +#endif +#else + #define SLJIT_PRINT_D "" +#endif + +#define sljit_verbose_param(p, i) \ + if ((p) & SLJIT_IMM) \ + fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \ + else if ((p) & SLJIT_MEM) { \ + if ((p) & 0xf) { \ + if (i) { \ + if (((p) >> 4) & 0xf) \ + fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ + else \ + fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ + } \ + else { \ + if (((p) >> 4) & 0xf) \ + fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ + else \ + fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ + } \ + } \ + else \ + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ + } else \ + fprintf(compiler->verbose, "%s", reg_names[p]); +#define sljit_verbose_fparam(p, i) \ + if ((p) & SLJIT_MEM) { \ + if ((p) & 0xf) { \ + if (i) { \ + if (((p) >> 4) & 0xf) \ + fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \ + else \ + fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & 0xF], (i)); \ + } \ + else { \ + if (((p) >> 4) & 0xF) \ + fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \ + else \ + fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \ + } \ + } \ + else \ + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \ + } else \ + fprintf(compiler->verbose, "%s", freg_names[p]); + +static SLJIT_CONST char* op_names[] = { + /* op0 */ + (char*)"breakpoint", (char*)"nop", + (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv", + /* op1 */ + (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh", + (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu", + (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh", + (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg", + (char*)"clz", + /* op2 */ + (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", + (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", + (char*)"shl", (char*)"lshr", (char*)"ashr", + /* fop1 */ + (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs", + /* fop2 */ + (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv" +}; + +static char* jump_names[] = { + (char*)"c_equal", (char*)"c_not_equal", + (char*)"c_less", (char*)"c_greater_equal", + (char*)"c_greater", (char*)"c_less_equal", + (char*)"c_sig_less", (char*)"c_sig_greater_equal", + (char*)"c_sig_greater", (char*)"c_sig_less_equal", + (char*)"c_overflow", (char*)"c_not_overflow", + (char*)"c_mul_overflow", (char*)"c_mul_not_overflow", + (char*)"c_float_equal", (char*)"c_float_not_equal", + (char*)"c_float_less", (char*)"c_float_greater_equal", + (char*)"c_float_greater", (char*)"c_float_less_equal", + (char*)"c_float_nan", (char*)"c_float_not_nan", + (char*)"jump", (char*)"fast_call", + (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" +}; + +#endif + +/* --------------------------------------------------------------------- */ +/* Arch dependent */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler) +{ +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + struct sljit_jump *jump; +#endif + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + + SLJIT_ASSERT(compiler->size > 0); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + jump = compiler->jumps; + while (jump) { + /* All jumps have target. */ + SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR)); + jump = jump->next; + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + + SLJIT_ASSERT(args >= 0 && args <= 3); + SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); + SLJIT_ASSERT(args <= saveds); + SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); +#endif +} + +static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + return; + } +#endif + + SLJIT_ASSERT(args >= 0 && args <= 3); + SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); + SLJIT_ASSERT(args <= saveds); + SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " set_context args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); +#endif +} + +static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (op != SLJIT_UNUSED) { + SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_SI); + FUNCTION_CHECK_SRC(src, srcw); + } + else + SLJIT_ASSERT(src == 0 && srcw == 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (op == SLJIT_UNUSED) + fprintf(compiler->verbose, " return\n"); + else { + fprintf(compiler->verbose, " return %s ", op_names[op]); + sljit_verbose_param(src, srcw); + fprintf(compiler->verbose, "\n"); + } + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fast_enter "); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fast_return "); + sljit_verbose_param(src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + + SLJIT_ASSERT((op >= SLJIT_BREAKPOINT && op <= SLJIT_SMUL) + || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV)); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]); +#endif +} + +static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + return; + } +#endif + + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_OP(); + FUNCTION_CHECK_SRC(src, srcw); + FUNCTION_CHECK_DST(dst, dstw); + FUNCTION_CHECK_OP1(); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + return; + } +#endif + + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_OP(); + FUNCTION_CHECK_SRC(src1, src1w); + FUNCTION_CHECK_SRC(src2, src2w); + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_get_register_index(int reg) +{ + SLJIT_UNUSED_ARG(reg); + SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS); +} + +static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(instruction); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT(instruction); +} + +static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + return; + } +#endif + + SLJIT_ASSERT(sljit_is_fpu_available()); + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_OP(); + FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)], + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S"); + sljit_verbose_fparam(dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + + SLJIT_ASSERT(sljit_is_fpu_available()); + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_OP(); + FUNCTION_FCHECK(src1, src1w); + FUNCTION_FCHECK(src2, src2w); + FUNCTION_FCHECK(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]); + sljit_verbose_fparam(dst, dstw); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, "label:\n"); +#endif +} + +static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + return; + } +#endif + + SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP))); + SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) + fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); +#endif +} + +static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + + SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP))); + SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_SRC(src1, src1w); + FUNCTION_CHECK_SRC(src2, src2w); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); + sljit_verbose_param(src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + + SLJIT_ASSERT(sljit_is_fpu_available()); + SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP))); + SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_NOT_NAN); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_FCHECK(src1, src1w); + FUNCTION_FCHECK(src2, src2w); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fcmp%s <%s> ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); + sljit_verbose_fparam(src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + + SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]); + sljit_verbose_param(src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(type); + + SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); + SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR); + SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E", + !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, ", <%s>\n", jump_names[type]); + } +#endif +} + +static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(offset); + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " local_base "); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); + } +#endif +} + +static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + /* If debug and verbose are disabled, all arguments are unused. */ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(init_value); + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " const "); + sljit_verbose_param(dst, dstw); + fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); + } +#endif +} + +static SLJIT_INLINE int emit_mov_before_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + /* Return if don't need to do anything. */ + if (op == SLJIT_UNUSED) + return SLJIT_SUCCESS; + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + if (src == SLJIT_RETURN_REG && op == SLJIT_MOV) + return SLJIT_SUCCESS; +#else + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI)) + return SLJIT_SUCCESS; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); +} + +/* CPU description section */ + +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) +#define SLJIT_CPUINFO_PART1 " 32bit (" +#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#define SLJIT_CPUINFO_PART1 " 64bit (" +#else +#error "Internal error: CPU type info missing" +#endif + +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define SLJIT_CPUINFO_PART2 "little endian + " +#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) +#define SLJIT_CPUINFO_PART2 "big endian + " +#else +#error "Internal error: CPU type info missing" +#endif + +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) +#define SLJIT_CPUINFO_PART3 "unaligned)" +#else +#define SLJIT_CPUINFO_PART3 "aligned)" +#endif + +#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + #include "sljitNativeX86_common.c" +#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + #include "sljitNativeX86_common.c" +#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + #include "sljitNativeARM_v5.c" +#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + #include "sljitNativeARM_v5.c" +#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + #include "sljitNativeARM_Thumb2.c" +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + #include "sljitNativePPC_common.c" +#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + #include "sljitNativePPC_common.c" +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #include "sljitNativeMIPS_common.c" +#endif + +#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* Default compare for most architectures. */ + int flags, tmp_src, condition; + sljit_w tmp_srcw; + + CHECK_ERROR_PTR(); + check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); + + condition = type & 0xff; + if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { + /* Immediate is prefered as second argument by most architectures. */ + switch (condition) { + case SLJIT_C_LESS: + condition = SLJIT_C_GREATER; + break; + case SLJIT_C_GREATER_EQUAL: + condition = SLJIT_C_LESS_EQUAL; + break; + case SLJIT_C_GREATER: + condition = SLJIT_C_LESS; + break; + case SLJIT_C_LESS_EQUAL: + condition = SLJIT_C_GREATER_EQUAL; + break; + case SLJIT_C_SIG_LESS: + condition = SLJIT_C_SIG_GREATER; + break; + case SLJIT_C_SIG_GREATER_EQUAL: + condition = SLJIT_C_SIG_LESS_EQUAL; + break; + case SLJIT_C_SIG_GREATER: + condition = SLJIT_C_SIG_LESS; + break; + case SLJIT_C_SIG_LESS_EQUAL: + condition = SLJIT_C_SIG_GREATER_EQUAL; + break; + } + type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); + tmp_src = src1; + src1 = src2; + src2 = tmp_src; + tmp_srcw = src1w; + src1w = src2w; + src2w = tmp_srcw; + } + + if (condition <= SLJIT_C_NOT_ZERO) + flags = SLJIT_SET_E; + else if (condition <= SLJIT_C_LESS_EQUAL) + flags = SLJIT_SET_U; + else + flags = SLJIT_SET_S; + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), + SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int flags, condition; + + check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); + + condition = type & 0xff; + if (condition <= SLJIT_C_FLOAT_NOT_EQUAL) + flags = SLJIT_SET_E; + else + flags = SLJIT_SET_S; + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + sljit_emit_fop1(compiler, SLJIT_FCMP | flags, src1, src1w, src2, src2w); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); +} + +#endif + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) +{ + CHECK_ERROR(); + check_sljit_get_local_base(compiler, dst, dstw, offset); + + ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + if (offset != 0) + return sljit_emit_op2(compiler, SLJIT_ADD | SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); + return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_LOCALS_REG, 0); +} + +#endif + +#else /* SLJIT_CONFIG_UNSUPPORTED */ + +/* Empty function bodies for those machines, which are not (yet) supported. */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ + return "unsupported"; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) +{ + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT_STOP(); + return NULL; +} + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(verbose); + SLJIT_ASSERT_STOP(); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) +{ + SLJIT_UNUSED_ARG(code); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + SLJIT_ASSERT_STOP(); + return reg; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(instruction); + SLJIT_UNUSED_ARG(size); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ + SLJIT_ASSERT_STOP(); + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src1); + SLJIT_UNUSED_ARG(src1w); + SLJIT_UNUSED_ARG(src2); + SLJIT_UNUSED_ARG(src2w); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) +{ + SLJIT_UNUSED_ARG(jump); + SLJIT_UNUSED_ARG(label); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) +{ + SLJIT_UNUSED_ARG(jump); + SLJIT_UNUSED_ARG(target); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(type); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(offset); + SLJIT_ASSERT_STOP(); + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(initval); + SLJIT_ASSERT_STOP(); + return NULL; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + SLJIT_UNUSED_ARG(addr); + SLJIT_UNUSED_ARG(new_addr); + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + SLJIT_UNUSED_ARG(addr); + SLJIT_UNUSED_ARG(new_constant); + SLJIT_ASSERT_STOP(); +} + +#endif diff -Nru pcre3-8.12/sljit/sljitLir.h pcre3-8.31/sljit/sljitLir.h --- pcre3-8.12/sljit/sljitLir.h 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitLir.h 2012-04-03 15:33:31.000000000 +0000 @@ -0,0 +1,863 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +#ifndef _SLJIT_LIR_H_ +#define _SLJIT_LIR_H_ + +/* + ------------------------------------------------------------------------ + Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC) + ------------------------------------------------------------------------ + + Short description + Advantages: + - The execution can be continued from any LIR instruction + In other words, jump into and out of the code is safe + - Both target of (conditional) jump and call instructions + and constants can be dynamically modified during runtime + - although it is not suggested to do it frequently + - very effective to cache an important value once + - A fixed stack space can be allocated for local variables + - The compiler is thread-safe + - The compiler is highly configurable through preprocessor macros. + You can disable unneeded features (multithreading in single + threaded applications), and you can use your own system functions + (including memory allocators). See sljitConfig.h + Disadvantages: + - Limited number of registers (only 6+4 integer registers, max 3+2 + temporary, max 3+2 saved and 4 floating point registers) + In practice: + - This approach is very effective for interpreters + - One of the saved registers typically points to a stack interface + - It can jump to any exception handler anytime (even for another + function. It is safe for SLJIT.) + - Fast paths can be modified during runtime reflecting the changes + of the fastest execution path of the dynamic language + - SLJIT supports complex memory addressing modes + - mainly position independent code + - Optimizations (perhaps later) + - Only for basic blocks (when no labels inserted between LIR instructions) + + For valgrind users: + - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" +*/ + +#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG) +#include "sljitConfig.h" +#endif + +/* The following header file defines useful macros for fine tuning +sljit based code generators. They are listed in the begining +of sljitConfigInternal.h */ + +#include "sljitConfigInternal.h" + +/* --------------------------------------------------------------------- */ +/* Error codes */ +/* --------------------------------------------------------------------- */ + +/* Indicates no error. */ +#define SLJIT_SUCCESS 0 +/* After the call of sljit_generate_code(), the error code of the compiler + is set to this value to avoid future sljit calls (in debug mode at least). + The complier should be freed after sljit_generate_code(). */ +#define SLJIT_ERR_COMPILED 1 +/* Cannot allocate non executable memory. */ +#define SLJIT_ERR_ALLOC_FAILED 2 +/* Cannot allocate executable memory. + Only for sljit_generate_code() */ +#define SLJIT_ERR_EX_ALLOC_FAILED 3 +/* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */ +#define SLJIT_ERR_UNSUPPORTED 4 + +/* --------------------------------------------------------------------- */ +/* Registers */ +/* --------------------------------------------------------------------- */ + +#define SLJIT_UNUSED 0 + +/* Temporary (scratch) registers may not preserve their values across function calls. */ +#define SLJIT_TEMPORARY_REG1 1 +#define SLJIT_TEMPORARY_REG2 2 +#define SLJIT_TEMPORARY_REG3 3 +/* Note: Extra Registers cannot be used for memory addressing. */ +/* Note: on x86-32, these registers are emulated (using stack loads & stores). */ +#define SLJIT_TEMPORARY_EREG1 4 +#define SLJIT_TEMPORARY_EREG2 5 + +/* Saved registers whose preserve their values across function calls. */ +#define SLJIT_SAVED_REG1 6 +#define SLJIT_SAVED_REG2 7 +#define SLJIT_SAVED_REG3 8 +/* Note: Extra Registers cannot be used for memory addressing. */ +/* Note: on x86-32, these registers are emulated (using stack loads & stores). */ +#define SLJIT_SAVED_EREG1 9 +#define SLJIT_SAVED_EREG2 10 + +/* Read-only register (cannot be the destination of an operation). + Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since + several ABIs has certain limitations about the stack layout. However + sljit_get_local_base() can be used to obtain the offset of a value. */ +#define SLJIT_LOCALS_REG 11 + +/* Number of registers. */ +#define SLJIT_NO_TMP_REGISTERS 5 +#define SLJIT_NO_GEN_REGISTERS 5 +#define SLJIT_NO_REGISTERS 11 + +/* Return with machine word. */ + +#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1 + +/* x86 prefers specific registers for special purposes. In case of shift + by register it supports only SLJIT_TEMPORARY_REG3 for shift argument + (which is the src2 argument of sljit_emit_op2). If another register is + used, sljit must exchange data between registers which cause a minor + slowdown. Other architectures has no such limitation. */ + +#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3 + +/* --------------------------------------------------------------------- */ +/* Floating point registers */ +/* --------------------------------------------------------------------- */ + +/* Note: SLJIT_UNUSED as destination is not valid for floating point + operations, since they cannot be used for setting flags. */ + +/* Floating point operations are performed on double precision values. */ + +#define SLJIT_FLOAT_REG1 1 +#define SLJIT_FLOAT_REG2 2 +#define SLJIT_FLOAT_REG3 3 +#define SLJIT_FLOAT_REG4 4 + +/* --------------------------------------------------------------------- */ +/* Main structures and functions */ +/* --------------------------------------------------------------------- */ + +struct sljit_memory_fragment { + struct sljit_memory_fragment *next; + sljit_uw used_size; + sljit_ub memory[1]; +}; + +struct sljit_label { + struct sljit_label *next; + sljit_uw addr; + /* The maximum size difference. */ + sljit_uw size; +}; + +struct sljit_jump { + struct sljit_jump *next; + sljit_uw addr; + sljit_w flags; + union { + sljit_uw target; + struct sljit_label* label; + } u; +}; + +struct sljit_const { + struct sljit_const *next; + sljit_uw addr; +}; + +struct sljit_compiler { + int error; + + struct sljit_label *labels; + struct sljit_jump *jumps; + struct sljit_const *consts; + struct sljit_label *last_label; + struct sljit_jump *last_jump; + struct sljit_const *last_const; + + struct sljit_memory_fragment *buf; + struct sljit_memory_fragment *abuf; + + /* Used local registers. */ + int temporaries; + /* Used saved registers. */ + int saveds; + /* Local stack size. */ + int local_size; + /* Code size. */ + sljit_uw size; + /* For statistical purposes. */ + sljit_uw executable_size; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + int args; + int locals_offset; + int temporaries_start; + int saveds_start; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + int mode32; +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + int flags_saved; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + /* Constant pool handling. */ + sljit_uw *cpool; + sljit_ub *cpool_unique; + sljit_uw cpool_diff; + sljit_uw cpool_fill; + /* Other members. */ + /* Contains pointer, "ldr pc, [...]" pairs. */ + sljit_uw patches; +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + /* Temporary fields. */ + sljit_uw shift_imm; + int cache_arg; + sljit_w cache_argw; +#endif + +#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) + int cache_arg; + sljit_w cache_argw; +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_w imm; + int cache_arg; + sljit_w cache_argw; +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + int delay_slot; + int cache_arg; + sljit_w cache_argw; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + FILE* verbose; +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + /* Local size passed to the functions. */ + int logical_local_size; +#endif + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + int skip_checks; +#endif +}; + +/* --------------------------------------------------------------------- */ +/* Main functions */ +/* --------------------------------------------------------------------- */ + +/* Creates an sljit compiler. + Returns NULL if failed. */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void); +/* Free everything except the codes. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); + +static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } + +/* + Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, + and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler, + and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned. + Excellent for allocating small blocks during the compiling, and no need to worry + about freeing them. The size is enough to contain at most 16 pointers. + If the size is outside of the range, the function will return with NULL, + but this return value does not indicate that there is no more memory (does + not set the compiler to out-of-memory status). +*/ +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size); + +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +/* Passing NULL disables verbose. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); + +/* + After the code generation we can retrieve the allocated executable memory size, + although this area may not be fully filled with instructions depending on some + optimizations. This function is useful only for statistical purposes. + + Before a successful code generation, this function returns with 0. +*/ +static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } + +/* Instruction generation. Returns with error code. */ + +/* + The executable code is basically a function call from the viewpoint of + the C language. The function calls must obey to the ABI (Application + Binary Interface) of the platform, which specify the purpose of machine + registers and stack handling among other things. The sljit_emit_enter + function emits the necessary instructions for setting up a new context + for the executable code and moves function arguments to the saved + registers. The number of arguments are specified in the "args" + parameter and the first argument goes to SLJIT_SAVED_REG1, the second + goes to SLJIT_SAVED_REG2 and so on. The number of temporary and + saved registers are passed in "temporaries" and "saveds" arguments + respectively. Since the saved registers contains the arguments, + "args" must be less or equal than "saveds". The sljit_emit_enter + is also capable of allocating a stack space for local variables. The + "local_size" argument contains the size in bytes of this local area + and its staring address is stored in SLJIT_LOCALS_REG. However + the SLJIT_LOCALS_REG is not necessary the machine stack pointer. + The memory bytes between SLJIT_LOCALS_REG (inclusive) and + SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely + until the function returns. The stack space is uninitialized. + + Note: every call of sljit_emit_enter and sljit_set_context overwrites + the previous context. */ + +#define SLJIT_MAX_LOCAL_SIZE 65536 + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, + int args, int temporaries, int saveds, int local_size); + +/* The machine code has a context (which contains the local stack space size, + number of used registers, etc.) which initialized by sljit_emit_enter. Several + functions (like sljit_emit_return) requres this context to be able to generate + the appropriate code. However, some code fragments (like inline cache) may have + no normal entry point so their context is unknown for the compiler. Using the + function below we can specify thir context. + + Note: every call of sljit_emit_enter and sljit_set_context overwrites + the previous context. */ + +/* Note: multiple calls of this function overwrites the previous call. */ + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, + int args, int temporaries, int saveds, int local_size); + +/* Return from machine code. The op argument can be SLJIT_UNUSED which means the + function does not return with anything or any opcode between SLJIT_MOV and + SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op + is SLJIT_UNUSED, otherwise see below the description about source and + destination arguments. */ +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, + int src, sljit_w srcw); + +/* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL). + All registers and even the stack frame is passed to the callee. The return address is + preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can + use this as a return value later. */ + +/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions + are needed. Excellent for small uility functions, where saving registers and setting up + a new stack frame would cost too much performance. However, it is still possible to return + to the address of the caller (or anywhere else). */ + +/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */ + +/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, + since many architectures do clever branch prediction on call / return instruction pairs. */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw); +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw); + +/* + Source and destination values for arithmetical instructions + imm - a simple immediate value (cannot be used as a destination) + reg - any of the registers (immediate argument must be 0) + [imm] - absolute immediate memory address + [reg+imm] - indirect memory address + [reg+(reg<addr; } +static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } +static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; } + +/* Only the address is required to rewrite the code. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant); + +/* --------------------------------------------------------------------- */ +/* Miscellaneous utility functions */ +/* --------------------------------------------------------------------- */ + +#define SLJIT_MAJOR_VERSION 0 +#define SLJIT_MINOR_VERSION 88 + +/* Get the human readable name of the platfrom. + Can be useful for debugging on platforms like ARM, where ARM and + Thumb2 functions can be mixed. */ +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); + +/* Portble helper function to get an offset of a member. */ +#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10) + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) +/* This global lock is useful to compile common functions. */ +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void); +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void); +#endif + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) + +/* The sljit_stack is a utiliy feature of sljit, which allocates a + writable memory region between base (inclusive) and limit (exclusive). + Both base and limit is a pointer, and base is always <= than limit. + This feature uses the "address space reserve" feature + of modern operating systems. Basically we don't need to allocate a + huge memory block in one step for the worst case, we can start with + a smaller chunk and extend it later. Since the address space is + reserved, the data never copied to other regions, thus it is safe + to store pointers here. */ + +/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more). + Note: stack growing should not happen in small steps: 4k, 16k or even + bigger growth is better. + Note: this structure may not be supported by all operating systems. + Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK + is not defined. */ + +struct sljit_stack { + /* User data, anything can be stored here. + Starting with the same value as base. */ + sljit_uw top; + /* These members are read only. */ + sljit_uw base; + sljit_uw limit; + sljit_uw max_limit; +}; + +/* Returns NULL if unsuccessful. + Note: limit and max_limit contains the size for stack allocation + Note: the top field is initialized to base. */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit); +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack); + +/* Can be used to increase (allocate) or decrease (free) the memory area. + Returns with a non-zero value if unsuccessful. If new_limit is greater than + max_limit, it will fail. It is very easy to implement a stack data structure, + since the growth ratio can be added to the current limit, and sljit_stack_resize + will do all the necessary checks. The fields of the stack are not changed if + sljit_stack_resize fails. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit); + +#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */ + +#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + +/* Get the entry address of a given function. */ +#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name) + +#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ + +/* All JIT related code should be placed in the same context (library, binary, etc.). */ + +#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name) + +/* For powerpc64, the function pointers point to a context descriptor. */ +struct sljit_function_context { + sljit_w addr; + sljit_w r2; + sljit_w r11; +}; + +/* Fill the context arguments using the addr and the function. + If func_ptr is NULL, it will not be set to the address of context + If addr is NULL, the function address also comes from the func pointer. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func); + +#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ + +#endif /* _SLJIT_LIR_H_ */ diff -Nru pcre3-8.12/sljit/sljitNativeARM_Thumb2.c pcre3-8.31/sljit/sljitNativeARM_Thumb2.c --- pcre3-8.12/sljit/sljitNativeARM_Thumb2.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeARM_Thumb2.c 2012-04-03 15:33:31.000000000 +0000 @@ -0,0 +1,1939 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ + return "ARM-Thumb2" SLJIT_CPUINFO; +} + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define TMP_PC (SLJIT_NO_REGISTERS + 4) + +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) + +/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { + 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15 +}; + +#define COPY_BITS(src, from, to, bits) \ + ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to)) + +/* Thumb16 encodings. */ +#define RD3(rd) (reg_map[rd]) +#define RN3(rn) (reg_map[rn] << 3) +#define RM3(rm) (reg_map[rm] << 6) +#define RDN3(rdn) (reg_map[rdn] << 8) +#define IMM3(imm) (imm << 6) +#define IMM8(imm) (imm) + +/* Thumb16 helpers. */ +#define SET_REGS44(rd, rn) \ + ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4)) +#define IS_2_LO_REGS(reg1, reg2) \ + (reg_map[reg1] <= 7 && reg_map[reg2] <= 7) +#define IS_3_LO_REGS(reg1, reg2, reg3) \ + (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) + +/* Thumb32 encodings. */ +#define RD4(rd) (reg_map[rd] << 8) +#define RN4(rn) (reg_map[rn] << 16) +#define RM4(rm) (reg_map[rm]) +#define RT4(rt) (reg_map[rt] << 12) +#define DD4(dd) ((dd) << 12) +#define DN4(dn) ((dn) << 16) +#define DM4(dm) (dm) +#define IMM5(imm) \ + (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6)) +#define IMM12(imm) \ + (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)) + +typedef sljit_ui sljit_ins; + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +/* dot '.' changed to _ + I immediate form (possibly followed by number of immediate bits). */ +#define ADCI 0xf1400000 +#define ADCS 0x4140 +#define ADC_W 0xeb400000 +#define ADD 0x4400 +#define ADDS 0x1800 +#define ADDSI3 0x1c00 +#define ADDSI8 0x3000 +#define ADD_W 0xeb000000 +#define ADDWI 0xf2000000 +#define ADD_SP 0xb000 +#define ADD_W 0xeb000000 +#define ADD_WI 0xf1000000 +#define ANDI 0xf0000000 +#define ANDS 0x4000 +#define AND_W 0xea000000 +#define ASRS 0x4100 +#define ASRSI 0x1000 +#define ASR_W 0xfa40f000 +#define ASR_WI 0xea4f0020 +#define BICI 0xf0200000 +#define BKPT 0xbe00 +#define BLX 0x4780 +#define BX 0x4700 +#define CLZ 0xfab0f080 +#define CMPI 0x2800 +#define CMP_W 0xebb00f00 +#define EORI 0xf0800000 +#define EORS 0x4040 +#define EOR_W 0xea800000 +#define IT 0xbf00 +#define LSLS 0x4080 +#define LSLSI 0x0000 +#define LSL_W 0xfa00f000 +#define LSL_WI 0xea4f0000 +#define LSRS 0x40c0 +#define LSRSI 0x0800 +#define LSR_W 0xfa20f000 +#define LSR_WI 0xea4f0010 +#define MOV 0x4600 +#define MOVS 0x0000 +#define MOVSI 0x2000 +#define MOVT 0xf2c00000 +#define MOVW 0xf2400000 +#define MOV_W 0xea4f0000 +#define MOV_WI 0xf04f0000 +#define MUL 0xfb00f000 +#define MVNS 0x43c0 +#define MVN_W 0xea6f0000 +#define MVN_WI 0xf06f0000 +#define NOP 0xbf00 +#define ORNI 0xf0600000 +#define ORRI 0xf0400000 +#define ORRS 0x4300 +#define ORR_W 0xea400000 +#define POP 0xbd00 +#define POP_W 0xe8bd0000 +#define PUSH 0xb500 +#define PUSH_W 0xe92d0000 +#define RSB_WI 0xf1c00000 +#define RSBSI 0x4240 +#define SBCI 0xf1600000 +#define SBCS 0x4180 +#define SBC_W 0xeb600000 +#define SMULL 0xfb800000 +#define STR_SP 0x9000 +#define SUBS 0x1a00 +#define SUBSI3 0x1e00 +#define SUBSI8 0x3800 +#define SUB_W 0xeba00000 +#define SUBWI 0xf2a00000 +#define SUB_SP 0xb080 +#define SUB_WI 0xf1a00000 +#define SXTB 0xb240 +#define SXTB_W 0xfa4ff080 +#define SXTH 0xb200 +#define SXTH_W 0xfa0ff080 +#define TST 0x4200 +#define UMULL 0xfba00000 +#define UXTB 0xb2c0 +#define UXTB_W 0xfa5ff080 +#define UXTH 0xb280 +#define UXTH_W 0xfa1ff080 +#define VABS_F64 0xeeb00bc0 +#define VADD_F64 0xee300b00 +#define VCMP_F64 0xeeb40b40 +#define VDIV_F64 0xee800b00 +#define VMOV_F64 0xeeb00b40 +#define VMRS 0xeef1fa10 +#define VMUL_F64 0xee200b00 +#define VNEG_F64 0xeeb10b40 +#define VSTR 0xed000b00 +#define VSUB_F64 0xee300b40 + +static int push_inst16(struct sljit_compiler *compiler, sljit_ins inst) +{ + sljit_uh *ptr; + SLJIT_ASSERT(!(inst & 0xffff0000)); + + ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); + FAIL_IF(!ptr); + *ptr = inst; + compiler->size++; + return SLJIT_SUCCESS; +} + +static int push_inst32(struct sljit_compiler *compiler, sljit_ins inst) +{ + sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr++ = inst >> 16; + *ptr = inst; + compiler->size += 2; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_imm32_const(struct sljit_compiler *compiler, int dst, sljit_uw imm) +{ + FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | + COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); + return push_inst32(compiler, MOVT | RD4(dst) | + COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); +} + +static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm) +{ + int dst = inst[1] & 0x0f00; + SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); + inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); + inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); + inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1); + inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); +} + +static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +{ + sljit_w diff; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; + + if (jump->flags & JUMP_ADDR) { + /* Branch to ARM code is not optimized yet. */ + if (!(jump->u.target & 0x1)) + return 0; + diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)) >> 1; + } + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)) >> 1; + } + + if (jump->flags & IS_CONDITIONAL) { + SLJIT_ASSERT(!(jump->flags & IS_BL)); + if (diff <= 127 && diff >= -128) { + jump->flags |= B_TYPE1; + return 5; + } + if (diff <= 524287 && diff >= -524288) { + jump->flags |= B_TYPE2; + return 4; + } + /* +1 comes from the prefix IT instruction. */ + diff--; + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= B_TYPE3; + return 3; + } + } + else if (jump->flags & IS_BL) { + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= BL_TYPE6; + return 3; + } + } + else { + if (diff <= 1023 && diff >= -1024) { + jump->flags |= B_TYPE4; + return 4; + } + if (diff <= 8388607 && diff >= -8388608) { + jump->flags |= B_TYPE5; + return 3; + } + } + + return 0; +} + +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) +{ + sljit_uh* inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_addr); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 3); + } +} + +static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) +{ + int type = (jump->flags >> 4) & 0xf; + sljit_w diff; + sljit_uh *jump_inst; + int s, j1, j2; + + if (SLJIT_UNLIKELY(type == 0)) { + inline_set_jump_addr(jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + return; + } + + if (jump->flags & JUMP_ADDR) { + SLJIT_ASSERT(jump->u.target & 0x1); + diff = ((sljit_w)jump->u.target - (sljit_w)(jump->addr + 4)) >> 1; + } + else + diff = ((sljit_w)(jump->u.label->addr) - (sljit_w)(jump->addr + 4)) >> 1; + jump_inst = (sljit_uh*)jump->addr; + + switch (type) { + case 1: + /* Encoding T1 of 'B' instruction */ + SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_CONDITIONAL)); + jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff); + return; + case 2: + /* Encoding T3 of 'B' instruction */ + SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_CONDITIONAL)); + jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1); + jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff); + return; + case 3: + SLJIT_ASSERT(jump->flags & IS_CONDITIONAL); + *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8; + diff--; + type = 5; + break; + case 4: + /* Encoding T2 of 'B' instruction */ + SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_CONDITIONAL)); + jump_inst[0] = 0xe000 | (diff & 0x7ff); + return; + } + + SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608); + + /* Really complex instruction form for branches. */ + s = (diff >> 23) & 0x1; + j1 = (~(diff >> 21) ^ s) & 0x1; + j2 = (~(diff >> 22) ^ s) & 0x1; + jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10); + jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff); + + /* The others have a common form. */ + if (type == 5) /* Encoding T4 of 'B' instruction */ + jump_inst[1] |= 0x9000; + else if (type == 6) /* Encoding T1 of 'BL' instruction */ + jump_inst[1] |= 0xd000; + else + SLJIT_ASSERT_STOP(); +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_uh *code; + sljit_uh *code_ptr; + sljit_uh *buf_ptr; + sljit_uh *buf_end; + sljit_uw half_count; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + check_sljit_generate_code(compiler); + reverse_buf(compiler); + + code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + half_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + + do { + buf_ptr = (sljit_uh*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 1); + do { + *code_ptr = *buf_ptr++; + /* These structures are ordered by their address. */ + SLJIT_ASSERT(!label || label->size >= half_count); + SLJIT_ASSERT(!jump || jump->addr >= half_count); + SLJIT_ASSERT(!const_ || const_->addr >= half_count); + if (label && label->size == half_count) { + label->addr = ((sljit_uw)code_ptr) | 0x1; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == half_count) { + jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_CONDITIONAL) ? 10 : 8); + code_ptr -= detect_jump_type(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == half_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + half_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == half_count) { + label->addr = ((sljit_uw)code_ptr) | 0x1; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); + + jump = compiler->jumps; + while (jump) { + set_jump_instruction(jump); + jump = jump->next; + } + + SLJIT_CACHE_FLUSH(code, code_ptr); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = compiler->size * sizeof(sljit_uh); + /* Set thumb mode flag. */ + return (void*)((sljit_uw)code | 0x1); +} + +#define INVALID_IMM 0x80000000 +static sljit_uw get_imm(sljit_uw imm) +{ + /* Thumb immediate form. */ + int counter; + + if (imm <= 0xff) + return imm; + + if ((imm & 0xffff) == (imm >> 16)) { + /* Some special cases. */ + if (!(imm & 0xff00)) + return (1 << 12) | (imm & 0xff); + if (!(imm & 0xff)) + return (2 << 12) | ((imm >> 8) & 0xff); + if ((imm & 0xff00) == ((imm & 0xff) << 8)) + return (3 << 12) | (imm & 0xff); + } + + /* Assembly optimization: count leading zeroes? */ + counter = 8; + if (!(imm & 0xffff0000)) { + counter += 16; + imm <<= 16; + } + if (!(imm & 0xff000000)) { + counter += 8; + imm <<= 8; + } + if (!(imm & 0xf0000000)) { + counter += 4; + imm <<= 4; + } + if (!(imm & 0xc0000000)) { + counter += 2; + imm <<= 2; + } + if (!(imm & 0x80000000)) { + counter += 1; + imm <<= 1; + } + /* Since imm >= 128, this must be true. */ + SLJIT_ASSERT(counter <= 31); + + if (imm & 0x00ffffff) + return INVALID_IMM; /* Cannot be encoded. */ + + return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); +} + +static int load_immediate(struct sljit_compiler *compiler, int dst, sljit_uw imm) +{ + sljit_uw tmp; + + if (imm >= 0x10000) { + tmp = get_imm(imm); + if (tmp != INVALID_IMM) + return push_inst32(compiler, MOV_WI | RD4(dst) | tmp); + tmp = get_imm(~imm); + if (tmp != INVALID_IMM) + return push_inst32(compiler, MVN_WI | RD4(dst) | tmp); + } + + /* set low 16 bits, set hi 16 bits to 0. */ + FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | + COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); + + /* set hi 16 bit if needed. */ + if (imm >= 0x10000) + return push_inst32(compiler, MOVT | RD4(dst) | + COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); + return SLJIT_SUCCESS; +} + +#define ARG1_IMM 0x0010000 +#define ARG2_IMM 0x0020000 +#define KEEP_FLAGS 0x0040000 +#define SET_MULOV 0x0080000 +/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */ +#define SET_FLAGS 0x0100000 +#define UNUSED_RETURN 0x0200000 +#define SLOW_DEST 0x0400000 +#define SLOW_SRC1 0x0800000 +#define SLOW_SRC2 0x1000000 + +static int emit_op_imm(struct sljit_compiler *compiler, int flags, int dst, sljit_uw arg1, sljit_uw arg2) +{ + /* dst must be register, TMP_REG1 + arg1 must be register, TMP_REG1, imm + arg2 must be register, TMP_REG2, imm */ + int reg; + sljit_uw imm, negated_imm; + + if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { + /* Both are immediates. */ + flags &= ~ARG1_IMM; + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + + if (flags & (ARG1_IMM | ARG2_IMM)) { + reg = (flags & ARG2_IMM) ? arg1 : arg2; + imm = (flags & ARG2_IMM) ? arg2 : arg1; + + switch (flags & 0xffff) { + case SLJIT_MOV: + SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); + return load_immediate(compiler, dst, imm); + case SLJIT_NOT: + if (!(flags & SET_FLAGS)) + return load_immediate(compiler, dst, ~imm); + /* Since the flags should be set, we just fallback to the register mode. + Although I could do some clever things here, "NOT IMM" does not worth the efforts. */ + break; + case SLJIT_CLZ: + /* No form with immediate operand. */ + break; + case SLJIT_ADD: + negated_imm = (sljit_uw)-(sljit_w)imm; + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { + if (imm <= 0x7) + return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); + if (negated_imm <= 0x7) + return push_inst16(compiler, SUBSI3 | IMM3(negated_imm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst)); + if (negated_imm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(negated_imm) | RDN3(dst)); + } + } + if (!(flags & SET_FLAGS)) { + if (imm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm)); + if (negated_imm <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(negated_imm)); + } + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_ADDC: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SUB: + if (flags & ARG2_IMM) { + negated_imm = (sljit_uw)-(sljit_w)imm; + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { + if (imm <= 0x7) + return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); + if (negated_imm <= 0x7) + return push_inst16(compiler, ADDSI3 | IMM3(negated_imm) | RD3(dst) | RN3(reg)); + if (reg == dst) { + if (imm <= 0xff) + return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst)); + if (negated_imm <= 0xff) + return push_inst16(compiler, ADDSI8 | IMM8(negated_imm) | RDN3(dst)); + } + if (imm <= 0xff && (flags & UNUSED_RETURN)) + return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg)); + } + if (!(flags & SET_FLAGS)) { + if (imm <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm)); + if (negated_imm <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(negated_imm)); + } + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + } + else { + if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst)) + return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg)); + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + } + break; + case SLJIT_SUBC: + if (flags & ARG2_IMM) { + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + } + break; + case SLJIT_MUL: + /* No form with immediate operand. */ + break; + case SLJIT_AND: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1)); + if (imm != INVALID_IMM) + return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_OR: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1)); + if (imm != INVALID_IMM) + return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_XOR: + imm = get_imm(imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + break; + case SLJIT_SHL: + if (flags & ARG2_IMM) { + imm &= 0x1f; + if (imm == 0) { + if (!(flags & SET_FLAGS)) + return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); + } + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + } + break; + case SLJIT_LSHR: + if (flags & ARG2_IMM) { + imm &= 0x1f; + if (imm == 0) { + if (!(flags & SET_FLAGS)) + return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); + } + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + } + break; + case SLJIT_ASHR: + if (flags & ARG2_IMM) { + imm &= 0x1f; + if (imm == 0) { + if (!(flags & SET_FLAGS)) + return push_inst16(compiler, MOV | SET_REGS44(dst, reg)); + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg)); + } + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6)); + return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm)); + } + break; + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (flags & ARG2_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG2, arg2)); + arg2 = TMP_REG2; + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG1, arg1)); + arg1 = TMP_REG1; + } + } + + /* Both arguments are registers. */ + switch (flags & 0xffff) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); + case SLJIT_MOV_UB: + case SLJIT_MOVU_UB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_SB: + case SLJIT_MOVU_SB: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_UH: + case SLJIT_MOVU_UH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); + case SLJIT_MOV_SH: + case SLJIT_MOVU_SH: + SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); + case SLJIT_NOT: + SLJIT_ASSERT(arg1 == TMP_REG1); + if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); + case SLJIT_CLZ: + SLJIT_ASSERT(arg1 == TMP_REG1); + FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2))); + if (flags & SET_FLAGS) { + if (reg_map[dst] <= 7) + return push_inst16(compiler, CMPI | RDN3(dst)); + return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst)); + } + return SLJIT_SUCCESS; + case SLJIT_ADD: + if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) + return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2)); + if (dst == arg1 && !(flags & SET_FLAGS)) + return push_inst16(compiler, ADD | SET_REGS44(dst, arg2)); + return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_ADDC: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SUB: + if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2)) + return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2)); + return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SUBC: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_MUL: + if (!(flags & SET_FLAGS)) + return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2)); + SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2); + FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2))); + /* cmp TMP_REG2, dst asr #31. */ + return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst)); + case SLJIT_AND: + if (!(flags & KEEP_FLAGS)) { + if (dst == arg1 && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2)); + if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2)) + return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2)); + } + return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_OR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_XOR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_SHL: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_LSHR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + case SLJIT_ASHR: + if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2)); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +#define STORE 0x01 +#define SIGNED 0x02 + +#define WORD_SIZE 0x00 +#define BYTE_SIZE 0x04 +#define HALF_SIZE 0x08 + +#define UPDATE 0x10 +#define ARG_TEST 0x20 + +#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE))) +#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift))) + +/* + 1st letter: + w = word + b = byte + h = half + + 2nd letter: + s = signed + u = unsigned + + 3rd letter: + l = load + s = store +*/ + +static SLJIT_CONST sljit_uw sljit_mem16[12] = { +/* w u l */ 0x5800 /* ldr */, +/* w u s */ 0x5000 /* str */, +/* w s l */ 0x5800 /* ldr */, +/* w s s */ 0x5000 /* str */, + +/* b u l */ 0x5c00 /* ldrb */, +/* b u s */ 0x5400 /* strb */, +/* b s l */ 0x5600 /* ldrsb */, +/* b s s */ 0x5400 /* strb */, + +/* h u l */ 0x5a00 /* ldrh */, +/* h u s */ 0x5200 /* strh */, +/* h s l */ 0x5e00 /* ldrsh */, +/* h s s */ 0x5200 /* strh */, +}; + +static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = { +/* w u l */ 0x6800 /* ldr imm5 */, +/* w u s */ 0x6000 /* str imm5 */, +/* w s l */ 0x6800 /* ldr imm5 */, +/* w s s */ 0x6000 /* str imm5 */, + +/* b u l */ 0x7800 /* ldrb imm5 */, +/* b u s */ 0x7000 /* strb imm5 */, +/* b s l */ 0x0000 /* not allowed */, +/* b s s */ 0x7000 /* strb imm5 */, + +/* h u l */ 0x8800 /* ldrh imm5 */, +/* h u s */ 0x8000 /* strh imm5 */, +/* h s l */ 0x0000 /* not allowed */, +/* h s s */ 0x8000 /* strh imm5 */, +}; + +#define MEM_IMM8 0xc00 +#define MEM_IMM12 0x800000 +static SLJIT_CONST sljit_uw sljit_mem32[12] = { +/* w u l */ 0xf8500000 /* ldr.w */, +/* w u s */ 0xf8400000 /* str.w */, +/* w s l */ 0xf8500000 /* ldr.w */, +/* w s s */ 0xf8400000 /* str.w */, + +/* b u l */ 0xf8100000 /* ldrb.w */, +/* b u s */ 0xf8000000 /* strb.w */, +/* b s l */ 0xf9100000 /* ldrsb.w */, +/* b s s */ 0xf8000000 /* strb.w */, + +/* h u l */ 0xf8300000 /* ldrh.w */, +/* h u s */ 0xf8200000 /* strsh.w */, +/* h s l */ 0xf9300000 /* ldrsh.w */, +/* h s s */ 0xf8200000 /* strsh.w */, +}; + +/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ +static int emit_set_delta(struct sljit_compiler *compiler, int dst, int reg, sljit_w value) +{ + if (value >= 0) { + if (value <= 0xfff) + return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value)); + value = get_imm(value); + if (value != INVALID_IMM) + return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value); + } + else { + value = -value; + if (value <= 0xfff) + return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value)); + value = get_imm(value); + if (value != INVALID_IMM) + return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value); + } + return SLJIT_ERR_UNSUPPORTED; +} + +/* Can perform an operation using at most 1 instruction. */ +static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) +{ + int tmp; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + if ((arg & 0xf) && !(arg & 0xf0) && argw <= 0xff && argw >= -0xff) { + flags &= ~UPDATE; + arg &= 0xf; + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + if (argw >= 0) + argw |= 0x200; + else { + argw = -argw; + } + SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff); + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw)); + return -1; + } + return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; + } + + if (SLJIT_UNLIKELY(arg & 0xf0)) { + argw &= 0x3; + tmp = (arg >> 4) & 0xf; + arg &= 0xf; + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + if (!argw && IS_3_LO_REGS(reg, arg, tmp)) + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp))); + else + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4))); + return -1; + } + + if (!(arg & 0xf) || argw > 0xfff || argw < -0xff) + return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; + + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + + arg &= 0xf; + if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) { + tmp = 3; + if (IS_WORD_SIZE(flags)) { + if (OFFSET_CHECK(0x1f, 2)) + tmp = 2; + } + else if (flags & BYTE_SIZE) + { + if (OFFSET_CHECK(0x1f, 0)) + tmp = 0; + } + else { + SLJIT_ASSERT(flags & HALF_SIZE); + if (OFFSET_CHECK(0x1f, 1)) + tmp = 1; + } + + if (tmp != 3) { + FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp)))); + return -1; + } + } + + /* SP based immediate. */ + if (SLJIT_UNLIKELY(arg == SLJIT_LOCALS_REG) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) { + FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2))); + return -1; + } + + if (argw >= 0) + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); + else + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw)); + return -1; +} + +/* see getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + /* Simple operation except for updates. */ + if ((arg & 0xf0) || !(next_arg & SLJIT_MEM)) + return 0; + + if (!(arg & 0xf)) { + if ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff) + return 1; + return 0; + } + + if (argw == next_argw) + return 1; + + if (arg == next_arg && ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff)) + return 1; + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + int tmp_r; + sljit_w tmp; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + tmp_r = (flags & STORE) ? TMP_REG3 : reg; + + if (SLJIT_UNLIKELY(flags & UPDATE)) { + flags &= ~UPDATE; + /* Update only applies if a base register exists. */ + if (arg & 0xf) { + /* There is no caching here. */ + tmp = (arg & 0xf0) >> 4; + arg &= 0xf; + + if (!tmp) { + if (!(argw & ~0xfff)) { + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw)); + return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw)); + } + + if (compiler->cache_arg == SLJIT_MEM) { + if (argw == compiler->cache_argw) { + tmp = TMP_REG3; + argw = 0; + } + else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + tmp = TMP_REG3; + argw = 0; + } + } + + if (argw) { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + tmp = TMP_REG3; + argw = 0; + } + } + + argw &= 0x3; + if (!argw && IS_3_LO_REGS(reg, arg, tmp)) { + FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp))); + return push_inst16(compiler, ADD | SET_REGS44(arg, tmp)); + } + FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4))); + return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(tmp) | (argw << 6)); + } + } + + SLJIT_ASSERT(!(arg & 0xf0)); + + if (compiler->cache_arg == arg) { + if (!((argw - compiler->cache_argw) & ~0xfff)) + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | (argw - compiler->cache_argw)); + if (!((compiler->cache_argw - argw) & ~0xff)) + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); + } + } + + next_arg = (arg & 0xf) && (arg == next_arg); + arg &= 0xf; + if (arg && compiler->cache_arg == SLJIT_MEM && compiler->cache_argw == argw) + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + + compiler->cache_argw = argw; + if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + else { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + compiler->cache_arg = SLJIT_MEM; + + if (next_arg) { + FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg))); + compiler->cache_arg = SLJIT_MEM | arg; + arg = 0; + } + } + + if (arg) + return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3)); + return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); +} + +static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) +{ + if (getput_arg_fast(compiler, flags, reg, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg, arg, argw, 0, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size; + sljit_ins push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + push = (1 << 4); + if (saveds >= 5) + push |= 1 << 11; + if (saveds >= 4) + push |= 1 << 10; + if (saveds >= 3) + push |= 1 << 8; + if (saveds >= 2) + push |= 1 << 7; + if (saveds >= 1) + push |= 1 << 6; + if (temporaries >= 5) + push |= 1 << 5; + FAIL_IF(saveds >= 3 + ? push_inst32(compiler, PUSH_W | (1 << 14) | push) + : push_inst16(compiler, PUSH | push)); + + /* Stack must be aligned to 8 bytes: */ + size = (3 + saveds) * sizeof(sljit_uw); + local_size += size; + local_size = (local_size + 7) & ~7; + local_size -= size; + compiler->local_size = local_size; + if (local_size > 0) { + if (local_size <= (127 << 2)) + FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2))); + else + FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, local_size)); + } + + if (args >= 1) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1))); + if (args >= 2) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2))); + if (args >= 3) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + size = (3 + saveds) * sizeof(sljit_uw); + local_size += size; + local_size = (local_size + 7) & ~7; + local_size -= size; + compiler->local_size = local_size; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + sljit_ins pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size > 0) { + if (compiler->local_size <= (127 << 2)) + FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2))); + else + FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, compiler->local_size)); + } + + pop = (1 << 4); + if (compiler->saveds >= 5) + pop |= 1 << 11; + if (compiler->saveds >= 4) + pop |= 1 << 10; + if (compiler->saveds >= 3) + pop |= 1 << 8; + if (compiler->saveds >= 2) + pop |= 1 << 7; + if (compiler->saveds >= 1) + pop |= 1 << 6; + if (compiler->temporaries >= 5) + pop |= 1 << 5; + return compiler->saveds >= 3 + ? push_inst32(compiler, POP_W | (1 << 15) | pop) + : push_inst16(compiler, POP | pop); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); +extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + push_inst16(compiler, BKPT); + break; + case SLJIT_NOP: + push_inst16(compiler, NOP); + break; + case SLJIT_UMUL: + case SLJIT_SMUL: + return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_TEMPORARY_REG2] << 8) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 16) + | reg_map[SLJIT_TEMPORARY_REG2]); + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->temporaries >= 4) { + FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); + FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); + } else if (compiler->temporaries >= 3) + FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */)); +#if defined(__GNUC__) + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, + (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); +#else +#error "Software divmod functions are needed" +#endif + if (compiler->temporaries >= 4) { + FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); + return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); + } else if (compiler->temporaries >= 3) + return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int op_type, dst_r, flags; + + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + op_type = GET_OPCODE(op); + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + + if (op_type >= SLJIT_MOV && op_type <= SLJIT_MOVU_SI) { + switch (op_type) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + flags = WORD_SIZE; + break; + case SLJIT_MOV_UB: + flags = BYTE_SIZE; + if (src & SLJIT_IMM) + srcw = (unsigned char)srcw; + break; + case SLJIT_MOV_SB: + flags = BYTE_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (signed char)srcw; + break; + case SLJIT_MOV_UH: + flags = HALF_SIZE; + if (src & SLJIT_IMM) + srcw = (unsigned short)srcw; + break; + case SLJIT_MOV_SH: + flags = HALF_SIZE | SIGNED; + if (src & SLJIT_IMM) + srcw = (signed short)srcw; + break; + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + flags = WORD_SIZE | UPDATE; + break; + case SLJIT_MOVU_UB: + flags = BYTE_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (unsigned char)srcw; + break; + case SLJIT_MOVU_SB: + flags = BYTE_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (signed char)srcw; + break; + case SLJIT_MOVU_UH: + flags = HALF_SIZE | UPDATE; + if (src & SLJIT_IMM) + srcw = (unsigned short)srcw; + break; + case SLJIT_MOVU_SH: + flags = HALF_SIZE | SIGNED | UPDATE; + if (src & SLJIT_IMM) + srcw = (signed short)srcw; + break; + default: + SLJIT_ASSERT_STOP(); + flags = 0; + break; + } + + if (src & SLJIT_IMM) + FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags, dst_r, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); + } else { + if (dst_r != TMP_REG1) + return emit_op_imm(compiler, op_type, dst_r, TMP_REG1, src); + dst_r = src; + } + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; + } + + if (op_type == SLJIT_NEG) { +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, GET_FLAGS(op) | SLJIT_SUB, dst, dstw, SLJIT_IMM, 0, src, srcw); + } + + flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); + if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw)) + FAIL_IF(compiler->error); + else + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw)); + src = TMP_REG2; + } + + if (src & SLJIT_IMM) + flags |= ARG2_IMM; + else + srcw = src; + + emit_op_imm(compiler, flags | op_type, dst_r, TMP_REG1, srcw); + + if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) + return compiler->error; + else + return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_r, flags; + + CHECK_ERROR(); + check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); + + if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) + flags |= SLOW_DEST; + + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + } + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw)); + + if (src1 & SLJIT_MEM) + src1 = TMP_REG1; + if (src2 & SLJIT_MEM) + src2 = TMP_REG2; + + if (src1 & SLJIT_IMM) + flags |= ARG1_IMM; + else + src1w = src1; + if (src2 & SLJIT_IMM) + flags |= ARG2_IMM; + else + src2w = src2; + + if (dst == SLJIT_UNUSED) + flags |= UNUSED_RETURN; + + if (GET_OPCODE(op) == SLJIT_MUL && (op & SLJIT_SET_O)) + flags |= SET_MULOV; + + emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw); + return compiler->error; + } + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size == 2 || size == 4); + + if (size == 2) + return push_inst16(compiler, *(sljit_uh*)instruction); + return push_inst32(compiler, *(sljit_ins*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ + return 1; +} + +static int emit_fop_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) +{ + sljit_w tmp; + sljit_w inst = VSTR | ((flags & STORE) ? 0 : 0x00100000); + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (SLJIT_UNLIKELY(arg & 0xf0)) { + FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & 0xf) | RM4((arg & 0xf0) >> 4) | ((argw & 0x3) << 6))); + arg = SLJIT_MEM | TMP_REG2; + argw = 0; + } + + if (arg & 0xf) { + if (!(argw & ~0x3fc)) + return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2)); + if (!(-argw & ~0x3fc)) + return push_inst32(compiler, inst | RN4(arg & 0xf) | DD4(reg) | (-argw >> 2)); + } + + SLJIT_ASSERT(!(arg & 0xf0)); + if (compiler->cache_arg == arg) { + tmp = argw - compiler->cache_argw; + if (!(tmp & ~0x3fc)) + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2)); + if (!(-tmp & ~0x3fc)) + return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2)); + if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { + FAIL_IF(compiler->error); + compiler->cache_argw = argw; + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + if (SLJIT_UNLIKELY(!(arg & 0xf))) + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + else if (emit_set_delta(compiler, TMP_REG3, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) + FAIL_IF(compiler->error); + else { + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + if (arg & 0xf) + FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & 0xf)))); + } + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst & SLJIT_MEM) { + emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); + dst = TMP_FREG1; + } + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, 0, TMP_FREG2, src, srcw); + src = TMP_FREG2; + } + FAIL_IF(push_inst32(compiler, VCMP_F64 | DD4(dst) | DM4(src))); + return push_inst32(compiler, VMRS); + } + + dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; + if (src & SLJIT_MEM) { + emit_fop_mem(compiler, 0, dst_r, src, srcw); + src = dst_r; + } + + switch (GET_OPCODE(op)) { + case SLJIT_FMOV: + if (src != dst_r) + FAIL_IF(push_inst32(compiler, VMOV_F64 | DD4(dst_r) | DM4(src))); + break; + case SLJIT_FNEG: + FAIL_IF(push_inst32(compiler, VNEG_F64 | DD4(dst_r) | DM4(src))); + break; + case SLJIT_FABS: + FAIL_IF(push_inst32(compiler, VABS_F64 | DD4(dst_r) | DM4(src))); + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; + if (src1 & SLJIT_MEM) { + emit_fop_mem(compiler, 0, TMP_FREG1, src1, src1w); + src1 = TMP_FREG1; + } + if (src2 & SLJIT_MEM) { + emit_fop_mem(compiler, 0, TMP_FREG2, src2, src2w); + src2 = TMP_FREG2; + } + + switch (GET_OPCODE(op)) { + case SLJIT_FADD: + FAIL_IF(push_inst32(compiler, VADD_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_FSUB: + FAIL_IF(push_inst32(compiler, VSUB_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_FMUL: + FAIL_IF(push_inst32(compiler, VMUL_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + case SLJIT_FDIV: + FAIL_IF(push_inst32(compiler, VDIV_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); + break; + } + + if (dst & SLJIT_MEM) + return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); + else if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) + FAIL_IF(compiler->error); + else { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0)); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2))); + } + } + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); + return push_inst16(compiler, BLX | RN3(TMP_REG3)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(int type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_MUL_NOT_OVERFLOW: + case SLJIT_C_FLOAT_EQUAL: + return 0x0; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_MUL_OVERFLOW: + case SLJIT_C_FLOAT_NOT_EQUAL: + return 0x1; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return 0x3; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return 0x2; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return 0x8; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return 0x9; + + case SLJIT_C_SIG_LESS: + return 0xb; + + case SLJIT_C_SIG_GREATER_EQUAL: + return 0xa; + + case SLJIT_C_SIG_GREATER: + return 0xc; + + case SLJIT_C_SIG_LESS_EQUAL: + return 0xd; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_FLOAT_NAN: + return 0x6; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_NOT_NAN: + return 0x7; + + default: /* SLJIT_JUMP */ + return 0xe; + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + check_sljit_emit_label(compiler); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + struct sljit_jump *jump; + int cc; + + CHECK_ERROR_PTR(); + check_sljit_emit_jump(compiler, type); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In ARM, we don't need to touch the arguments. */ + PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); + if (type < SLJIT_JUMP) { + jump->flags |= IS_CONDITIONAL; + cc = get_cc(type); + jump->flags |= cc << 8; + PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + } + + jump->addr = compiler->size; + if (type <= SLJIT_JUMP) + PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1))); + else { + jump->flags |= IS_BL; + PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1))); + } + + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + struct sljit_jump *jump; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + /* In ARM, we don't need to touch the arguments. */ + if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); + jump->u.target = srcw; + + FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0)); + jump->addr = compiler->size; + FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1))); + } + else { + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); + + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw)); + if (type >= SLJIT_FAST_CALL) + return push_inst16(compiler, BLX | RN3(TMP_REG1)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + int dst_r; + sljit_uw cc; + + CHECK_ERROR(); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + cc = get_cc(type); + if (GET_OPCODE(op) == SLJIT_OR && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); + FAIL_IF(push_inst32(compiler, ORRI | RN4(dst) | RD4(dst) | 0x1)); + if (op & SLJIT_SET_E) { + if (reg_map[dst] <= 7) + return push_inst16(compiler, ORRS | RD3(dst) | RN3(dst)); + return push_inst32(compiler, ORR_W | SET_FLAGS | RD4(TMP_REG1) | RN4(dst) | RM4(dst)); + } + return SLJIT_SUCCESS; + } + + dst_r = TMP_REG2; + if (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && reg_map[dst] <= 7) + dst_r = dst; + + FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); + FAIL_IF(push_inst16(compiler, MOVSI | 0x1 | RDN3(dst_r))); + FAIL_IF(push_inst16(compiler, MOVSI | 0x0 | RDN3(dst_r))); + + if (dst_r == TMP_REG2) { + if (GET_OPCODE(op) == SLJIT_OR) { +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG2, 0); + } + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); + else + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + struct sljit_const *const_; + int dst_r; + + CHECK_ERROR_PTR(); + check_sljit_emit_const(compiler, dst, dstw, init_value); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + inline_set_jump_addr(addr, new_addr, 1); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + sljit_uh* inst = (sljit_uh*)addr; + modify_imm32_const(inst, new_constant); + SLJIT_CACHE_FLUSH(inst, inst + 3); +} diff -Nru pcre3-8.12/sljit/sljitNativeARM_v5.c pcre3-8.31/sljit/sljitNativeARM_v5.c --- pcre3-8.12/sljit/sljitNativeARM_v5.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeARM_v5.c 2012-04-03 15:33:31.000000000 +0000 @@ -0,0 +1,2456 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + return "ARMv7" SLJIT_CPUINFO; +#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + return "ARMv5" SLJIT_CPUINFO; +#else +#error "Internal error: Unknown ARM architecture" +#endif +} + +/* Last register + 1. */ +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define TMP_PC (SLJIT_NO_REGISTERS + 4) + +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) + +/* In ARM instruction words. + Cache lines are usually 32 byte aligned. */ +#define CONST_POOL_ALIGNMENT 8 +#define CONST_POOL_EMPTY 0xffffffff + +#define ALIGN_INSTRUCTION(ptr) \ + (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) +#define MAX_DIFFERENCE(max_diff) \ + (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + +/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { + 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 +}; + +#define RM(rm) (reg_map[rm]) +#define RD(rd) (reg_map[rd] << 12) +#define RN(rn) (reg_map[rn] << 16) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +/* The instruction includes the AL condition. + INST_NAME - CONDITIONAL remove this flag. */ +#define COND_MASK 0xf0000000 +#define CONDITIONAL 0xe0000000 +#define PUSH_POOL 0xff000000 + +/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */ +#define ADC_DP 0x5 +#define ADD_DP 0x4 +#define AND_DP 0x0 +#define B 0xea000000 +#define BIC_DP 0xe +#define BL 0xeb000000 +#define BLX 0xe12fff30 +#define BX 0xe12fff10 +#define CLZ 0xe16f0f10 +#define CMP_DP 0xa +#define BKPT 0xe1200070 +#define EOR_DP 0x1 +#define MOV_DP 0xd +#define MUL 0xe0000090 +#define MVN_DP 0xf +#define NOP 0xe1a00000 +#define ORR_DP 0xc +#define PUSH 0xe92d0000 +#define POP 0xe8bd0000 +#define RSB_DP 0x3 +#define RSC_DP 0x7 +#define SBC_DP 0x6 +#define SMULL 0xe0c00090 +#define SUB_DP 0x2 +#define UMULL 0xe0800090 +#define VABS_F64 0xeeb00bc0 +#define VADD_F64 0xee300b00 +#define VCMP_F64 0xeeb40b40 +#define VDIV_F64 0xee800b00 +#define VMOV_F64 0xeeb00b40 +#define VMRS 0xeef1fa10 +#define VMUL_F64 0xee200b00 +#define VNEG_F64 0xeeb10b40 +#define VSTR 0xed000b00 +#define VSUB_F64 0xee300b40 + +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +/* Arm v7 specific instructions. */ +#define MOVW 0xe3000000 +#define MOVT 0xe3400000 +#define SXTB 0xe6af0070 +#define SXTH 0xe6bf0070 +#define UXTB 0xe6ef0070 +#define UXTH 0xe6ff0070 +#endif + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + +static int push_cpool(struct sljit_compiler *compiler) +{ + /* Pushing the constant pool into the instruction stream. */ + sljit_uw* inst; + sljit_uw* cpool_ptr; + sljit_uw* cpool_end; + int i; + + /* The label could point the address after the constant pool. */ + if (compiler->last_label && compiler->last_label->size == compiler->size) + compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; + + SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = 0xff000000 | compiler->cpool_fill; + + for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = 0; + } + + cpool_ptr = compiler->cpool; + cpool_end = cpool_ptr + compiler->cpool_fill; + while (cpool_ptr < cpool_end) { + inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!inst); + compiler->size++; + *inst = *cpool_ptr++; + } + compiler->cpool_diff = CONST_POOL_EMPTY; + compiler->cpool_fill = 0; + return SLJIT_SUCCESS; +} + +static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) +{ + sljit_uw* ptr; + + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) + FAIL_IF(push_cpool(compiler)); + + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst; + return SLJIT_SUCCESS; +} + +static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +{ + sljit_uw* ptr; + sljit_uw cpool_index = CPOOL_SIZE; + sljit_uw* cpool_ptr; + sljit_uw* cpool_end; + sljit_ub* cpool_unique_ptr; + + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) + FAIL_IF(push_cpool(compiler)); + else if (compiler->cpool_fill > 0) { + cpool_ptr = compiler->cpool; + cpool_end = cpool_ptr + compiler->cpool_fill; + cpool_unique_ptr = compiler->cpool_unique; + do { + if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) { + cpool_index = cpool_ptr - compiler->cpool; + break; + } + cpool_ptr++; + cpool_unique_ptr++; + } while (cpool_ptr < cpool_end); + } + + if (cpool_index == CPOOL_SIZE) { + /* Must allocate a new entry in the literal pool. */ + if (compiler->cpool_fill < CPOOL_SIZE) { + cpool_index = compiler->cpool_fill; + compiler->cpool_fill++; + } + else { + FAIL_IF(push_cpool(compiler)); + cpool_index = 0; + compiler->cpool_fill = 1; + } + } + + SLJIT_ASSERT((inst & 0xfff) == 0); + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst | cpool_index; + + compiler->cpool[cpool_index] = literal; + compiler->cpool_unique[cpool_index] = 0; + if (compiler->cpool_diff == CONST_POOL_EMPTY) + compiler->cpool_diff = compiler->size; + return SLJIT_SUCCESS; +} + +static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +{ + sljit_uw* ptr; + if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) + FAIL_IF(push_cpool(compiler)); + + SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst | compiler->cpool_fill; + + compiler->cpool[compiler->cpool_fill] = literal; + compiler->cpool_unique[compiler->cpool_fill] = 1; + compiler->cpool_fill++; + if (compiler->cpool_diff == CONST_POOL_EMPTY) + compiler->cpool_diff = compiler->size; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler) +{ + /* Place for at least two instruction (doesn't matter whether the first has a literal). */ + if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) + return push_cpool(compiler); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler) +{ + /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ + SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); + return push_inst(compiler, BLX | RM(TMP_REG1)); +} + +static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size) +{ + sljit_uw diff; + sljit_uw ind; + sljit_uw counter = 0; + sljit_uw* clear_const_pool = const_pool; + sljit_uw* clear_const_pool_end = const_pool + cpool_size; + + SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT); + /* Set unused flag for all literals in the constant pool. + I.e.: unused literals can belong to branches, which can be encoded as B or BL. + We can "compress" the constant pool by discarding these literals. */ + while (clear_const_pool < clear_const_pool_end) + *clear_const_pool++ = (sljit_uw)(-1); + + while (last_pc_patch < code_ptr) { + /* Data transfer instruction with Rn == r15. */ + if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { + diff = const_pool - last_pc_patch; + ind = (*last_pc_patch) & 0xfff; + + /* Must be a load instruction with immediate offset. */ + SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); + if ((int)const_pool[ind] < 0) { + const_pool[ind] = counter; + ind = counter; + counter++; + } + else + ind = const_pool[ind]; + + SLJIT_ASSERT(diff >= 1); + if (diff >= 2 || ind > 0) { + diff = (diff + ind - 2) << 2; + SLJIT_ASSERT(diff <= 0xfff); + *last_pc_patch = (*last_pc_patch & ~0xfff) | diff; + } + else + *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004; + } + last_pc_patch++; + } + return counter; +} + +/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ +struct future_patch { + struct future_patch* next; + int index; + int value; +}; + +static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +{ + int value; + struct future_patch *curr_patch, *prev_patch; + + /* Using the values generated by patch_pc_relative_loads. */ + if (!*first_patch) + value = (int)cpool_start_address[cpool_current_index]; + else { + curr_patch = *first_patch; + prev_patch = 0; + while (1) { + if (!curr_patch) { + value = (int)cpool_start_address[cpool_current_index]; + break; + } + if ((sljit_uw)curr_patch->index == cpool_current_index) { + value = curr_patch->value; + if (prev_patch) + prev_patch->next = curr_patch->next; + else + *first_patch = curr_patch->next; + SLJIT_FREE(curr_patch); + break; + } + prev_patch = curr_patch; + curr_patch = curr_patch->next; + } + } + + if (value >= 0) { + if ((sljit_uw)value > cpool_current_index) { + curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch)); + if (!curr_patch) { + while (*first_patch) { + curr_patch = *first_patch; + *first_patch = (*first_patch)->next; + SLJIT_FREE(curr_patch); + } + return SLJIT_ERR_ALLOC_FAILED; + } + curr_patch->next = *first_patch; + curr_patch->index = value; + curr_patch->value = cpool_start_address[value]; + *first_patch = curr_patch; + } + cpool_start_address[value] = *buf_ptr; + } + return SLJIT_SUCCESS; +} + +#else + +static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) +{ + sljit_uw* ptr; + + ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + FAIL_IF(!ptr); + compiler->size++; + *ptr = inst; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm) +{ + FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); + return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); +} + +#endif + +static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +{ + sljit_w diff; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (jump->flags & IS_BL) + code_ptr--; + + if (jump->flags & JUMP_ADDR) + diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + diff >>= 2; + if (jump->flags & IS_BL) { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK); + jump->flags |= PATCH_B; + return 1; + } + } + else { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); + jump->flags |= PATCH_B; + } + } +#else + if (jump->flags & JUMP_ADDR) + diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr); + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr); + } + + /* Branch to Thumb code has not been optimized yet. */ + if (diff & 0x3) + return 0; + + diff >>= 2; + if (diff <= 0x01ffffff && diff >= -0x02000000) { + code_ptr -= 2; + *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK); + jump->flags |= PATCH_B; + return 1; + } +#endif + return 0; +} + +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) +{ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw *ptr = (sljit_uw*)addr; + sljit_uw *inst = (sljit_uw*)ptr[0]; + sljit_uw mov_pc = ptr[1]; + int bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2); + + if (diff <= 0x7fffff && diff >= -0x800000) { + /* Turn to branch. */ + if (!bl) { + inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } else { + inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff); + inst[1] = NOP; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } + } + } else { + /* Get the position of the constant. */ + if (mov_pc & (1 << 23)) + ptr = inst + ((mov_pc & 0xfff) >> 2) + 2; + else + ptr = inst + 1; + + if (*inst != mov_pc) { + inst[0] = mov_pc; + if (!bl) { + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } else { + inst[1] = BLX | RM(TMP_REG1); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } + } + } + *ptr = new_addr; + } +#else + sljit_uw *inst = (sljit_uw*)addr; + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff); + inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } +#endif +} + +static sljit_uw get_immediate(sljit_uw imm); + +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush) +{ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw *ptr = (sljit_uw*)addr; + sljit_uw *inst = (sljit_uw*)ptr[0]; + sljit_uw ldr_literal = ptr[1]; + sljit_uw src2; + + src2 = get_immediate(new_constant); + if (src2) { + *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + src2 = get_immediate(~new_constant); + if (src2) { + *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + return; + } + + if (ldr_literal & (1 << 23)) + ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2; + else + ptr = inst + 1; + + if (*inst != ldr_literal) { + *inst = ldr_literal; + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 1); + } + } + *ptr = new_constant; +#else + sljit_uw *inst = (sljit_uw*)addr; + SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT); + inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff); + inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff); + if (flush) { + SLJIT_CACHE_FLUSH(inst, inst + 2); + } +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_uw *code; + sljit_uw *code_ptr; + sljit_uw *buf_ptr; + sljit_uw *buf_end; + sljit_uw size; + sljit_uw word_count; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + sljit_uw cpool_size; + sljit_uw cpool_skip_alignment; + sljit_uw cpool_current_index; + sljit_uw *cpool_start_address; + sljit_uw *last_pc_patch; + struct future_patch *first_patch; +#endif + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + check_sljit_generate_code(compiler); + reverse_buf(compiler); + + /* Second code generation pass. */ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + size = compiler->size + (compiler->patches << 1); + if (compiler->cpool_fill > 0) + size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; +#else + size = compiler->size; +#endif + code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + cpool_size = 0; + cpool_skip_alignment = 0; + cpool_current_index = 0; + cpool_start_address = NULL; + first_patch = NULL; + last_pc_patch = code; +#endif + + code_ptr = code; + word_count = 0; + + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + + if (label && label->size == 0) { + label->addr = (sljit_uw)code; + label->size = 0; + label = label->next; + } + + do { + buf_ptr = (sljit_uw*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + word_count++; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (cpool_size > 0) { + if (cpool_skip_alignment > 0) { + buf_ptr++; + cpool_skip_alignment--; + } + else { + if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { + SLJIT_FREE_EXEC(code); + compiler->error = SLJIT_ERR_ALLOC_FAILED; + return NULL; + } + buf_ptr++; + if (++cpool_current_index >= cpool_size) { + SLJIT_ASSERT(!first_patch); + cpool_size = 0; + if (label && label->size == word_count) { + /* Points after the current instruction. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + } + } + } + else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { +#endif + *code_ptr = *buf_ptr++; + /* These structures are ordered by their address. */ + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (detect_jump_type(jump, code_ptr, code)) + code_ptr--; + jump->addr = (sljit_uw)code_ptr; +#else + jump->addr = (sljit_uw)(code_ptr - 2); + if (detect_jump_type(jump, code_ptr, code)) + code_ptr -= 2; +#endif + jump = jump->next; + } + if (label && label->size == word_count) { + /* code_ptr can be affected above. */ + label->addr = (sljit_uw)(code_ptr + 1); + label->size = (code_ptr + 1) - code; + label = label->next; + } + if (const_ && const_->addr == word_count) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + const_->addr = (sljit_uw)code_ptr; +#else + const_->addr = (sljit_uw)(code_ptr - 1); +#endif + const_ = const_->next; + } + code_ptr++; +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + } + else { + /* Fortunately, no need to shift. */ + cpool_size = *buf_ptr++ & ~PUSH_POOL; + SLJIT_ASSERT(cpool_size > 0); + cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1); + cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); + if (cpool_current_index > 0) { + /* Unconditional branch. */ + *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); + code_ptr = cpool_start_address + cpool_current_index; + } + cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; + cpool_current_index = 0; + last_pc_patch = code_ptr; + } +#endif + } while (buf_ptr < buf_end); + buf = buf->next; + } while (buf); + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + SLJIT_ASSERT(cpool_size == 0); + if (compiler->cpool_fill > 0) { + cpool_start_address = ALIGN_INSTRUCTION(code_ptr); + cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); + if (cpool_current_index > 0) + code_ptr = cpool_start_address + cpool_current_index; + + buf_ptr = compiler->cpool; + buf_end = buf_ptr + compiler->cpool_fill; + cpool_current_index = 0; + while (buf_ptr < buf_end) { + if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) { + SLJIT_FREE_EXEC(code); + compiler->error = SLJIT_ERR_ALLOC_FAILED; + return NULL; + } + buf_ptr++; + cpool_current_index++; + } + SLJIT_ASSERT(!first_patch); + } +#endif + + jump = compiler->jumps; + while (jump) { + buf_ptr = (sljit_uw*)jump->addr; + + if (jump->flags & PATCH_B) { + if (!(jump->flags & JUMP_ADDR)) { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + else { + SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; + } + } + else if (jump->flags & SLJIT_REWRITABLE_JUMP) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + jump->addr = (sljit_uw)code_ptr; + code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[1] = *buf_ptr; + inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); + code_ptr += 2; +#else + inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); +#endif + } + else { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (jump->flags & IS_BL) + buf_ptr--; + if (*buf_ptr & (1 << 23)) + buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; + else + buf_ptr += 1; + *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; +#else + inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); +#endif + } + jump = jump->next; + } + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + const_ = compiler->consts; + while (const_) { + buf_ptr = (sljit_uw*)const_->addr; + const_->addr = (sljit_uw)code_ptr; + + code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[1] = *buf_ptr; + if (*buf_ptr & (1 << 23)) + buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; + else + buf_ptr += 1; + /* Set the value again (can be a simple constant). */ + inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0); + code_ptr += 2; + + const_ = const_->next; + } +#endif + + SLJIT_ASSERT(code_ptr - code <= (int)size); + + SLJIT_CACHE_FLUSH(code, code_ptr); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = size * sizeof(sljit_uw); + return code; +} + +/* emit_op inp_flags. + WRITE_BACK must be the first, since it is a flag. */ +#define WRITE_BACK 0x01 +#define ALLOW_IMM 0x02 +#define ALLOW_INV_IMM 0x04 +#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) +#define ARG_TEST 0x08 + +/* Creates an index in data_transfer_insts array. */ +#define WORD_DATA 0x00 +#define BYTE_DATA 0x10 +#define HALF_DATA 0x20 +#define SIGNED_DATA 0x40 +#define LOAD_DATA 0x80 + +#define EMIT_INSTRUCTION(inst) \ + FAIL_IF(push_inst(compiler, (inst))) + +/* Condition: AL. */ +#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ + (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) + +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size; + sljit_uw push; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + /* Push saved registers, temporary registers + stmdb sp!, {..., lr} */ + push = PUSH | (1 << 14); + if (temporaries >= 5) + push |= 1 << 11; + if (temporaries >= 4) + push |= 1 << 10; + if (saveds >= 5) + push |= 1 << 8; + if (saveds >= 4) + push |= 1 << 7; + if (saveds >= 3) + push |= 1 << 6; + if (saveds >= 2) + push |= 1 << 5; + if (saveds >= 1) + push |= 1 << 4; + EMIT_INSTRUCTION(push); + + /* Stack must be aligned to 8 bytes: */ + size = (1 + saveds) * sizeof(sljit_uw); + if (temporaries >= 4) + size += (temporaries - 3) * sizeof(sljit_uw); + local_size += size; + local_size = (local_size + 7) & ~7; + local_size -= size; + compiler->local_size = local_size; + if (local_size > 0) + FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); + + if (args >= 1) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); + if (args >= 2) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); + if (args >= 3) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + size = (1 + saveds) * sizeof(sljit_uw); + if (temporaries >= 4) + size += (temporaries - 3) * sizeof(sljit_uw); + local_size += size; + local_size = (local_size + 7) & ~7; + local_size -= size; + compiler->local_size = local_size; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + sljit_uw pop; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size > 0) + FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); + + pop = POP | (1 << 15); + /* Push saved registers, temporary registers + ldmia sp!, {..., pc} */ + if (compiler->temporaries >= 5) + pop |= 1 << 11; + if (compiler->temporaries >= 4) + pop |= 1 << 10; + if (compiler->saveds >= 5) + pop |= 1 << 8; + if (compiler->saveds >= 4) + pop |= 1 << 7; + if (compiler->saveds >= 3) + pop |= 1 << 6; + if (compiler->saveds >= 2) + pop |= 1 << 5; + if (compiler->saveds >= 1) + pop |= 1 << 4; + + return push_inst(compiler, pop); +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* s/l - store/load (1 bit) + u/s - signed/unsigned (1 bit) + w/b/h/N - word/byte/half/NOT allowed (2 bit) + It contans 16 items, but not all are different. */ + +static sljit_w data_transfer_insts[16] = { +/* s u w */ 0xe5000000 /* str */, +/* s u b */ 0xe5400000 /* strb */, +/* s u h */ 0xe10000b0 /* strh */, +/* s u N */ 0x00000000 /* not allowed */, +/* s s w */ 0xe5000000 /* str */, +/* s s b */ 0xe5400000 /* strb */, +/* s s h */ 0xe10000b0 /* strh */, +/* s s N */ 0x00000000 /* not allowed */, + +/* l u w */ 0xe5100000 /* ldr */, +/* l u b */ 0xe5500000 /* ldrb */, +/* l u h */ 0xe11000b0 /* ldrh */, +/* l u N */ 0x00000000 /* not allowed */, +/* l s w */ 0xe5100000 /* ldr */, +/* l s b */ 0xe11000d0 /* ldrsb */, +/* l s h */ 0xe11000f0 /* ldrsh */, +/* l s N */ 0x00000000 /* not allowed */, +}; + +#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \ + (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2)) +/* Normal ldr/str instruction. + Type2: ldrsb, ldrh, ldrsh */ +#define IS_TYPE1_TRANSFER(type) \ + (data_transfer_insts[(type) >> 4] & 0x04000000) +#define TYPE2_TRANSFER_IMM(imm) \ + (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) + +/* flags: */ + /* Arguments are swapped. */ +#define ARGS_SWAPPED 0x01 + /* Inverted immediate. */ +#define INV_IMM 0x02 + /* Source and destination is register. */ +#define REG_DEST 0x04 +#define REG_SOURCE 0x08 + /* One instruction is enough. */ +#define FAST_DEST 0x10 + /* Multiple instructions are required. */ +#define SLOW_DEST 0x20 +/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */ +#define SET_FLAGS (1 << 20) +/* dst: reg + src1: reg + src2: reg or imm (if allowed) + SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */ +#define SRC2_IMM (1 << 25) + +#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2))) + +#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2)) + +#define EMIT_SHIFT_INS_AND_RETURN(opcode) \ + SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \ + if (compiler->shift_imm != 0x20) { \ + SLJIT_ASSERT(src1 == TMP_REG1); \ + SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ + if (compiler->shift_imm != 0) \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \ + } \ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); + +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) +{ + sljit_w mul_inst; + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP); + + case SLJIT_ADDC: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP); + + case SLJIT_SUB: + SLJIT_ASSERT(!(flags & INV_IMM)); + if (!(flags & ARGS_SWAPPED)) + EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP); + + case SLJIT_SUBC: + SLJIT_ASSERT(!(flags & INV_IMM)); + if (!(flags & ARGS_SWAPPED)) + EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP); + + case SLJIT_MUL: + SLJIT_ASSERT(!(flags & INV_IMM)); + SLJIT_ASSERT(!(src2 & SRC2_IMM)); + if (SLJIT_UNLIKELY(op & SLJIT_SET_O)) + mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12); + else + mul_inst = MUL | (reg_map[dst] << 16); + + if (dst != src2) + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2])); + else if (dst != src1) + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1])); + else { + /* Rm and Rd must not be the same register. */ + SLJIT_ASSERT(dst != TMP_REG1); + FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2]))); + FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1])); + } + + if (!(op & SLJIT_SET_O)) + return SLJIT_SUCCESS; + + /* We need to use TMP_REG3. */ + compiler->cache_arg = 0; + compiler->cache_argw = 0; + /* cmp TMP_REG2, dst asr #31. */ + return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0)); + + case SLJIT_AND: + if (!(flags & INV_IMM)) + EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP); + EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP); + + case SLJIT_OR: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP); + + case SLJIT_XOR: + SLJIT_ASSERT(!(flags & INV_IMM)); + EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP); + + case SLJIT_SHL: + EMIT_SHIFT_INS_AND_RETURN(0); + + case SLJIT_LSHR: + EMIT_SHIFT_INS_AND_RETURN(1); + + case SLJIT_ASHR: + EMIT_SHIFT_INS_AND_RETURN(2); + + case SLJIT_MOV: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if (dst != src2) { + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (op == SLJIT_MOV_UB) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_NOT: + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(!(flags & INV_IMM)); + SLJIT_ASSERT(!(src2 & SRC2_IMM)); + FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); + if (flags & SET_FLAGS) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); + return SLJIT_SUCCESS; + } + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +#undef EMIT_DATA_PROCESS_INS_AND_RETURN +#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN +#undef EMIT_SHIFT_INS_AND_RETURN + +/* Tests whether the immediate can be stored in the 12 bit imm field. + Returns with 0 if not possible. */ +static sljit_uw get_immediate(sljit_uw imm) +{ + int rol; + + if (imm <= 0xff) + return SRC2_IMM | imm; + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol = 8; + } + else { + imm = (imm << 24) | (imm >> 8); + rol = 0; + } + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol += 4; + } + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + return SRC2_IMM | (imm >> 24) | (rol << 8); + else + return 0; +} + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive) +{ + sljit_uw mask; + sljit_uw imm1; + sljit_uw imm2; + int rol; + + /* Step1: Search a zero byte (8 continous zero bit). */ + mask = 0xff000000; + rol = 8; + while(1) { + if (!(imm & mask)) { + /* Rol imm by rol. */ + imm = (imm << rol) | (imm >> (32 - rol)); + /* Calculate arm rol. */ + rol = 4 + (rol >> 1); + break; + } + rol += 2; + mask >>= 2; + if (mask & 0x3) { + /* rol by 8. */ + imm = (imm << 8) | (imm >> 24); + mask = 0xff00; + rol = 24; + while (1) { + if (!(imm & mask)) { + /* Rol imm by rol. */ + imm = (imm << rol) | (imm >> (32 - rol)); + /* Calculate arm rol. */ + rol = (rol >> 1) - 8; + break; + } + rol += 2; + mask >>= 2; + if (mask & 0x3) + return 0; + } + break; + } + } + + /* The low 8 bit must be zero. */ + SLJIT_ASSERT(!(imm & 0xff)); + + if (!(imm & 0xff000000)) { + imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); + imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); + } + else if (imm & 0xc0000000) { + imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); + imm <<= 8; + rol += 4; + + if (!(imm & 0xff000000)) { + imm <<= 8; + rol += 4; + } + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + else + return 0; + } + else { + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); + imm <<= 8; + rol += 4; + + if (!(imm & 0xf0000000)) { + imm <<= 4; + rol += 2; + } + + if (!(imm & 0xc0000000)) { + imm <<= 2; + rol += 1; + } + + if (!(imm & 0x00ffffff)) + imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + else + return 0; + } + + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2)); + return 1; +} +#endif + +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm) +{ + sljit_uw tmp; + +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + if (!(imm & ~0xffff)) + return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); +#endif + + /* Create imm by 1 inst. */ + tmp = get_immediate(imm); + if (tmp) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); + return SLJIT_SUCCESS; + } + + tmp = get_immediate(~imm); + if (tmp) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp)); + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + /* Create imm by 2 inst. */ + FAIL_IF(generate_int(compiler, reg, imm, 1)); + FAIL_IF(generate_int(compiler, reg, ~imm, 0)); + + /* Load integer. */ + return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm); +#else + return emit_imm(compiler, reg, imm); +#endif +} + +/* Can perform an operation using at most 1 instruction. */ +static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) +{ + sljit_uw imm; + + if (arg & SLJIT_IMM) { + imm = get_immediate(argw); + if (imm) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)); + return -1; + } + imm = get_immediate(~argw); + if (imm) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm)); + return -1; + } + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; + } + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads/stores. */ + if (arg & 0xf) { + if (!(arg & 0xf0)) { + if (IS_TYPE1_TRANSFER(inp_flags)) { + if (argw >= 0 && argw <= 0xfff) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, argw)); + return -1; + } + if (argw < 0 && argw >= -0xfff) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, -argw)); + return -1; + } + } + else { + if (argw >= 0 && argw <= 0xff) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw))); + return -1; + } + if (argw < 0 && argw >= -0xff) { + if (inp_flags & ARG_TEST) + return 1; + argw = -argw; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw))); + return -1; + } + } + } + else if ((argw & 0x3) == 0 || IS_TYPE1_TRANSFER(inp_flags)) { + if (inp_flags & ARG_TEST) + return 1; + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, + RM((arg >> 4) & 0xf) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7))); + return -1; + } + } + + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + /* Immediate caching is not supported as it would be an operation on constant arguments. */ + if (arg & SLJIT_IMM) + return 0; + + /* Always a simple operation. */ + if (arg & 0xf0) + return 0; + + if (!(arg & 0xf)) { + /* Immediate access. */ + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) + return 1; + return 0; + } + + if (argw <= 0xfffff && argw >= -0xfffff) + return 0; + + if (argw == next_argw && (next_arg & SLJIT_MEM)) + return 1; + + if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff)) + return 1; + + return 0; +} + +#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \ + if (max_delta & 0xf00) \ + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \ + else \ + FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm)))); + +#define TEST_WRITE_BACK() \ + if (inp_flags & WRITE_BACK) { \ + tmp_r = arg & 0xf; \ + if (reg == tmp_r) { \ + /* This can only happen for stores */ \ + /* since ldr reg, [reg, ...]! has no meaning */ \ + SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \ + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg))); \ + reg = TMP_REG3; \ + } \ + } + +/* Emit the necessary instructions. See can_cache above. */ +static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + int tmp_r; + sljit_w max_delta; + sljit_w sign; + + if (arg & SLJIT_IMM) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + return load_immediate(compiler, reg, argw); + } + + SLJIT_ASSERT(arg & SLJIT_MEM); + + tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; + max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff; + + if ((arg & 0xf) == SLJIT_UNUSED) { + /* Write back is not used. */ + if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) { + if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { + sign = 1; + argw = argw - compiler->cache_argw; + } + else { + sign = 0; + argw = compiler->cache_argw - argw; + } + + if (max_delta & 0xf00) { + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw)); + } + else { + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw))); + } + return SLJIT_SUCCESS; + } + + /* With write back, we can create some sophisticated loads, but + it is hard to decide whether we should convert downward (0s) or upward (1s). */ + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0); + return SLJIT_SUCCESS; + } + + /* Extended imm addressing for [reg+imm] format. */ + sign = (max_delta << 8) | 0xff; + if (!(arg & 0xf0) && argw <= sign && argw >= -sign) { + TEST_WRITE_BACK(); + if (argw >= 0) { + sign = 1; + } + else { + sign = 0; + argw = -argw; + } + + /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */ + if (max_delta & 0xf00) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00)); + else + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00)); + + argw &= max_delta; + GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw); + return SLJIT_SUCCESS; + } + + if (arg & 0xf0) { + SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); + if (inp_flags & WRITE_BACK) + tmp_r = arg & 0xf; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0))); + return SLJIT_SUCCESS; + } + + if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + argw = argw - compiler->cache_argw; + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw); + return SLJIT_SUCCESS; + } + + if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + argw = compiler->cache_argw - argw; + GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw); + return SLJIT_SUCCESS; + } + + if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); + return SLJIT_SUCCESS; + } + + if (argw == next_argw && (next_arg & SLJIT_MEM)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + + TEST_WRITE_BACK(); + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0))); + return SLJIT_SUCCESS; + } + + if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf])); + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0); + return SLJIT_SUCCESS; + } + + if ((arg & 0xf) == tmp_r) { + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); + return SLJIT_SUCCESS; +} + +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + + /* We prefers register and simple consts. */ + int dst_r; + int src1_r; + int src2_r = 0; + int sugg_src2_r = TMP_REG2; + int flags = GET_FLAGS(op) ? SET_FLAGS : 0; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + /* Destination check. */ + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else if (dst == SLJIT_UNUSED) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else { + SLJIT_ASSERT(dst & SLJIT_MEM); + if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { + flags |= FAST_DEST; + dst_r = TMP_REG2; + } + else { + flags |= SLOW_DEST; + dst_r = 0; + } + } + + /* Source 1. */ + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) + src1_r = src1; + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + flags |= ARGS_SWAPPED; + src1_r = src2; + src2 = src1; + src2w = src1w; + } + else do { /* do { } while(0) is used because of breaks. */ + src1_r = 0; + if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { + /* The second check will generate a hit. */ + src2_r = get_immediate(src1w); + if (src2_r) { + flags |= ARGS_SWAPPED; + src1 = src2; + src1w = src2w; + break; + } + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_immediate(~src1w); + if (src2_r) { + flags |= ARGS_SWAPPED | INV_IMM; + src1 = src2; + src1w = src2w; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_immediate(-src1w); + if (src2_r) { + /* Note: ARGS_SWAPPED is intentionally not applied! */ + src1 = src2; + src1w = src2w; + op = SLJIT_SUB | GET_ALL_FLAGS(op); + break; + } + } + } + + if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1_r = TMP_REG1; + } + } while (0); + + /* Source 2. */ + if (src2_r == 0) { + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + src2_r = src2; + flags |= REG_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else do { /* do { } while(0) is used because of breaks. */ + if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) { + src2_r = get_immediate(src2w); + if (src2_r) + break; + if (inp_flags & ALLOW_INV_IMM) { + src2_r = get_immediate(~src2w); + if (src2_r) { + flags |= INV_IMM; + break; + } + } + if (GET_OPCODE(op) == SLJIT_ADD) { + src2_r = get_immediate(-src2w); + if (src2_r) { + op = SLJIT_SUB | GET_ALL_FLAGS(op); + flags &= ~ARGS_SWAPPED; + break; + } + } + if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { + src2_r = get_immediate(-src2w); + if (src2_r) { + op = SLJIT_ADD | GET_ALL_FLAGS(op); + flags &= ~ARGS_SWAPPED; + break; + } + } + } + + /* src2_r is 0. */ + if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { + FAIL_IF(compiler->error); + src2_r = sugg_src2_r; + } + } while (0); + } + + /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero. + If they are zero, they must not be registers. */ + if (src1_r == 0 && src2_r == 0 && dst_r == 0) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); + flags |= ARGS_SWAPPED; + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + src1_r = TMP_REG1; + src2_r = TMP_REG2; + } + else if (src1_r == 0 && src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + src1_r = TMP_REG1; + } + else if (src1_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + src1_r = TMP_REG1; + } + else if (src2_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + src2_r = sugg_src2_r; + } + + if (dst_r == 0) + dst_r = TMP_REG2; + + if (src1_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + src1_r = TMP_REG1; + } + + if (src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); + src2_r = sugg_src2_r; + } + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (flags & (FAST_DEST | SLOW_DEST)) { + if (flags & FAST_DEST) + FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); + else + FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); + } + return SLJIT_SUCCESS; +} + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); +extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); +#else +#error "Software divmod functions are needed" +#endif + +#ifdef __cplusplus +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + EMIT_INSTRUCTION(BKPT); + break; + case SLJIT_NOP: + EMIT_INSTRUCTION(NOP); + break; + case SLJIT_UMUL: + case SLJIT_SMUL: +#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) + return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_TEMPORARY_REG2] << 16) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 8) + | reg_map[SLJIT_TEMPORARY_REG2]); +#else + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) + | (reg_map[SLJIT_TEMPORARY_REG2] << 16) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 8) + | reg_map[TMP_REG1]); +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: + if (compiler->temporaries >= 3) + EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */); +#if defined(__GNUC__) + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, + (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); +#else +#error "Software divmod functions are needed" +#endif + if (compiler->temporaries >= 3) + return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); + return SLJIT_SUCCESS; + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_MOVU: + case SLJIT_MOVU_UI: + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + CHECK_ERROR(); + check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + case SLJIT_SUB: + case SLJIT_SUBC: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: + if (src2 & SLJIT_IMM) { + compiler->shift_imm = src2w & 0x1f; + return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); + } + else { + compiler->shift_imm = 0x20; + return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); + } + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size == 4); + + return push_inst(compiler, *(sljit_uw*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + +/* 0 - no fpu + 1 - vfp */ +static int arm_fpu_type = -1; + +static void init_compiler() +{ + if (arm_fpu_type != -1) + return; + + /* TODO: Only the OS can help to determine the correct fpu type. */ + arm_fpu_type = 1; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ + if (arm_fpu_type == -1) + init_compiler(); + return arm_fpu_type; +} + +#else + +#define arm_fpu_type 1 + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +#endif + +#define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \ + (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs)) +#define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \ + ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16)) + +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) { + if (argw >= 0 && argw <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; + } + if (argw < 0 && argw >= -0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2)); + return SLJIT_SUCCESS; + } + if (argw >= 0 && argw <= 0x3ffff) { + SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); + argw &= 0x3ff; + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; + } + if (argw < 0 && argw >= -0x3ffff) { + argw = -argw; + SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); + argw &= 0x3ff; + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; + } + } + + if (arg & 0xf0) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0)); + return SLJIT_SUCCESS; + } + + if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) { + if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2)); + return SLJIT_SUCCESS; + } + if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2)); + return SLJIT_SUCCESS; + } + } + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + if (arg & 0xf) { + FAIL_IF(load_immediate(compiler, TMP_REG1, argw)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & 0xf, reg_map[TMP_REG1])); + } + else + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_freg; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); + dst = TMP_FREG1; + } + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); + src = TMP_FREG2; + } + EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src); + EMIT_INSTRUCTION(VMRS); + return SLJIT_SUCCESS; + } + + dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_freg, 1, src, srcw)); + src = dst_freg; + } + + switch (op) { + case SLJIT_FMOV: + if (src != dst_freg && dst_freg != TMP_FREG1) + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_freg, src, 0)); + break; + case SLJIT_FNEG: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_freg, src, 0)); + break; + case SLJIT_FABS: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_freg, src, 0)); + break; + } + + if (dst_freg == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_freg; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (op) { + case SLJIT_FADD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_freg, src2, src1)); + break; + + case SLJIT_FSUB: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_freg, src2, src1)); + break; + + case SLJIT_FMUL: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_freg, src2, src1)); + break; + + case SLJIT_FDIV: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_freg, src2, src1)); + break; + } + + if (dst_freg == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); + else if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); + else if (src & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) + FAIL_IF(compiler->error); + else { + compiler->cache_arg = 0; + compiler->cache_argw = 0; + FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2))); + } + } + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG3, srcw)); + return push_inst(compiler, BLX | RM(TMP_REG3)); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +static sljit_uw get_cc(int type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_MUL_NOT_OVERFLOW: + case SLJIT_C_FLOAT_EQUAL: + return 0x00000000; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_MUL_OVERFLOW: + case SLJIT_C_FLOAT_NOT_EQUAL: + return 0x10000000; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return 0x30000000; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return 0x20000000; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return 0x80000000; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return 0x90000000; + + case SLJIT_C_SIG_LESS: + return 0xb0000000; + + case SLJIT_C_SIG_GREATER_EQUAL: + return 0xa0000000; + + case SLJIT_C_SIG_GREATER: + return 0xc0000000; + + case SLJIT_C_SIG_LESS_EQUAL: + return 0xd0000000; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_FLOAT_NAN: + return 0x60000000; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_FLOAT_NOT_NAN: + return 0x70000000; + + default: /* SLJIT_JUMP */ + return 0xe0000000; + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + check_sljit_emit_label(compiler); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + check_sljit_emit_jump(compiler, type); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In ARM, we don't need to touch the arguments. */ +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (type >= SLJIT_FAST_CALL) + PTR_FAIL_IF(prepare_blx(compiler)); + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, + type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0)); + + if (jump->flags & SLJIT_REWRITABLE_JUMP) { + jump->addr = compiler->size; + compiler->patches++; + } + + if (type >= SLJIT_FAST_CALL) { + jump->flags |= IS_BL; + PTR_FAIL_IF(emit_blx(compiler)); + } + + if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) + jump->addr = compiler->size; +#else + if (type >= SLJIT_FAST_CALL) + jump->flags |= IS_BL; + PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); + PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type))); + jump->addr = compiler->size; +#endif + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + struct sljit_jump *jump; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + /* In ARM, we don't need to touch the arguments. */ + if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); + jump->u.target = srcw; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (type >= SLJIT_FAST_CALL) + FAIL_IF(prepare_blx(compiler)); + FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); + if (type >= SLJIT_FAST_CALL) + FAIL_IF(emit_blx(compiler)); +#else + FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); + FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); +#endif + jump->addr = compiler->size; + } + else { + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); + + SLJIT_ASSERT(src & SLJIT_MEM); + FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + int reg; + sljit_uw cc; + + CHECK_ERROR(); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + cc = get_cc(type); + if (GET_OPCODE(op) == SLJIT_OR) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ORR_DP, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); + if (op & SLJIT_SET_E) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))); + return SLJIT_SUCCESS; + } + + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw); + } + + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); + + if (reg == TMP_REG2) + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + struct sljit_const *const_; + int reg; + + CHECK_ERROR_PTR(); + check_sljit_emit_const(compiler, dst, dstw, init_value); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); + compiler->patches++; +#else + PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); +#endif + set_const(const_, compiler); + + if (reg == TMP_REG2 && dst != SLJIT_UNUSED) + if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)) + return NULL; + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + inline_set_jump_addr(addr, new_addr, 1); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + inline_set_const(addr, new_constant, 1); +} diff -Nru pcre3-8.12/sljit/sljitNativeMIPS_32.c pcre3-8.31/sljit/sljitNativeMIPS_32.c --- pcre3-8.12/sljit/sljitNativeMIPS_32.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeMIPS_32.c 2011-12-28 16:57:57.000000000 +0000 @@ -0,0 +1,405 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* mips 32-bit arch dependent functions. */ + +static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm) +{ + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + if (imm < 0 && imm >= SIMM_MIN) + return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); + + FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar)); + return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS; +} + +#define EMIT_LOGICAL(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \ + } \ + else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \ + } + +#define EMIT_SHIFT(op_imm, op_norm) \ + if (flags & SRC2_IMM) { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ + } \ + else { \ + if (op & SLJIT_SET_E) \ + FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ + if (CHECK_FLAGS(SLJIT_SET_E)) \ + FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \ + } + +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, sljit_w src2) +{ + int overflow_ra = 0; + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); + if (src2 < 0) + FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + else { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + } + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + if (src2 < 0) + FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG)); + } + } + else { + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); + FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); + if (src1 != dst) + overflow_ra = DR(src1); + else if (src2 != dst) + overflow_ra = DR(src2); + else { + /* Rare ocasion. */ + FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); + overflow_ra = TMP_EREG2; + } + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + } + } + + /* a + b >= a | b (otherwise, the carry should be set to 1). */ + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG)); + if (op & SLJIT_SET_O) + return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); + return SLJIT_SUCCESS; + + case SLJIT_ADDC: + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) { + if (src2 >= 0) + FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); + else { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1)); + FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); + } + } + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst))); + } else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst))); + } + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1)); + + FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + if (!(op & SLJIT_SET_C)) + return SLJIT_SUCCESS; + + /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */ + FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2)); + FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2)); + /* Set carry flag. */ + return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG); + + case SLJIT_SUB: + if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); + if (src2 < 0) + FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1)); + if (src1 != dst) + overflow_ra = DR(src1); + else { + /* Rare ocasion. */ + FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); + overflow_ra = TMP_EREG2; + } + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG)); + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG)); + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); + FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1)); + if (src1 != dst) + overflow_ra = DR(src1); + else { + /* Rare ocasion. */ + FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2)); + overflow_ra = TMP_EREG2; + } + } + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (op & (SLJIT_SET_U | SLJIT_SET_C)) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG)); + if (op & SLJIT_SET_U) + FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG)); + if (op & SLJIT_SET_S) { + FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG)); + FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG)); + } + /* dst may be the same as src1 or src2. */ + if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C)) + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (op & SLJIT_SET_O) { + FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG)); + return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); + } + return SLJIT_SUCCESS; + + case SLJIT_SUBC: + if ((flags & SRC2_IMM) && src2 == SIMM_MIN) { + FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2))); + src2 = TMP_REG2; + flags &= ~SRC2_IMM; + } + + if (flags & SRC2_IMM) { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst))); + } + else { + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1)); + /* dst may be the same as src1 or src2. */ + FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst))); + } + + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1)); + + FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst))); + + if (op & SLJIT_SET_C) + FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG)); + + return SLJIT_SUCCESS; + + case SLJIT_MUL: + SLJIT_ASSERT(!(flags & SRC2_IMM)); + if (!(op & SLJIT_SET_O)) { +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); + return push_inst(compiler, MFLO | D(dst), DR(dst)); +#endif + } + FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1)); + FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2)); + return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG); + + case SLJIT_AND: + EMIT_LOGICAL(ANDI, AND); + return SLJIT_SUCCESS; + + case SLJIT_OR: + EMIT_LOGICAL(ORI, OR); + return SLJIT_SUCCESS; + + case SLJIT_XOR: + EMIT_LOGICAL(XORI, XOR); + return SLJIT_SUCCESS; + + case SLJIT_SHL: + EMIT_SHIFT(SLL, SLLV); + return SLJIT_SUCCESS; + + case SLJIT_LSHR: + EMIT_SHIFT(SRL, SRLV); + return SLJIT_SUCCESS; + + case SLJIT_ASHR: + EMIT_SHIFT(SRA, SRAV); + return SLJIT_SUCCESS; + + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) { +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) { +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); +#else + if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { + FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); + return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); + } + /* Nearly all instructions are unmovable in the following sequence. */ + FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + /* Check zero. */ + FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); + /* Check sign bit. */ + FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS)); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS)); + if (op & SLJIT_SET_E) + return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); +#endif + return SLJIT_SUCCESS; + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) +{ + FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg))); + return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff -Nru pcre3-8.12/sljit/sljitNativeMIPS_common.c pcre3-8.31/sljit/sljitNativeMIPS_common.c --- pcre3-8.12/sljit/sljitNativeMIPS_common.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeMIPS_common.c 2012-04-03 15:33:31.000000000 +0000 @@ -0,0 +1,1831 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ + return "MIPS" SLJIT_CPUINFO; +} + +/* Latest MIPS architecture. */ +/* Detect SLJIT_MIPS_32_64 */ + +/* Length of an instruction word + Both for mips-32 and mips-64 */ +typedef sljit_ui sljit_ins; + +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) + +/* For position independent code, t9 must contain the function address. */ +#define PIC_ADDR_REG TMP_REG2 + +/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ +#define TMP_EREG1 15 +#define TMP_EREG2 24 +/* Floating point status register. */ +#define FCSR_REG 31 +/* Return address register. */ +#define RETURN_ADDR_REG 31 + +/* Flags are keept in volatile registers. */ +#define EQUAL_FLAG 7 +/* And carry flag as well. */ +#define ULESS_FLAG 10 +#define UGREATER_FLAG 11 +#define LESS_FLAG 12 +#define GREATER_FLAG 13 +#define OVERFLOW_FLAG 14 + +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ + +#define S(s) (reg_map[s] << 21) +#define T(t) (reg_map[t] << 16) +#define D(d) (reg_map[d] << 11) +/* Absolute registers. */ +#define SA(s) ((s) << 21) +#define TA(t) ((t) << 16) +#define DA(d) ((d) << 11) +#define FT(t) ((t) << (16 + 1)) +#define FS(s) ((s) << (11 + 1)) +#define FD(d) ((d) << (6 + 1)) +#define IMM(imm) ((imm) & 0xffff) +#define SH_IMM(imm) ((imm & 0x1f) << 6) + +#define DR(dr) (reg_map[dr]) +#define HI(opcode) ((opcode) << 26) +#define LO(opcode) (opcode) +#define FMT_D (17 << 21) + +#define ABS_D (HI(17) | FMT_D | LO(5)) +#define ADD_D (HI(17) | FMT_D | LO(0)) +#define ADDU (HI(0) | LO(33)) +#define ADDIU (HI(9)) +#define AND (HI(0) | LO(36)) +#define ANDI (HI(12)) +#define B (HI(4)) +#define BAL (HI(1) | (17 << 16)) +#define BC1F (HI(17) | (8 << 21)) +#define BC1T (HI(17) | (8 << 21) | (1 << 16)) +#define BEQ (HI(4)) +#define BGEZ (HI(1) | (1 << 16)) +#define BGTZ (HI(7)) +#define BLEZ (HI(6)) +#define BLTZ (HI(1) | (0 << 16)) +#define BNE (HI(5)) +#define BREAK (HI(0) | LO(13)) +#define C_UN_D (HI(17) | FMT_D | LO(49)) +#define C_UEQ_D (HI(17) | FMT_D | LO(51)) +#define C_ULE_D (HI(17) | FMT_D | LO(55)) +#define C_ULT_D (HI(17) | FMT_D | LO(53)) +#define DIV (HI(0) | LO(26)) +#define DIVU (HI(0) | LO(27)) +#define DIV_D (HI(17) | FMT_D | LO(3)) +#define J (HI(2)) +#define JAL (HI(3)) +#define JALR (HI(0) | LO(9)) +#define JR (HI(0) | LO(8)) +#define LD (HI(55)) +#define LDC1 (HI(53)) +#define LUI (HI(15)) +#define LW (HI(35)) +#define NEG_D (HI(17) | FMT_D | LO(7)) +#define MFHI (HI(0) | LO(16)) +#define MFLO (HI(0) | LO(18)) +#define MOV_D (HI(17) | FMT_D | LO(6)) +#define CFC1 (HI(17) | (2 << 21)) +#define MOVN (HI(0) | LO(11)) +#define MOVZ (HI(0) | LO(10)) +#define MUL_D (HI(17) | FMT_D | LO(2)) +#define MULT (HI(0) | LO(24)) +#define MULTU (HI(0) | LO(25)) +#define NOP (HI(0) | LO(0)) +#define NOR (HI(0) | LO(39)) +#define OR (HI(0) | LO(37)) +#define ORI (HI(13)) +#define SD (HI(63)) +#define SDC1 (HI(61)) +#define SLT (HI(0) | LO(42)) +#define SLTI (HI(10)) +#define SLTIU (HI(11)) +#define SLTU (HI(0) | LO(43)) +#define SLL (HI(0) | LO(0)) +#define SLLV (HI(0) | LO(4)) +#define SRL (HI(0) | LO(2)) +#define SRLV (HI(0) | LO(6)) +#define SRA (HI(0) | LO(3)) +#define SRAV (HI(0) | LO(7)) +#define SUB_D (HI(17) | FMT_D | LO(1)) +#define SUBU (HI(0) | LO(35)) +#define SW (HI(43)) +#define XOR (HI(0) | LO(38)) +#define XORI (HI(14)) + +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) +#define CLZ (HI(28) | LO(32)) +#define MUL (HI(28) | LO(2)) +#define SEB (HI(31) | (16 << 6) | LO(32)) +#define SEH (HI(31) | (24 << 6) | LO(32)) +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define ADDU_W ADDU +#define ADDIU_W ADDIU +#define SLL_W SLL +#define SUBU_W SUBU +#else +#define ADDU_W DADDU +#define ADDIU_W DADDIU +#define SLL_W DSLL +#define SUBU_W DSUBU +#endif + +#define SIMM_MAX (0x7fff) +#define SIMM_MIN (-0x8000) +#define UIMM_MAX (0xffff) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { + 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 +}; + +/* dest_reg is the absolute name of the register + Useful for reordering instructions in the delay slot. */ +static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot) +{ + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + compiler->delay_slot = delay_slot; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_ins invert_branch(int flags) +{ + return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); +} + +static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_w diff; + sljit_uw target_addr; + sljit_ins *inst; + sljit_ins saved_inst; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return code_ptr; + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + inst = (sljit_ins*)jump->addr; + if (jump->flags & IS_COND) + inst--; + + /* B instructions. */ + if (jump->flags & IS_MOVABLE) { + diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2; + if (diff <= SIMM_MAX && diff >= SIMM_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + inst[0] = inst[-1]; + inst[-1] = (jump->flags & IS_JAL) ? BAL : B; + jump->addr -= sizeof(sljit_ins); + return inst; + } + saved_inst = inst[0]; + inst[0] = inst[-1]; + inst[-1] = saved_inst ^ invert_branch(jump->flags); + jump->addr -= 2 * sizeof(sljit_ins); + return inst; + } + } + + diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2; + if (diff <= SIMM_MAX && diff >= SIMM_MIN) { + jump->flags |= PATCH_B; + + if (!(jump->flags & IS_COND)) { + inst[0] = (jump->flags & IS_JAL) ? BAL : B; + inst[1] = NOP; + return inst + 1; + } + inst[0] = inst[0] ^ invert_branch(jump->flags); + inst[1] = NOP; + jump->addr -= sizeof(sljit_ins); + return inst + 1; + } + + if (jump->flags & IS_COND) { + if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = (inst[0] & 0xffff0000) | 3; + inst[1] = NOP; + inst[2] = J; + inst[3] = NOP; + jump->addr += sizeof(sljit_ins); + return inst + 3; + } + return code_ptr; + } + + /* J instuctions. */ + if (jump->flags & IS_MOVABLE) { + if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = inst[-1]; + inst[-1] = (jump->flags & IS_JAL) ? JAL : J; + jump->addr -= sizeof(sljit_ins); + return inst; + } + } + + if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) { + jump->flags |= PATCH_J; + inst[0] = (jump->flags & IS_JAL) ? JAL : J; + inst[1] = NOP; + return inst + 1; + } + + return code_ptr; +} + +#ifdef __GNUC__ +static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr) +{ + SLJIT_CACHE_FLUSH(code, code_ptr); +} +#endif + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + check_sljit_generate_code(compiler); + reverse_buf(compiler); + + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + jump->addr = (sljit_uw)(code_ptr - 3); +#else + jump->addr = (sljit_uw)(code_ptr - 6); +#endif + code_ptr = optimize_jump(jump, code_ptr, code); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + + if (jump->flags & PATCH_B) { + addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; + SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN); + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); + break; + } + if (jump->flags & PATCH_J) { + SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)); + buf_ptr[0] |= (addr >> 2) & 0x03ffffff; + break; + } + + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); +#else + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); +#endif + } while (0); + jump = jump->next; + } + + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = compiler->size * sizeof(sljit_ins); +#ifndef __GNUC__ + SLJIT_CACHE_FLUSH(code, code_ptr); +#else + /* GCC workaround for invalid code generation with -O2. */ + sljit_cache_flush(code, code_ptr); +#endif + return code; +} + +/* Creates an index in data_transfer_insts array. */ +#define WORD_DATA 0x00 +#define BYTE_DATA 0x01 +#define HALF_DATA 0x02 +#define INT_DATA 0x03 +#define SIGNED_DATA 0x04 +#define LOAD_DATA 0x08 + +#define MEM_MASK 0x0f + +#define WRITE_BACK 0x00010 +#define ARG_TEST 0x00020 +#define CUMULATIVE_OP 0x00040 +#define LOGICAL_OP 0x00080 +#define IMM_OP 0x00100 +#define SRC2_IMM 0x00200 + +#define UNUSED_DEST 0x00400 +#define REG_DEST 0x00800 +#define REG1_SOURCE 0x01000 +#define REG2_SOURCE 0x02000 +#define SLOW_SRC1 0x04000 +#define SLOW_SRC2 0x08000 +#define SLOW_DEST 0x10000 + +/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ +#define CHECK_FLAGS(list) \ + (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#include "sljitNativeMIPS_32.c" +#else +#include "sljitNativeMIPS_64.c" +#endif + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define STACK_STORE SW +#define STACK_LOAD LW +#else +#define STACK_STORE SD +#define STACK_LOAD LD +#endif + +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + sljit_ins base; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1 + 4) * sizeof(sljit_w); + local_size = (local_size + 15) & ~0xf; + compiler->local_size = local_size; + + if (local_size <= SIMM_MAX) { + /* Frequent case. */ + FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(-local_size), DR(SLJIT_LOCALS_REG))); + base = S(SLJIT_LOCALS_REG); + } + else { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(SLJIT_LOCALS_REG), DR(SLJIT_LOCALS_REG))); + base = S(TMP_REG2); + local_size = 0; + } + + FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); + if (saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); + if (saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS)); + if (saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS)); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS)); + if (saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS)); + + if (args >= 1) + FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1))); + if (args >= 2) + FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2))); + if (args >= 3) + FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_REG3))); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + local_size += (saveds + 1 + 4) * sizeof(sljit_w); + compiler->local_size = (local_size + 15) & ~0xf; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + int local_size; + sljit_ins base; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + local_size = compiler->local_size; + if (local_size <= SIMM_MAX) + base = S(SLJIT_LOCALS_REG); + else { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_LOCALS_REG) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1))); + base = S(TMP_REG1); + local_size = 0; + } + + FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG)); + if (compiler->saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2))); + if (compiler->saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1))); + if (compiler->saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3))); + if (compiler->saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2))); + if (compiler->saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1))); + + FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); + if (compiler->local_size <= SIMM_MAX) + return push_inst(compiler, ADDIU_W | S(SLJIT_LOCALS_REG) | T(SLJIT_LOCALS_REG) | IMM(compiler->local_size), UNMOVABLE_INS); + else + return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_LOCALS_REG), UNMOVABLE_INS); +} + +#undef STACK_STORE +#undef STACK_LOAD + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define ARCH_DEPEND(a, b) a +#else +#define ARCH_DEPEND(a, b) b +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[16] = { +/* s u w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), +/* s u b */ HI(40) /* sb */, +/* s u h */ HI(41) /* sh*/, +/* s u i */ HI(43) /* sw */, + +/* s s w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), +/* s s b */ HI(40) /* sb */, +/* s s h */ HI(41) /* sh*/, +/* s s i */ HI(43) /* sw */, + +/* l u w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), +/* l u b */ HI(36) /* lbu */, +/* l u h */ HI(37) /* lhu */, +/* l u i */ ARCH_DEPEND(HI(35) /* lw */, HI(39) /* lwu */), + +/* l s w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), +/* l s b */ HI(32) /* lb */, +/* l s h */ HI(33) /* lh */, +/* l s i */ HI(35) /* lw */, +}; + +/* reg_ar is an absoulute register! */ + +/* Can perform an operation using at most 1 instruction. */ +static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { + /* Works for both absoulte and relative addresses. */ + if (SLJIT_UNLIKELY(flags & ARG_TEST)) + return 1; + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) | TA(reg_ar) | IMM(argw), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS)); + return -1; + } + return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those + operators always uses word arguments without write back. */ +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + if (!(next_arg & SLJIT_MEM)) + return 0; + + /* Simple operation except for updates. */ + if (arg & 0xf0) { + argw &= 0x3; + next_argw &= 0x3; + if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0))) + return 1; + return 0; + } + + if (arg == next_arg) { + if (((sljit_uw)(next_argw - argw) <= SIMM_MAX && (sljit_uw)(next_argw - argw) >= SIMM_MIN)) + return 1; + return 0; + } + + return 0; +} + +/* Emit the necessary instructions. See can_cache above. */ +static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + int tmp_ar; + int base; + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(next_arg & SLJIT_MEM)) { + next_arg = 0; + next_argw = 0; + } + + tmp_ar = (flags & LOAD_DATA) ? reg_ar : DR(TMP_REG3); + base = arg & 0xf; + + if (SLJIT_UNLIKELY(arg & 0xf0)) { + argw &= 0x3; + if ((flags & WRITE_BACK) && reg_ar == DR(base)) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); + FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + reg_ar = DR(TMP_REG1); + } + + /* Using the cache. */ + if (argw == compiler->cache_argw) { + if (!(flags & WRITE_BACK)) { + if (arg == compiler->cache_arg) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + } + else { + if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + } + } + + if (SLJIT_UNLIKELY(argw)) { + compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3))); + } + + if (!(flags & WRITE_BACK)) { + if (arg == next_arg && argw == (next_argw & 0x3)) { + compiler->cache_arg = arg; + compiler->cache_argw = argw; + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); + tmp_ar = DR(TMP_REG3); + } + else + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + + if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { + /* Update only applies if a base register exists. */ + if (reg_ar == DR(base)) { + SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar); + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS)); + if (argw) + return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)); + return SLJIT_SUCCESS; + } + FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + reg_ar = DR(TMP_REG1); + } + + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (argw) + FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base))); + } + else { + if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + } + else { + compiler->cache_arg = SLJIT_MEM; + compiler->cache_argw = argw; + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base))); + } + } + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) { + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + compiler->cache_argw = argw; + } + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + + if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { + if (argw != compiler->cache_argw) + FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3))); + } + else { + compiler->cache_arg = SLJIT_MEM; + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + } + compiler->cache_argw = argw; + + if (!base) + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + + if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { + compiler->cache_arg = arg; + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); + } + + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); +} + +static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) +{ + if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) + return compiler->error; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); +} + +static int emit_op(struct sljit_compiler *compiler, int op, int flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + int dst_r = TMP_REG2; + int src1_r; + sljit_w src2_r = 0; + int sugg_src2_r = TMP_REG2; + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { + dst_r = dst; + flags |= REG_DEST; + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else if (dst == SLJIT_UNUSED) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + if (GET_FLAGS(op)) + flags |= UNUSED_DEST; + } + else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) + flags |= SLOW_DEST; + + if (flags & IMM_OP) { + if ((src2 & SLJIT_IMM) && src2w) { + if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN)) + || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) { + flags |= SRC2_IMM; + src2_r = src2w; + } + } + if ((src1 & SLJIT_IMM) && src1w && (flags & CUMULATIVE_OP) && !(flags & SRC2_IMM)) { + if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) + || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { + flags |= SRC2_IMM; + src2_r = src1w; + + /* And swap arguments. */ + src1 = src2; + src1w = src2w; + src2 = SLJIT_IMM; + /* src2w = src2_r unneeded. */ + } + } + } + + /* Source 1. */ + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) { + src1_r = src1; + flags |= REG1_SOURCE; + } + else if (src1 & SLJIT_IMM) { + if (src1w) { + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); + src1_r = TMP_REG1; + } + else + src1_r = 0; + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC1; + src1_r = TMP_REG1; + } + + /* Source 2. */ + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else if (src2 & SLJIT_IMM) { + if (!(flags & SRC2_IMM)) { + if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { + FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); + src2_r = sugg_src2_r; + } + else + src2_r = 0; + } + } + else { + if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w)) + FAIL_IF(compiler->error); + else + flags |= SLOW_SRC2; + src2_r = sugg_src2_r; + } + + if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) { + SLJIT_ASSERT(src2_r == TMP_REG2); + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw)); + } + } + else if (flags & SLOW_SRC1) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw)); + else if (flags & SLOW_SRC2) + FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw)); + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (dst & SLJIT_MEM) { + if (!(flags & SLOW_DEST)) { + getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw); + return compiler->error; + } + return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + op = GET_OPCODE(op); + switch (op) { + case SLJIT_BREAKPOINT: + return push_inst(compiler, BREAK, UNMOVABLE_INS); + case SLJIT_NOP: + return push_inst(compiler, NOP, UNMOVABLE_INS); + case SLJIT_UMUL: + case SLJIT_SMUL: + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); + case SLJIT_UDIV: + case SLJIT_SDIV: +#if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #define inp_flags 0 +#endif + + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_MOVU: + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), inp_flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + + case SLJIT_CLZ: + return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); + } + + return SLJIT_SUCCESS; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #undef inp_flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #define inp_flags 0 +#endif + + CHECK_ERROR(); + check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + case SLJIT_ADDC: + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + case SLJIT_SUBC: + return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (src2 & SLJIT_IMM) + src2w &= 0x1f; +#else + if (src2 & SLJIT_IMM) + src2w &= 0x3f; +#endif + return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + #undef inp_flags +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size == 4); + + return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ +#if (defined SLJIT_QEMU && SLJIT_QEMU) + /* Qemu says fir is 0 by default. */ + return 1; +#elif defined(__GNUC__) + sljit_w fir; + asm ("cfc1 %0, $0" : "=r"(fir)); + return (fir >> 22) & 0x1; +#else +#error "FIR check is not implemented for this architecture" +#endif +} + +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) +{ + int hi_reg; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (!(arg & 0xf0)) { + /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ + if (argw <= SIMM_MAX && argw >= SIMM_MIN) + return push_inst(compiler, (load ? LDC1 : SDC1) | S(arg & 0xf) | FT(fpu_reg) | IMM(argw), MOVABLE_INS); + } + + if (arg & 0xf0) { + argw &= 0x3; + hi_reg = (arg >> 4) & 0xf; + if (argw) { + FAIL_IF(push_inst(compiler, SLL_W | T(hi_reg) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1))); + hi_reg = TMP_REG1; + } + FAIL_IF(push_inst(compiler, ADDU_W | S(hi_reg) | T(arg & 0xf) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG1) | FT(fpu_reg) | IMM(0), MOVABLE_INS); + } + + /* Use cache. */ + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(argw - compiler->cache_argw), MOVABLE_INS); + + /* Put value to cache. */ + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + if (arg & 0xf) + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(arg & 0xf) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(0), MOVABLE_INS); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); + dst = TMP_FREG1; + } + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); + src = TMP_FREG2; + } + + /* src and dst are swapped. */ + if (op & SLJIT_SET_E) { + FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); + } + if (op & SLJIT_SET_S) { + /* Mixing the instructions for the two checks. */ + FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); + FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); + FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); + FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); + } + return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC); + } + + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); + src = dst_fr; + } + + switch (op) { + case SLJIT_FMOV: + if (src != dst_fr && dst_fr != TMP_FREG1) + FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + case SLJIT_FNEG: + FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + case SLJIT_FABS: + FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (op) { + case SLJIT_FADD: + FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_FSUB: + FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_FMUL: + FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + + case SLJIT_FDIV: + FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); + else if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); + else if (src & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw)); + + FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); + return push_inst(compiler, NOP, UNMOVABLE_INS); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + check_sljit_emit_label(compiler); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + compiler->delay_slot = UNMOVABLE_INS; + return label; +} + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define JUMP_LENGTH 4 +#else +#define JUMP_LENGTH 7 +#endif + +#define BR_Z(src) \ + inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \ + flags = IS_BIT26_COND; \ + delay_check = src; + +#define BR_NZ(src) \ + inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \ + flags = IS_BIT26_COND; \ + delay_check = src; + +#define BR_T() \ + inst = BC1T | JUMP_LENGTH; \ + flags = IS_BIT16_COND; \ + delay_check = FCSR_FCC; + +#define BR_F() \ + inst = BC1F | JUMP_LENGTH; \ + flags = IS_BIT16_COND; \ + delay_check = FCSR_FCC; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + struct sljit_jump *jump; + sljit_ins inst; + int flags = 0; + int delay_check = UNMOVABLE_INS; + + CHECK_ERROR_PTR(); + check_sljit_emit_jump(compiler, type); + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + BR_NZ(EQUAL_FLAG); + break; + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_FLOAT_EQUAL: + BR_Z(EQUAL_FLAG); + break; + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + BR_Z(ULESS_FLAG); + break; + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + BR_NZ(ULESS_FLAG); + break; + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + BR_Z(UGREATER_FLAG); + break; + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + BR_NZ(UGREATER_FLAG); + break; + case SLJIT_C_SIG_LESS: + BR_Z(LESS_FLAG); + break; + case SLJIT_C_SIG_GREATER_EQUAL: + BR_NZ(LESS_FLAG); + break; + case SLJIT_C_SIG_GREATER: + BR_Z(GREATER_FLAG); + break; + case SLJIT_C_SIG_LESS_EQUAL: + BR_NZ(GREATER_FLAG); + break; + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + BR_Z(OVERFLOW_FLAG); + break; + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + BR_NZ(OVERFLOW_FLAG); + break; + case SLJIT_C_FLOAT_NAN: + BR_F(); + break; + case SLJIT_C_FLOAT_NOT_NAN: + BR_T(); + break; + default: + /* Not conditional branch. */ + inst = 0; + break; + } + + jump->flags |= flags; + if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check)) + jump->flags |= IS_MOVABLE; + + if (inst) + PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS)); + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + if (type <= SLJIT_JUMP) { + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + } else { + SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); + /* Cannot be optimized out if type is >= CALL0. */ + jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0); + PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + jump->addr = compiler->size; + /* A NOP if type < CALL1. */ + PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); + } + return jump; +} + +#define RESOLVE_IMM1() \ + if (src1 & SLJIT_IMM) { \ + if (src1w) { \ + PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ + src1 = TMP_REG1; \ + } \ + else \ + src1 = 0; \ + } + +#define RESOLVE_IMM2() \ + if (src2 & SLJIT_IMM) { \ + if (src2w) { \ + PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ + src2 = TMP_REG2; \ + } \ + else \ + src2 = 0; \ + } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + struct sljit_jump *jump; + int flags; + sljit_ins inst; + + CHECK_ERROR_PTR(); + check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; + if (src1 & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags, DR(TMP_REG1), src1, src1w)) + PTR_FAIL_IF(compiler->error); + else + PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); + src1 = TMP_REG1; + } + if (src2 & SLJIT_MEM) { + if (getput_arg_fast(compiler, flags, DR(TMP_REG2), src2, src2w)) + PTR_FAIL_IF(compiler->error); + else + PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); + src2 = TMP_REG2; + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type <= SLJIT_C_NOT_EQUAL) { + RESOLVE_IMM1(); + RESOLVE_IMM2(); + jump->flags |= IS_BIT26_COND; + if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) + jump->flags |= IS_MOVABLE; + PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS)); + } + else if (type >= SLJIT_C_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { + inst = NOP; + if ((src1 & SLJIT_IMM) && (src1w == 0)) { + RESOLVE_IMM2(); + switch (type) { + case SLJIT_C_SIG_LESS: + inst = BLEZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_C_SIG_GREATER_EQUAL: + inst = BGTZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_C_SIG_GREATER: + inst = BGEZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_C_SIG_LESS_EQUAL: + inst = BLTZ; + jump->flags |= IS_BIT16_COND; + break; + } + src1 = src2; + } + else { + RESOLVE_IMM1(); + switch (type) { + case SLJIT_C_SIG_LESS: + inst = BGEZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_C_SIG_GREATER_EQUAL: + inst = BLTZ; + jump->flags |= IS_BIT16_COND; + break; + case SLJIT_C_SIG_GREATER: + inst = BLEZ; + jump->flags |= IS_BIT26_COND; + break; + case SLJIT_C_SIG_LESS_EQUAL: + inst = BGTZ; + jump->flags |= IS_BIT26_COND; + break; + } + } + PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS)); + } + else { + if (type == SLJIT_C_LESS || type == SLJIT_C_GREATER_EQUAL || type == SLJIT_C_SIG_LESS || type == SLJIT_C_SIG_GREATER_EQUAL) { + RESOLVE_IMM1(); + if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); + else { + RESOLVE_IMM2(); + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1))); + } + type = (type == SLJIT_C_LESS || type == SLJIT_C_SIG_LESS) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; + } + else { + RESOLVE_IMM2(); + if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); + else { + RESOLVE_IMM1(); + PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); + } + type = (type == SLJIT_C_GREATER || type == SLJIT_C_SIG_GREATER) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL; + } + + jump->flags |= IS_BIT26_COND; + PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS)); + } + + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return jump; +} + +#undef RESOLVE_IMM1 +#undef RESOLVE_IMM2 + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + struct sljit_jump *jump; + sljit_ins inst; + int if_true; + + CHECK_ERROR_PTR(); + check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (src1 > SLJIT_FLOAT_REG4) { + PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + if (src2 > SLJIT_FLOAT_REG4) { + PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); + src2 = TMP_FREG2; + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + jump->flags |= IS_BIT16_COND; + type &= 0xff; + + switch (type) { + case SLJIT_C_FLOAT_EQUAL: + inst = C_UEQ_D; + if_true = 1; + break; + case SLJIT_C_FLOAT_NOT_EQUAL: + inst = C_UEQ_D; + if_true = 0; + break; + case SLJIT_C_FLOAT_LESS: + inst = C_ULT_D; + if_true = 1; + break; + case SLJIT_C_FLOAT_GREATER_EQUAL: + inst = C_ULT_D; + if_true = 0; + break; + case SLJIT_C_FLOAT_GREATER: + inst = C_ULE_D; + if_true = 0; + break; + case SLJIT_C_FLOAT_LESS_EQUAL: + inst = C_ULE_D; + if_true = 1; + break; + case SLJIT_C_FLOAT_NAN: + inst = C_UN_D; + if_true = 1; + break; + case SLJIT_C_FLOAT_NOT_NAN: + default: /* Make compilers happy. */ + inst = C_UN_D; + if_true = 0; + break; + } + + PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS)); + /* Intentionally the other opcode. */ + PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); + PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS)); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return jump; +} + +#undef JUMP_LENGTH +#undef BR_Z +#undef BR_NZ +#undef BR_T +#undef BR_F + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + int src_r = TMP_REG2; + struct sljit_jump *jump = NULL; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + if (DR(src) != 4) + src_r = src; + else + FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + } + + if (type >= SLJIT_CALL0) { + SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); + if (src & (SLJIT_IMM | SLJIT_MEM)) { + if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); + else { + SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM)); + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + } + FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + /* We need an extra instruction in any case. */ + return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); + } + + /* Register input. */ + if (type >= SLJIT_CALL1) + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); + FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS)); + return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS); + } + + if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); + jump->u.target = srcw; + + if (compiler->delay_slot != UNMOVABLE_INS) + jump->flags |= IS_MOVABLE; + + FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + } + else if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + + FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); + if (jump) + jump->addr = compiler->size; + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + int sugg_dst_ar, dst_ar; + + CHECK_ERROR(); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2); + + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_NOT_EQUAL: + FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + break; + case SLJIT_C_LESS: + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_LESS: + case SLJIT_C_FLOAT_GREATER_EQUAL: + dst_ar = ULESS_FLAG; + break; + case SLJIT_C_GREATER: + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_GREATER: + case SLJIT_C_FLOAT_LESS_EQUAL: + dst_ar = UGREATER_FLAG; + break; + case SLJIT_C_SIG_LESS: + case SLJIT_C_SIG_GREATER_EQUAL: + dst_ar = LESS_FLAG; + break; + case SLJIT_C_SIG_GREATER: + case SLJIT_C_SIG_LESS_EQUAL: + dst_ar = GREATER_FLAG; + break; + case SLJIT_C_OVERFLOW: + case SLJIT_C_NOT_OVERFLOW: + dst_ar = OVERFLOW_FLAG; + break; + case SLJIT_C_MUL_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + type ^= 0x1; /* Flip type bit for the XORI below. */ + break; + case SLJIT_C_FLOAT_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + dst_ar = EQUAL_FLAG; + break; + + case SLJIT_C_FLOAT_NAN: + case SLJIT_C_FLOAT_NOT_NAN: + FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); + FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); + FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + break; + + default: + SLJIT_ASSERT_STOP(); + dst_ar = sugg_dst_ar; + break; + } + + if (type & 0x1) { + FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); + dst_ar = sugg_dst_ar; + } + + if (GET_OPCODE(op) == SLJIT_OR) { + if (DR(TMP_REG2) != dst_ar) + FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw); + + if (sugg_dst_ar != dst_ar) + return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + struct sljit_const *const_; + int reg; + + CHECK_ERROR_PTR(); + check_sljit_emit_const(compiler, dst, dstw, init_value); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} diff -Nru pcre3-8.12/sljit/sljitNativePPC_32.c pcre3-8.31/sljit/sljitNativePPC_32.c --- pcre3-8.12/sljit/sljitNativePPC_32.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativePPC_32.c 2012-01-10 14:05:14.000000000 +0000 @@ -0,0 +1,262 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* ppc 32-bit arch dependent functions. */ + +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) +{ + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); + + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm)); + + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; +} + +#define INS_CLEAR_LEFT(dst, src, from) \ + (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) + +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) +{ + switch (op) { + case SLJIT_ADD: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM2) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM4) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); + return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); + return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); + + case SLJIT_ADDC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | S(0))); + FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); + return push_inst(compiler, MTXER | S(0)); + } + return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); + + case SLJIT_SUB: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & (ALT_FORM2 | ALT_FORM3)) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) + FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm)); + if (flags & ALT_FORM3) + return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm); + return SLJIT_SUCCESS; + } + if (flags & (ALT_FORM4 | ALT_FORM5)) { + if (flags & ALT_FORM4) + FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); + if (flags & ALT_FORM5) + FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2))); + return SLJIT_SUCCESS; + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); + if (flags & ALT_FORM6) + FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2))); + return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); + + case SLJIT_SUBC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | S(0))); + FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); + return push_inst(compiler, MTXER | S(0)); + } + return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); + + case SLJIT_MUL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); + } + return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); + + case SLJIT_AND: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); + } + return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_OR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_XOR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_SHL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); + } + return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_LSHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); + } + return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_ASHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + compiler->imm &= 0x1f; + return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); + } + return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) +{ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 2); +} diff -Nru pcre3-8.12/sljit/sljitNativePPC_64.c pcre3-8.31/sljit/sljitNativePPC_64.c --- pcre3-8.12/sljit/sljitNativePPC_64.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativePPC_64.c 2012-01-10 14:05:14.000000000 +0000 @@ -0,0 +1,428 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* ppc 64-bit arch dependent functions. */ + +#ifdef __GNUC__ +#define ASM_SLJIT_CLZ(src, dst) \ + asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) +#else +#error "Must implement count leading zeroes" +#endif + +#define RLDI(dst, src, sh, mb, type) \ + (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) + +#define PUSH_RLDICR(reg, shift) \ + push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) + +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) +{ + sljit_uw tmp; + sljit_uw shift; + sljit_uw tmp2; + sljit_uw shift2; + + if (imm <= SIMM_MAX && imm >= SIMM_MIN) + return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); + + if (!(imm & ~0xffff)) + return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm)); + + if (imm <= SLJIT_W(0x7fffffff) && imm >= SLJIT_W(-0x80000000)) { + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; + } + + /* Count leading zeroes. */ + tmp = (imm >= 0) ? imm : ~imm; + ASM_SLJIT_CLZ(tmp, shift); + SLJIT_ASSERT(shift > 0); + shift--; + tmp = (imm << shift); + + if ((tmp & ~0xffff000000000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + shift += 15; + return PUSH_RLDICR(reg, shift); + } + + if ((tmp & ~0xffffffff00000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32))); + shift += 31; + return PUSH_RLDICR(reg, shift); + } + + /* Cut out the 16 bit from immediate. */ + shift += 15; + tmp2 = imm & ((1ul << (63 - shift)) - 1); + + if (tmp2 <= 0xffff) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(PUSH_RLDICR(reg, shift)); + return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2); + } + + if (tmp2 <= 0xffffffff) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + FAIL_IF(PUSH_RLDICR(reg, shift)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS; + } + + ASM_SLJIT_CLZ(tmp2, shift2); + tmp2 <<= shift2; + + if ((tmp2 & ~0xffff000000000000ul) == 0) { + FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48))); + shift2 += 15; + shift += (63 - shift2); + FAIL_IF(PUSH_RLDICR(reg, shift)); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48))); + return PUSH_RLDICR(reg, shift2); + } + + /* The general version. */ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32))); + FAIL_IF(PUSH_RLDICR(reg, 31)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)); +} + +/* Simplified mnemonics: clrldi. */ +#define INS_CLEAR_LEFT(dst, src, from) \ + (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5)) + +/* Sign extension for integer operations. */ +#define UN_EXTS() \ + if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ + src2 = TMP_REG2; \ + } + +#define BIN_EXTS() \ + if (flags & ALT_SIGN_EXT) { \ + if (flags & REG1_SOURCE) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ + src1 = TMP_REG1; \ + } \ + if (flags & REG2_SOURCE) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \ + src2 = TMP_REG2; \ + } \ + } + +#define BIN_IMM_EXTS() \ + if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \ + FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \ + src1 = TMP_REG1; \ + } + +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) +{ + switch (op) { + case SLJIT_ADD: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM2) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + BIN_IMM_EXTS(); + return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & ALT_FORM4) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff))); + return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))); + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2)); + BIN_EXTS(); + return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)); + + case SLJIT_ADDC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | S(0))); + FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); + return push_inst(compiler, MTXER | S(0)); + } + BIN_EXTS(); + return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)); + + case SLJIT_SUB: + if (flags & ALT_FORM1) { + /* Flags does not set: BIN_IMM_EXTS unnecessary. */ + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm); + } + if (flags & (ALT_FORM2 | ALT_FORM3)) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm)); + if (flags & ALT_FORM3) + return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm); + return SLJIT_SUCCESS; + } + if (flags & (ALT_FORM4 | ALT_FORM5)) { + if (flags & ALT_FORM4) + FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); + if (flags & ALT_FORM5) + return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)); + return SLJIT_SUCCESS; + } + if (!(flags & ALT_SET_FLAGS)) + return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1)); + BIN_EXTS(); + if (flags & ALT_FORM6) + FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2))); + return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)); + + case SLJIT_SUBC: + if (flags & ALT_FORM1) { + FAIL_IF(push_inst(compiler, MFXER | S(0))); + FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); + return push_inst(compiler, MTXER | S(0)); + } + BIN_EXTS(); + return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)); + + case SLJIT_MUL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm); + } + BIN_EXTS(); + if (flags & ALT_FORM2) + return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1)); + return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1)); + + case SLJIT_AND: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm); + } + return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_OR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_XOR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM2) { + SLJIT_ASSERT(src2 == TMP_REG2); + return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm); + } + if (flags & ALT_FORM3) { + SLJIT_ASSERT(src2 == TMP_REG2); + FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm))); + return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16)); + } + return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_SHL: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1)); + } + else { + compiler->imm &= 0x3f; + return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags)); + } + } + if (flags & ALT_FORM2) + return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_LSHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1)); + } + else { + compiler->imm &= 0x3f; + return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags)); + } + } + if (flags & ALT_FORM2) + return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_ASHR: + if (flags & ALT_FORM1) { + SLJIT_ASSERT(src2 == TMP_REG2); + if (flags & ALT_FORM2) { + compiler->imm &= 0x1f; + return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); + } + else { + compiler->imm &= 0x3f; + return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)); + } + } + if (flags & ALT_FORM2) + return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_MOV: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SI) + return push_inst(compiler, EXTSW | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + if (flags & ALT_FORM1) + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); + return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); + } + + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) +{ + FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); + FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); + FAIL_IF(PUSH_RLDICR(reg, 31)); + FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16))); + return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff); + inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 5); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + sljit_ins *inst = (sljit_ins*)addr; + + inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff); + inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff); + inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff); + inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); + SLJIT_CACHE_FLUSH(inst, inst + 5); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func) +{ + sljit_w* ptrs; + if (func_ptr) + *func_ptr = (void*)context; + ptrs = (sljit_w*)func; + context->addr = addr ? addr : ptrs[0]; + context->r2 = ptrs[1]; + context->r11 = ptrs[2]; +} diff -Nru pcre3-8.12/sljit/sljitNativePPC_common.c pcre3-8.31/sljit/sljitNativePPC_common.c --- pcre3-8.12/sljit/sljitNativePPC_common.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativePPC_common.c 2012-04-03 15:33:31.000000000 +0000 @@ -0,0 +1,1865 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ + return "PowerPC" SLJIT_CPUINFO; +} + +/* Length of an instruction word. + Both for ppc-32 and ppc-64. */ +typedef sljit_ui sljit_ins; + +static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) +{ + while (from < to) { +#ifdef __GNUC__ + asm volatile ( "icbi 0, %0" : : "r"(from) ); +#else +#error "Must implement icbi" +#endif + from++; + } +} + +#define TMP_REG1 (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) +#define ZERO_REG (SLJIT_NO_REGISTERS + 4) + +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) + +/* --------------------------------------------------------------------- */ +/* Instrucion forms */ +/* --------------------------------------------------------------------- */ +#define D(d) (reg_map[d] << 21) +#define S(s) (reg_map[s] << 21) +#define A(a) (reg_map[a] << 16) +#define B(b) (reg_map[b] << 11) +#define C(c) (reg_map[c] << 6) +#define FD(fd) ((fd) << 21) +#define FA(fa) ((fa) << 16) +#define FB(fb) ((fb) << 11) +#define FC(fc) ((fc) << 6) +#define IMM(imm) ((imm) & 0xffff) +#define CRD(d) ((d) << 21) + +/* Instruction bit sections. + OE and Rc flag (see ALT_SET_FLAGS). */ +#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS)) +/* Rc flag (see ALT_SET_FLAGS). */ +#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10) +#define HI(opcode) ((opcode) << 26) +#define LO(opcode) ((opcode) << 1) + +#define ADD (HI(31) | LO(266)) +#define ADDC (HI(31) | LO(10)) +#define ADDE (HI(31) | LO(138)) +#define ADDI (HI(14)) +#define ADDIC (HI(13)) +#define ADDIS (HI(15)) +#define ADDME (HI(31) | LO(234)) +#define AND (HI(31) | LO(28)) +#define ANDI (HI(28)) +#define ANDIS (HI(29)) +#define Bx (HI(18)) +#define BCx (HI(16)) +#define BCCTR (HI(19) | LO(528) | (3 << 11)) +#define BLR (HI(19) | LO(16) | (0x14 << 21)) +#define CNTLZD (HI(31) | LO(58)) +#define CNTLZW (HI(31) | LO(26)) +#define CMP (HI(31) | LO(0)) +#define CMPI (HI(11)) +#define CMPL (HI(31) | LO(32)) +#define CMPLI (HI(10)) +#define CROR (HI(19) | LO(449)) +#define DIVD (HI(31) | LO(489)) +#define DIVDU (HI(31) | LO(457)) +#define DIVW (HI(31) | LO(491)) +#define DIVWU (HI(31) | LO(459)) +#define EXTSB (HI(31) | LO(954)) +#define EXTSH (HI(31) | LO(922)) +#define EXTSW (HI(31) | LO(986)) +#define FABS (HI(63) | LO(264)) +#define FADD (HI(63) | LO(21)) +#define FCMPU (HI(63) | LO(0)) +#define FDIV (HI(63) | LO(18)) +#define FMR (HI(63) | LO(72)) +#define FMUL (HI(63) | LO(25)) +#define FNEG (HI(63) | LO(40)) +#define FSUB (HI(63) | LO(20)) +#define LD (HI(58) | 0) +#define LFD (HI(50)) +#define LFDUX (HI(31) | LO(631)) +#define LFDX (HI(31) | LO(599)) +#define LWZ (HI(32)) +#define MFCR (HI(31) | LO(19)) +#define MFLR (HI(31) | LO(339) | 0x80000) +#define MFXER (HI(31) | LO(339) | 0x10000) +#define MTCTR (HI(31) | LO(467) | 0x90000) +#define MTLR (HI(31) | LO(467) | 0x80000) +#define MTXER (HI(31) | LO(467) | 0x10000) +#define MULHD (HI(31) | LO(73)) +#define MULHDU (HI(31) | LO(9)) +#define MULHW (HI(31) | LO(75)) +#define MULHWU (HI(31) | LO(11)) +#define MULLD (HI(31) | LO(233)) +#define MULLI (HI(7)) +#define MULLW (HI(31) | LO(235)) +#define NEG (HI(31) | LO(104)) +#define NOP (HI(24)) +#define NOR (HI(31) | LO(124)) +#define OR (HI(31) | LO(444)) +#define ORI (HI(24)) +#define ORIS (HI(25)) +#define RLDICL (HI(30)) +#define RLWINM (HI(21)) +#define SLD (HI(31) | LO(27)) +#define SLW (HI(31) | LO(24)) +#define SRAD (HI(31) | LO(794)) +#define SRADI (HI(31) | LO(413 << 1)) +#define SRAW (HI(31) | LO(792)) +#define SRAWI (HI(31) | LO(824)) +#define SRD (HI(31) | LO(539)) +#define SRW (HI(31) | LO(536)) +#define STD (HI(62) | 0) +#define STDU (HI(62) | 1) +#define STDUX (HI(31) | LO(181)) +#define STFD (HI(54)) +#define STFDUX (HI(31) | LO(759)) +#define STFDX (HI(31) | LO(727)) +#define STW (HI(36)) +#define STWU (HI(37)) +#define STWUX (HI(31) | LO(183)) +#define SUBF (HI(31) | LO(40)) +#define SUBFC (HI(31) | LO(8)) +#define SUBFE (HI(31) | LO(136)) +#define SUBFIC (HI(8)) +#define XOR (HI(31) | LO(316)) +#define XORI (HI(26)) +#define XORIS (HI(27)) + +#define SIMM_MAX (0x7fff) +#define SIMM_MIN (-0x8000) +#define UIMM_MAX (0xffff) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { + 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 +}; + +static int push_inst(struct sljit_compiler *compiler, sljit_ins ins) +{ + sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + *ptr = ins; + compiler->size++; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +{ + sljit_w diff; + sljit_uw target_addr; + + if (jump->flags & SLJIT_REWRITABLE_JUMP) + return 0; + + if (jump->flags & JUMP_ADDR) + target_addr = jump->u.target; + else { + SLJIT_ASSERT(jump->flags & JUMP_LABEL); + target_addr = (sljit_uw)(code + jump->u.label->size); + } + diff = ((sljit_w)target_addr - (sljit_w)(code_ptr)) & ~0x3l; + + if (jump->flags & UNCOND_B) { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + jump->flags |= PATCH_B; + return 1; + } + if (target_addr <= 0x03ffffff) { + jump->flags |= PATCH_B | ABSOLUTE_B; + return 1; + } + } + else { + if (diff <= 0x7fff && diff >= -0x8000) { + jump->flags |= PATCH_B; + return 1; + } + if (target_addr <= 0xffff) { + jump->flags |= PATCH_B | ABSOLUTE_B; + return 1; + } + } + return 0; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; + sljit_uw word_count; + sljit_uw addr; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + check_sljit_generate_code(compiler); + reverse_buf(compiler); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); +#endif + code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + word_count = 0; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = (sljit_ins*)buf->memory; + buf_end = buf_ptr + (buf->used_size >> 2); + do { + *code_ptr = *buf_ptr++; + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + jump->addr = (sljit_uw)(code_ptr - 3); +#else + jump->addr = (sljit_uw)(code_ptr - 6); +#endif + if (optimize_jump(jump, code_ptr, code)) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + code_ptr[-3] = code_ptr[0]; + code_ptr -= 3; +#else + code_ptr[-6] = code_ptr[0]; + code_ptr -= 6; +#endif + } + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + code_ptr ++; + word_count ++; + } while (buf_ptr < buf_end); + + buf = buf->next; + } while (buf); + + if (label && label->size == word_count) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size - ((compiler->size & 0x1) ? 3 : 2)); +#else + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); +#endif + + jump = compiler->jumps; + while (jump) { + do { + addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; + buf_ptr = (sljit_ins*)jump->addr; + if (jump->flags & PATCH_B) { + if (jump->flags & UNCOND_B) { + if (!(jump->flags & ABSOLUTE_B)) { + addr = addr - jump->addr; + SLJIT_ASSERT((sljit_w)addr <= 0x01ffffff && (sljit_w)addr >= -0x02000000); + *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); + } + else { + SLJIT_ASSERT(addr <= 0x03ffffff); + *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); + } + } + else { + if (!(jump->flags & ABSOLUTE_B)) { + addr = addr - jump->addr; + SLJIT_ASSERT((sljit_w)addr <= 0x7fff && (sljit_w)addr >= -0x8000); + *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); + } + else { + addr = addr & ~0x3l; + SLJIT_ASSERT(addr <= 0xffff); + *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); + } + + } + break; + } + /* Set the fields of immediate loads. */ +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); +#else + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); +#endif + } while (0); + jump = jump->next; + } + + SLJIT_CACHE_FLUSH(code, code_ptr); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = compiler->size * sizeof(sljit_ins); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (((sljit_w)code_ptr) & 0x4) + code_ptr++; + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_w)code, sljit_generate_code); + return code_ptr; +#else + return code; +#endif +} + +/* inp_flags: */ + +/* Creates an index in data_transfer_insts array. */ +#define WORD_DATA 0x00 +#define BYTE_DATA 0x01 +#define HALF_DATA 0x02 +#define INT_DATA 0x03 +#define SIGNED_DATA 0x04 +#define LOAD_DATA 0x08 +#define WRITE_BACK 0x10 +#define INDEXED 0x20 + +#define MEM_MASK 0x3f + +/* Other inp_flags. */ + +#define ARG_TEST 0x000100 +/* Integer opertion and set flags -> requires exts on 64 bit systems. */ +#define ALT_SIGN_EXT 0x000200 +/* This flag affects the RC() and OERC() macros. */ +#define ALT_SET_FLAGS 0x000400 +#define ALT_FORM1 0x010000 +#define ALT_FORM2 0x020000 +#define ALT_FORM3 0x040000 +#define ALT_FORM4 0x080000 +#define ALT_FORM5 0x100000 +#define ALT_FORM6 0x200000 + +/* Source and destination is register. */ +#define REG_DEST 0x000001 +#define REG1_SOURCE 0x000002 +#define REG2_SOURCE 0x000004 +/* getput_arg_fast returned true. */ +#define FAST_DEST 0x000008 +/* Multiple instructions are required. */ +#define SLOW_DEST 0x000010 +/* +ALT_SIGN_EXT 0x000200 +ALT_SET_FLAGS 0x000400 +ALT_FORM1 0x010000 +... +ALT_FORM6 0x200000 */ + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#include "sljitNativePPC_32.c" +#else +#include "sljitNativePPC_64.c" +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define STACK_STORE STW +#define STACK_LOAD LWZ +#else +#define STACK_STORE STD +#define STACK_LOAD LD +#endif + +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + FAIL_IF(push_inst(compiler, MFLR | D(0))); + FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); + if (saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); + if (saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); + if (saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); + if (saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); + if (saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)) )); + + FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); + if (args >= 1) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1))); + if (args >= 2) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2))); + if (args >= 3) + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3))); + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; +#else + compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; +#endif + compiler->local_size = (compiler->local_size + 15) & ~0xf; + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (compiler->local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, STWU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, -compiler->local_size)); + FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); + } +#else + if (compiler->local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, STDU | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(-compiler->local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, -compiler->local_size)); + FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); + } +#endif + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; +#else + compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; +#endif + compiler->local_size = (compiler->local_size + 15) & ~0xf; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + if (compiler->local_size <= SIMM_MAX) + FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | IMM(compiler->local_size))); + else { + FAIL_IF(load_immediate(compiler, 0, compiler->local_size)); + FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); + } + + FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)))); + if (compiler->saveds >= 5) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); + if (compiler->saveds >= 4) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); + if (compiler->saveds >= 3) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); + if (compiler->saveds >= 2) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); + if (compiler->saveds >= 1) + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); + + FAIL_IF(push_inst(compiler, MTLR | S(0))); + FAIL_IF(push_inst(compiler, BLR)); + + return SLJIT_SUCCESS; +} + +#undef STACK_STORE +#undef STACK_LOAD + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* i/x - immediate/indexed form + n/w - no write-back / write-back (1 bit) + s/l - store/load (1 bit) + u/s - signed/unsigned (1 bit) + w/b/h/i - word/byte/half/int allowed (2 bit) + It contans 32 items, but not all are different. */ + +/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ +#define ADDR_MODE2 0x10000 +/* 64-bit only: there is no lwau instruction. */ +#define UPDATE_REQ 0x20000 + +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) +#define ARCH_DEPEND(a, b) a +#define GET_INST_CODE(inst) (inst) +#else +#define ARCH_DEPEND(a, b) b +#define GET_INST_CODE(index) ((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) +#endif + +static SLJIT_CONST sljit_ins data_transfer_insts[64] = { + +/* No write-back. */ + +/* i n s u w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* i n s u b */ HI(38) /* stb */, +/* i n s u h */ HI(44) /* sth*/, +/* i n s u i */ HI(36) /* stw */, + +/* i n s s w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* i n s s b */ HI(38) /* stb */, +/* i n s s h */ HI(44) /* sth*/, +/* i n s s i */ HI(36) /* stw */, + +/* i n l u w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* i n l u b */ HI(34) /* lbz */, +/* i n l u h */ HI(40) /* lhz */, +/* i n l u i */ HI(32) /* lwz */, + +/* i n l s w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* i n l s b */ HI(34) /* lbz */ /* EXTS_REQ */, +/* i n l s h */ HI(42) /* lha */, +/* i n l s i */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), + +/* Write-back. */ + +/* i w s u w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* i w s u b */ HI(39) /* stbu */, +/* i w s u h */ HI(45) /* sthu */, +/* i w s u i */ HI(37) /* stwu */, + +/* i w s s w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* i w s s b */ HI(39) /* stbu */, +/* i w s s h */ HI(45) /* sthu */, +/* i w s s i */ HI(37) /* stwu */, + +/* i w l u w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* i w l u b */ HI(35) /* lbzu */, +/* i w l u h */ HI(41) /* lhzu */, +/* i w l u i */ HI(33) /* lwzu */, + +/* i w l s w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* i w l s b */ HI(35) /* lbzu */ /* EXTS_REQ */, +/* i w l s h */ HI(43) /* lhau */, +/* i w l s i */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), + +/* ---------- */ +/* Indexed */ +/* ---------- */ + +/* No write-back. */ + +/* x n s u w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* x n s u b */ HI(31) | LO(215) /* stbx */, +/* x n s u h */ HI(31) | LO(407) /* sthx */, +/* x n s u i */ HI(31) | LO(151) /* stwx */, + +/* x n s s w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* x n s s b */ HI(31) | LO(215) /* stbx */, +/* x n s s h */ HI(31) | LO(407) /* sthx */, +/* x n s s i */ HI(31) | LO(151) /* stwx */, + +/* x n l u w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* x n l u b */ HI(31) | LO(87) /* lbzx */, +/* x n l u h */ HI(31) | LO(279) /* lhzx */, +/* x n l u i */ HI(31) | LO(23) /* lwzx */, + +/* x n l s w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* x n l s b */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, +/* x n l s h */ HI(31) | LO(343) /* lhax */, +/* x n l s i */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), + +/* Write-back. */ + +/* x w s u w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* x w s u b */ HI(31) | LO(247) /* stbux */, +/* x w s u h */ HI(31) | LO(439) /* sthux */, +/* x w s u i */ HI(31) | LO(183) /* stwux */, + +/* x w s s w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* x w s s b */ HI(31) | LO(247) /* stbux */, +/* x w s s h */ HI(31) | LO(439) /* sthux */, +/* x w s s i */ HI(31) | LO(183) /* stwux */, + +/* x w l u w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* x w l u b */ HI(31) | LO(119) /* lbzux */, +/* x w l u h */ HI(31) | LO(311) /* lhzux */, +/* x w l u i */ HI(31) | LO(55) /* lwzux */, + +/* x w l s w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* x w l s b */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, +/* x w l s h */ HI(31) | LO(375) /* lhaux */, +/* x w l s i */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */) + +}; + +#undef ARCH_DEPEND + +/* Simple cases, (no caching is required). */ +static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) +{ + sljit_ins inst; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + int tmp_reg; +#endif + + SLJIT_ASSERT(arg & SLJIT_MEM); + if (!(arg & 0xf)) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (inp_flags & ARG_TEST) + return 1; + + inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); + return -1; + } +#else + inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; + if (argw <= SIMM_MAX && argw >= SIMM_MIN && + (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) { + if (inp_flags & ARG_TEST) + return 1; + + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); + return -1; + } +#endif + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; + } + + if (!(arg & 0xf0)) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (inp_flags & ARG_TEST) + return 1; + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); + return -1; + } +#else + inst = data_transfer_insts[inp_flags & MEM_MASK]; + if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) { + if (inp_flags & ARG_TEST) + return 1; + + if ((inp_flags & WRITE_BACK) && (inst & UPDATE_REQ)) { + tmp_reg = (inp_flags & LOAD_DATA) ? (arg & 0xf) : TMP_REG3; + if (push_inst(compiler, ADDI | D(tmp_reg) | A(arg & 0xf) | IMM(argw))) + return -1; + arg = tmp_reg | SLJIT_MEM; + argw = 0; + } + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); + return -1; + } +#endif + } + else if (!(argw & 0x3)) { + if (inp_flags & ARG_TEST) + return 1; + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + return -1; + } + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; +} + +/* See getput_arg below. + Note: can_cache is called only for binary operators. Those operator always + uses word arguments without write back. */ +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + SLJIT_ASSERT(next_arg & SLJIT_MEM); + + if (!(arg & 0xf)) { + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) + return 1; + return 0; + } + + if (arg & 0xf0) + return 0; + + if (argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN)) + return 1; + } + + if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) + return 1; + + return 0; +} + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define ADJUST_CACHED_IMM(imm) \ + if ((inst & ADDR_MODE2) && (imm & 0x3)) { \ + /* Adjust cached value. Fortunately this is really a rare case */ \ + compiler->cache_argw += imm & 0x3; \ + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \ + imm &= ~0x3; \ + } +#else +#define ADJUST_CACHED_IMM(imm) +#endif + +/* Emit the necessary instructions. See can_cache above. */ +static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) +{ + int tmp_r; + sljit_ins inst; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; + if ((arg & 0xf) == tmp_r) { + /* Special case for "mov reg, [reg, ... ]". + Caching would not happen anyway. */ + tmp_r = TMP_REG3; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } + + if (!(arg & 0xf)) { + inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; + if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= SIMM_MAX || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= SIMM_MAX)) { + argw = argw - compiler->cache_argw; + ADJUST_CACHED_IMM(argw); + SLJIT_ASSERT(!(inst & UPDATE_REQ)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); + } + + if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + tmp_r = TMP_REG3; + } + + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(tmp_r)); + } + + if (SLJIT_UNLIKELY(arg & 0xf0)) { + argw &= 0x3; + /* Otherwise getput_arg_fast would capture it. */ + SLJIT_ASSERT(argw); +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1))); +#endif + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); + } + + inst = data_transfer_insts[inp_flags & MEM_MASK]; + + if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw <= SIMM_MAX || (sljit_uw)compiler->cache_argw - (sljit_uw)argw <= SIMM_MAX)) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + argw = argw - compiler->cache_argw; + ADJUST_CACHED_IMM(argw); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); + } + + if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); + } + + if (argw == next_argw && (next_arg & SLJIT_MEM)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + + compiler->cache_arg = SLJIT_IMM; + compiler->cache_argw = argw; + + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); + } + + if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) { + SLJIT_ASSERT(inp_flags & LOAD_DATA); + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & 0xf))); + + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3)); + } + + /* Get the indexed version instead of the normal one. */ + inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; + SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); + FAIL_IF(load_immediate(compiler, tmp_r, argw)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); +} + +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* arg1 goes to TMP_REG1 or src reg + arg2 goes to TMP_REG2, imm or src reg + TMP_REG3 can be used for caching + result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ + int dst_r; + int src1_r; + int src2_r; + int sugg_src2_r = TMP_REG2; + int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + /* Destination check. */ + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) { + dst_r = dst; + flags |= REG_DEST; + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; + } + else if (dst == SLJIT_UNUSED) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } + else { + SLJIT_ASSERT(dst & SLJIT_MEM); + if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { + flags |= FAST_DEST; + dst_r = TMP_REG2; + } + else { + flags |= SLOW_DEST; + dst_r = 0; + } + } + + /* Source 1. */ + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) { + src1_r = src1; + flags |= REG1_SOURCE; + } + else if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if ((inp_flags & 0x3) == INT_DATA) { + if (inp_flags & SIGNED_DATA) + src1w = (signed int)src1w; + else + src1w = (unsigned int)src1w; + } +#endif + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1_r = TMP_REG1; + } + else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + FAIL_IF(compiler->error); + src1_r = TMP_REG1; + } + else + src1_r = 0; + + /* Source 2. */ + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) { + src2_r = src2; + flags |= REG2_SOURCE; + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + dst_r = src2_r; + } + else if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if ((inp_flags & 0x3) == INT_DATA) { + if (inp_flags & SIGNED_DATA) + src2w = (signed int)src2w; + else + src2w = (unsigned int)src2w; + } +#endif + FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); + src2_r = sugg_src2_r; + } + else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { + FAIL_IF(compiler->error); + src2_r = sugg_src2_r; + } + else + src2_r = 0; + + /* src1_r, src2_r and dst_r can be zero (=unprocessed). + All arguments are complex addressing modes, and it is a binary operator. */ + if (src1_r == 0 && src2_r == 0 && dst_r == 0) { + if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + } + else { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + } + src1_r = TMP_REG1; + src2_r = TMP_REG2; + } + else if (src1_r == 0 && src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + src1_r = TMP_REG1; + } + else if (src1_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + src1_r = TMP_REG1; + } + else if (src2_r == 0 && dst_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + src2_r = sugg_src2_r; + } + + if (dst_r == 0) + dst_r = TMP_REG2; + + if (src1_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + src1_r = TMP_REG1; + } + + if (src2_r == 0) { + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); + src2_r = sugg_src2_r; + } + + FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); + + if (flags & (FAST_DEST | SLOW_DEST)) { + if (flags & FAST_DEST) + FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); + else + FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + switch (GET_OPCODE(op)) { + case SLJIT_BREAKPOINT: + case SLJIT_NOP: + return push_inst(compiler, NOP); + break; + case SLJIT_UMUL: + case SLJIT_SMUL: + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); +#else + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); +#endif + case SLJIT_UDIV: + case SLJIT_SDIV: + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) { + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); + } + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); +#else + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); +#endif + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if ((src & SLJIT_IMM) && srcw == 0) + src = ZERO_REG; + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) { + inp_flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (int)srcw; + } +#endif + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV: + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UI: + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_SI: + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOV_UB: + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOV_SB: + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOV_UH: + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOV_SH: + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_MOVU: + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UI: + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_SI: + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_MOVU_UB: + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); + + case SLJIT_MOVU_SB: + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); + + case SLJIT_MOVU_UH: + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); + + case SLJIT_MOVU_SH: + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); + + case SLJIT_NOT: + return emit_op(compiler, SLJIT_NOT, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_NEG: + return emit_op(compiler, SLJIT_NEG, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_CLZ: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + return emit_op(compiler, SLJIT_CLZ, inp_flags | (!(op & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); +#else + return emit_op(compiler, SLJIT_CLZ, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); +#endif + } + + return SLJIT_SUCCESS; +} + +#define TEST_SL_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) + +#define TEST_UL_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_SH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000)) +#else +#define TEST_SH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) +#endif + +#define TEST_UH_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000)) + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_ADD_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000)) +#else +#define TEST_ADD_IMM(src, srcw) \ + ((src) & SLJIT_IMM) +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_UI_IMM(src, srcw) \ + (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) +#else +#define TEST_UI_IMM(src, srcw) \ + ((src) & SLJIT_IMM) +#endif + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + + CHECK_ERROR(); + check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + if ((src1 & SLJIT_IMM) && src1w == 0) + src1 = ZERO_REG; + if ((src2 & SLJIT_IMM) && src2w == 0) + src2 = ZERO_REG; + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) { + inp_flags |= INT_DATA | SIGNED_DATA; + if (src1 & SLJIT_IMM) + src1w = (src1w << 32) >> 32; + if (src2 & SLJIT_IMM) + src2w = (src2w << 32) >> 32; + if (GET_FLAGS(op)) + inp_flags |= ALT_SIGN_EXT; + } +#endif + if (op & SLJIT_SET_O) + FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src2, src2w)) { + compiler->imm = (src2w >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src1, src1w)) { + compiler->imm = (src1w >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + /* Range between -1 and -32768 is covered above. */ + if (TEST_ADD_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_ADD_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_ADD, inp_flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_ADDC: + return emit_op(compiler, SLJIT_ADDC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUB: + if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (TEST_SL_IMM(src2, -src2w)) { + compiler->imm = (-src2w) & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_SH_IMM(src2, -src2w)) { + compiler->imm = ((-src2w) >> 16) & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + /* Range between -1 and -32768 is covered above. */ + if (TEST_ADD_IMM(src2, -src2w)) { + compiler->imm = -src2w & 0xffffffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + } + } + if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { + if (!(op & SLJIT_SET_U)) { + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + if (TEST_UL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); + } + if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) { + compiler->imm = src2w; + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, SLJIT_SUB, inp_flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + } + if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) { + if (TEST_SL_IMM(src2, -src2w)) { + compiler->imm = (-src2w) & 0xffff; + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + } + /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SUBC: + return emit_op(compiler, SLJIT_SUBC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_MUL: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) + inp_flags |= ALT_FORM2; +#endif + if (!GET_FLAGS(op)) { + if (TEST_SL_IMM(src2, src2w)) { + compiler->imm = src2w & 0xffff; + return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_SL_IMM(src1, src1w)) { + compiler->imm = src1w & 0xffff; + return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, SLJIT_MUL, inp_flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_AND: + case SLJIT_OR: + case SLJIT_XOR: + /* Commutative unsigned operations. */ + if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { + if (TEST_UL_IMM(src2, src2w)) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UL_IMM(src1, src1w)) { + compiler->imm = src1w; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + } + if (TEST_UH_IMM(src2, src2w)) { + compiler->imm = (src2w >> 16) & 0xffff; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UH_IMM(src1, src1w)) { + compiler->imm = (src1w >> 16) & 0xffff; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) { + if (TEST_UI_IMM(src2, src2w)) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + } + if (TEST_UI_IMM(src1, src1w)) { + compiler->imm = src1w; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + } + } + return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); + + case SLJIT_SHL: + case SLJIT_LSHR: + case SLJIT_ASHR: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) + inp_flags |= ALT_FORM2; +#endif + if (src2 & SLJIT_IMM) { + compiler->imm = src2w; + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + } + return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + check_sljit_get_register_index(reg); + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size == 4); + + return push_inst(compiler, *(sljit_ins*)instruction); +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ + /* Always available. */ + return 1; +} + +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) +{ + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (!(arg & 0xf0)) { + /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ + if (argw <= SIMM_MAX && argw >= SIMM_MIN) + return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(arg & 0xf) | IMM(argw)); + } + + if (arg & 0xf0) { + argw &= 0x3; + if (argw) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(TMP_REG2) | (argw << 11) | ((31 - argw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, (arg >> 4) & 0xf, argw, 63 - argw, 1))); +#endif + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B(TMP_REG2)); + } + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + } + + /* Use cache. */ + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) + return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(TMP_REG3) | IMM(argw - compiler->cache_argw)); + + /* Put value to cache. */ + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + if (!(arg & 0xf)) + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(0) | B(TMP_REG3)); + return push_inst(compiler, (load ? LFDUX : STFDUX) | FD(fpu_reg) | A(TMP_REG3) | B(arg & 0xf)); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); + dst = TMP_FREG1; + } + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); + src = TMP_FREG2; + } + return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src)); + } + + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); + src = dst_fr; + } + + switch (op) { + case SLJIT_FMOV: + if (src != dst_fr && dst_fr != TMP_FREG1) + FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src))); + break; + case SLJIT_FNEG: + FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src))); + break; + case SLJIT_FABS: + FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src))); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_fr; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; + + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); + src2 = TMP_FREG2; + } + + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (op) { + case SLJIT_FADD: + FAIL_IF(push_inst(compiler, FADD | FD(dst_fr) | FA(src1) | FB(src2))); + break; + + case SLJIT_FSUB: + FAIL_IF(push_inst(compiler, FSUB | FD(dst_fr) | FA(src1) | FB(src2))); + break; + + case SLJIT_FMUL: + FAIL_IF(push_inst(compiler, FMUL | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); + break; + + case SLJIT_FDIV: + FAIL_IF(push_inst(compiler, FDIV | FD(dst_fr) | FA(src1) | FB(src2))); + break; + } + + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Other instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + return push_inst(compiler, MFLR | D(dst)); + else if (dst & SLJIT_MEM) { + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + FAIL_IF(push_inst(compiler, MTLR | S(src))); + else { + if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + else if (src & SLJIT_IMM) + FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); + FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); + } + return push_inst(compiler, BLR); +} + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + struct sljit_label *label; + + CHECK_ERROR_PTR(); + check_sljit_emit_label(compiler); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + return label; +} + +static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, int type) +{ + switch (type) { + case SLJIT_C_EQUAL: + return (12 << 21) | (2 << 16); + + case SLJIT_C_NOT_EQUAL: + return (4 << 21) | (2 << 16); + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return (12 << 21) | ((4 + 0) << 16); + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return (4 << 21) | ((4 + 0) << 16); + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return (12 << 21) | ((4 + 1) << 16); + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return (4 << 21) | ((4 + 1) << 16); + + case SLJIT_C_SIG_LESS: + return (12 << 21) | (0 << 16); + + case SLJIT_C_SIG_GREATER_EQUAL: + return (4 << 21) | (0 << 16); + + case SLJIT_C_SIG_GREATER: + return (12 << 21) | (1 << 16); + + case SLJIT_C_SIG_LESS_EQUAL: + return (4 << 21) | (1 << 16); + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + return (12 << 21) | (3 << 16); + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + return (4 << 21) | (3 << 16); + + case SLJIT_C_FLOAT_EQUAL: + return (12 << 21) | ((4 + 2) << 16); + + case SLJIT_C_FLOAT_NOT_EQUAL: + return (4 << 21) | ((4 + 2) << 16); + + case SLJIT_C_FLOAT_NAN: + return (12 << 21) | ((4 + 3) << 16); + + case SLJIT_C_FLOAT_NOT_NAN: + return (4 << 21) | ((4 + 3) << 16); + + default: + SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); + return (20 << 21); + } +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + struct sljit_jump *jump; + sljit_ins bo_bi_flags; + + CHECK_ERROR_PTR(); + check_sljit_emit_jump(compiler, type); + + bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff); + if (!bo_bi_flags) + return NULL; + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF(!jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + /* In PPC, we don't need to touch the arguments. */ + if (type >= SLJIT_JUMP) + jump->flags |= UNCOND_B; + + PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0)); + PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1))); + jump->addr = compiler->size; + PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + sljit_ins bo_bi_flags; + struct sljit_jump *jump = NULL; + int src_r; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + bo_bi_flags = get_bo_bi_flags(compiler, type); + FAIL_IF(!bo_bi_flags); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) + src_r = src; + else if (src & SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF(!jump); + set_jump(jump, compiler, JUMP_ADDR | UNCOND_B); + jump->u.target = srcw; + + FAIL_IF(emit_const(compiler, TMP_REG2, 0)); + src_r = TMP_REG2; + } + else { + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + src_r = TMP_REG2; + } + + FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); + if (jump) + jump->addr = compiler->size; + return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)); +} + +/* Get a bit from CR, all other bits are zeroed. */ +#define GET_CR_BIT(bit, dst) \ + FAIL_IF(push_inst(compiler, MFCR | D(dst))); \ + FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1))); + +#define INVERT_BIT(dst) \ + FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + int reg; + + CHECK_ERROR(); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + + switch (type) { + case SLJIT_C_EQUAL: + GET_CR_BIT(2, reg); + break; + + case SLJIT_C_NOT_EQUAL: + GET_CR_BIT(2, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + GET_CR_BIT(4 + 0, reg); + break; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + GET_CR_BIT(4 + 0, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + GET_CR_BIT(4 + 1, reg); + break; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + GET_CR_BIT(4 + 1, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_SIG_LESS: + GET_CR_BIT(0, reg); + break; + + case SLJIT_C_SIG_GREATER_EQUAL: + GET_CR_BIT(0, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_SIG_GREATER: + GET_CR_BIT(1, reg); + break; + + case SLJIT_C_SIG_LESS_EQUAL: + GET_CR_BIT(1, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + GET_CR_BIT(3, reg); + break; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + GET_CR_BIT(3, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_FLOAT_EQUAL: + GET_CR_BIT(4 + 2, reg); + break; + + case SLJIT_C_FLOAT_NOT_EQUAL: + GET_CR_BIT(4 + 2, reg); + INVERT_BIT(reg); + break; + + case SLJIT_C_FLOAT_NAN: + GET_CR_BIT(4 + 3, reg); + break; + + case SLJIT_C_FLOAT_NOT_NAN: + GET_CR_BIT(4 + 3, reg); + INVERT_BIT(reg); + break; + + default: + SLJIT_ASSERT_STOP(); + break; + } + + if (GET_OPCODE(op) == SLJIT_OR) + return emit_op(compiler, GET_OPCODE(op), GET_FLAGS(op) ? ALT_SET_FLAGS : 0, dst, dstw, dst, dstw, TMP_REG2, 0); + + if (reg == TMP_REG2) + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + struct sljit_const *const_; + int reg; + + CHECK_ERROR_PTR(); + check_sljit_emit_const(compiler, dst, dstw, init_value); + ADJUST_LOCAL_OFFSET(dst, dstw); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; + + PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; +} diff -Nru pcre3-8.12/sljit/sljitNativeX86_32.c pcre3-8.31/sljit/sljitNativeX86_32.c --- pcre3-8.12/sljit/sljitNativeX86_32.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeX86_32.c 2012-04-04 10:28:12.000000000 +0000 @@ -0,0 +1,523 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* x86 32-bit arch dependent functions. */ + +static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm) +{ + sljit_ub *buf; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w)); + FAIL_IF(!buf); + INC_SIZE(1 + sizeof(sljit_w)); + *buf++ = opcode; + *(sljit_w*)buf = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) +{ + if (type == SLJIT_JUMP) { + *code_ptr++ = 0xe9; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + *code_ptr++ = 0xe8; + jump->addr++; + } + else { + *code_ptr++ = 0x0f; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MW; + else + *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4); + code_ptr += 4; + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size; + int locals_offset; + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; + compiler->args = args; + compiler->flags_saved = 0; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0); +#else + size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0); +#endif + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + + INC_SIZE(size); + PUSH_REG(reg_map[TMP_REGISTER]); +#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (args > 0) { + *buf++ = 0x8b; + *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3); + } +#endif + if (saveds > 2) + PUSH_REG(reg_map[SLJIT_SAVED_REG3]); + if (saveds > 1) + PUSH_REG(reg_map[SLJIT_SAVED_REG2]); + if (saveds > 0) + PUSH_REG(reg_map[SLJIT_SAVED_REG1]); + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (args > 0) { + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3]; + } + if (args > 1) { + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2]; + } + if (args > 2) { + *buf++ = 0x8b; + *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3); + *buf++ = 0x24; + *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */ + } +#else + if (args > 0) { + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 2; + } + if (args > 1) { + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 3; + } + if (args > 2) { + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 4; + } +#endif + + locals_offset = 2 * sizeof(sljit_uw); + compiler->temporaries_start = locals_offset; + if (temporaries > 3) + locals_offset += (temporaries - 3) * sizeof(sljit_uw); + compiler->saveds_start = locals_offset; + if (saveds > 3) + locals_offset += (saveds - 3) * sizeof(sljit_uw); + compiler->locals_offset = locals_offset; + local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); + +#ifdef _WIN32 + if (local_size > 1024) { + FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size)); + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + } +#endif + + compiler->local_size = local_size; + SLJIT_ASSERT(local_size > 0); + return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d, + SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int locals_offset; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; + compiler->args = args; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + locals_offset = 2 * sizeof(sljit_uw); + compiler->temporaries_start = locals_offset; + if (temporaries > 3) + locals_offset += (temporaries - 3) * sizeof(sljit_uw); + compiler->saveds_start = locals_offset; + if (saveds > 3) + locals_offset += (saveds - 3) * sizeof(sljit_uw); + compiler->locals_offset = locals_offset; + compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + int size; + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + SLJIT_ASSERT(compiler->args >= 0); + ADJUST_LOCAL_OFFSET(src, srcw); + + compiler->flags_saved = 0; + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + SLJIT_ASSERT(compiler->local_size > 0); + FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, + SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); + + size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3); +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (compiler->args > 2) + size += 2; +#else + if (compiler->args > 0) + size += 2; +#endif + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + + INC_SIZE(size); + + if (compiler->saveds > 0) + POP_REG(reg_map[SLJIT_SAVED_REG1]); + if (compiler->saveds > 1) + POP_REG(reg_map[SLJIT_SAVED_REG2]); + if (compiler->saveds > 2) + POP_REG(reg_map[SLJIT_SAVED_REG3]); + POP_REG(reg_map[TMP_REGISTER]); +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (compiler->args > 2) + RETN(sizeof(sljit_w)); + else + RET(); +#else + if (compiler->args > 0) + RETN(compiler->args * sizeof(sljit_w)); + else + RET(); +#endif + + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +/* Size contains the flags as well. */ +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, + /* The register or immediate operand. */ + int a, sljit_w imma, + /* The general operand (not immediate). */ + int b, sljit_w immb) +{ + sljit_ub *buf; + sljit_ub *buf_ptr; + int flags = size & ~0xf; + int inst_size; + + /* Both cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); + /* Size flags not allowed for typed instructions. */ + SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); + /* Both size flags cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + /* SSE2 and immediate is not possible. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); +#endif + + size &= 0xf; + inst_size = size; + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + inst_size++; +#endif + if (flags & EX86_PREF_66) + inst_size++; + + /* Calculate size of b. */ + inst_size += 1; /* mod r/m byte. */ + if (b & SLJIT_MEM) { + if ((b & 0x0f) == SLJIT_UNUSED) + inst_size += sizeof(sljit_w); + else if (immb != 0 && !(b & 0xf0)) { + /* Immediate operand. */ + if (immb <= 127 && immb >= -128) + inst_size += sizeof(sljit_b); + else + inst_size += sizeof(sljit_w); + } + + if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) + b |= SLJIT_LOCALS_REG << 4; + + if ((b & 0xf0) != SLJIT_UNUSED) + inst_size += 1; /* SIB byte. */ + } + + /* Calculate size of a. */ + if (a & SLJIT_IMM) { + if (flags & EX86_BIN_INS) { + if (imma <= 127 && imma >= -128) { + inst_size += 1; + flags |= EX86_BYTE_ARG; + } else + inst_size += 4; + } + else if (flags & EX86_SHIFT_INS) { + imma &= 0x1f; + if (imma != 1) { + inst_size ++; + flags |= EX86_BYTE_ARG; + } + } else if (flags & EX86_BYTE_ARG) + inst_size++; + else if (flags & EX86_HALF_ARG) + inst_size += sizeof(short); + else + inst_size += sizeof(sljit_w); + } + else + SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!buf); + + /* Encoding the byte. */ + INC_SIZE(inst_size); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + *buf++ = 0xf2; +#endif + if (flags & EX86_PREF_66) + *buf++ = 0x66; + + buf_ptr = buf + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; + + if ((a & SLJIT_IMM) || (a == 0)) + *buf_ptr = 0; +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + else if (!(flags & EX86_SSE2)) + *buf_ptr = reg_map[a] << 3; + else + *buf_ptr = a << 3; +#else + else + *buf_ptr = reg_map[a] << 3; +#endif + } + else { + if (a & SLJIT_IMM) { + if (imma == 1) + *buf = 0xd1; + else + *buf = 0xc1; + } else + *buf = 0xd3; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b); +#else + *buf_ptr++ |= 0xc0 + reg_map[b]; +#endif + else if ((b & 0x0f) != SLJIT_UNUSED) { + if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr |= 0x40; + else + *buf_ptr |= 0x80; + } + + if ((b & 0xf0) == SLJIT_UNUSED) + *buf_ptr++ |= reg_map[b & 0x0f]; + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3); + } + + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr++ = immb; /* 8 bit displacement. */ + else { + *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_w); + } + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6); + } + } + else { + *buf_ptr++ |= 0x05; + *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_w); + } + + if (a & SLJIT_IMM) { + if (flags & EX86_BYTE_ARG) + *buf_ptr = imma; + else if (flags & EX86_HALF_ARG) + *(short*)buf_ptr = imma; + else if (!(flags & EX86_SHIFT_INS)) + *(sljit_w*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) +{ + sljit_ub *buf; + +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + FAIL_IF(!buf); + INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); + + if (type >= SLJIT_CALL3) + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1]; +#else + buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1); + FAIL_IF(!buf); + INC_SIZE(type - SLJIT_CALL0); + if (type >= SLJIT_CALL3) + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + if (type >= SLJIT_CALL2) + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]); + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]); +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1); + POP_REG(reg_map[dst]); + return SLJIT_SUCCESS; + } + else if (dst & SLJIT_MEM) { + buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!buf); + *buf++ = 0x8f; + return SLJIT_SUCCESS; + } + + /* For UNUSED dst. Uncommon, but possible. */ + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1); + POP_REG(reg_map[TMP_REGISTER]); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1 + 1); + PUSH_REG(reg_map[src]); + } + else if (src & SLJIT_MEM) { + buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!buf); + *buf++ = 0xff; + *buf |= 6 << 3; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + } + else { + /* SLJIT_IMM. */ + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!buf); + + INC_SIZE(5 + 1); + *buf++ = 0x68; + *(sljit_w*)buf = srcw; + buf += sizeof(sljit_w); + } + + RET(); + return SLJIT_SUCCESS; +} diff -Nru pcre3-8.12/sljit/sljitNativeX86_64.c pcre3-8.31/sljit/sljitNativeX86_64.c --- pcre3-8.12/sljit/sljitNativeX86_64.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeX86_64.c 2012-04-04 10:28:12.000000000 +0000 @@ -0,0 +1,790 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* x86 64-bit arch dependent functions. */ + +static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm) +{ + sljit_ub *buf; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w)); + FAIL_IF(!buf); + INC_SIZE(2 + sizeof(sljit_w)); + *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + *buf++ = 0xb8 + (reg_map[reg] & 0x7); + *(sljit_w*)buf = imm; + return SLJIT_SUCCESS; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) +{ + if (type < SLJIT_JUMP) { + *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10; + *code_ptr++ = 10 + 3; + } + + SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first); + *code_ptr++ = REX_W | REX_B; + *code_ptr++ = 0xb8 + 1; + jump->addr = (sljit_uw)code_ptr; + + if (jump->flags & JUMP_LABEL) + jump->flags |= PATCH_MD; + else + *(sljit_w*)code_ptr = jump->u.target; + + code_ptr += sizeof(sljit_w); + *code_ptr++ = REX_B; + *code_ptr++ = 0xff; + *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */; + + return code_ptr; +} + +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type) +{ + sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw)); + + if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) { + *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; + *(sljit_w*)code_ptr = delta; + } + else { + SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); + *code_ptr++ = REX_W | REX_B; + *code_ptr++ = 0xb8 + 1; + *(sljit_w*)code_ptr = addr; + code_ptr += sizeof(sljit_w); + *code_ptr++ = REX_B; + *code_ptr++ = 0xff; + *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */; + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int size, pushed_size; + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; + compiler->flags_saved = 0; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + size = saveds; + /* Including the return address saved by the call instruction. */ + pushed_size = (saveds + 1) * sizeof(sljit_w); +#ifndef _WIN64 + if (saveds >= 2) + size += saveds - 1; +#else + if (saveds >= 4) + size += saveds - 3; + if (temporaries >= 5) { + size += (5 - 4) * 2; + pushed_size += sizeof(sljit_w); + } +#endif + size += args * 3; + if (size > 0) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + + INC_SIZE(size); + if (saveds >= 5) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg); + *buf++ = REX_B; + PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]); + } + if (saveds >= 4) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg); + *buf++ = REX_B; + PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]); + } + if (saveds >= 3) { +#ifndef _WIN64 + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg); + *buf++ = REX_B; +#else + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg); +#endif + PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]); + } + if (saveds >= 2) { +#ifndef _WIN64 + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg); + *buf++ = REX_B; +#else + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg); +#endif + PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]); + } + if (saveds >= 1) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg); + PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]); + } +#ifdef _WIN64 + if (temporaries >= 5) { + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg); + *buf++ = REX_B; + PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); + } +#endif + +#ifndef _WIN64 + if (args > 0) { + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7; + } + if (args > 1) { + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6; + } + if (args > 2) { + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2; + } +#else + if (args > 0) { + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1; + } + if (args > 1) { + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2; + } + if (args > 2) { + *buf++ = REX_W | REX_B; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0; + } +#endif + } + + local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; + compiler->local_size = local_size; +#ifdef _WIN64 + if (local_size > 1024) { + /* Allocate stack for the callback, which grows the stack. */ + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); + INC_SIZE(4); + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (5 << 3) | 4; + /* Pushed size must be divisible by 8. */ + SLJIT_ASSERT(!(pushed_size & 0x7)); + if (pushed_size & 0x8) { + *buf++ = 5 * sizeof(sljit_w); + local_size -= 5 * sizeof(sljit_w); + } else { + *buf++ = 4 * sizeof(sljit_w); + local_size -= 4 * sizeof(sljit_w); + } + FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size)); + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + } +#endif + SLJIT_ASSERT(local_size > 0); + if (local_size <= 127) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); + INC_SIZE(4); + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (5 << 3) | 4; + *buf++ = local_size; + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!buf); + INC_SIZE(7); + *buf++ = REX_W; + *buf++ = 0x81; + *buf++ = 0xc0 | (5 << 3) | 4; + *(sljit_hw*)buf = local_size; + buf += sizeof(sljit_hw); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) +{ + int pushed_size; + + CHECK_ERROR_VOID(); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); + + compiler->temporaries = temporaries; + compiler->saveds = saveds; +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->logical_local_size = local_size; +#endif + + /* Including the return address saved by the call instruction. */ + pushed_size = (saveds + 1) * sizeof(sljit_w); +#ifdef _WIN64 + if (temporaries >= 5) + pushed_size += sizeof(sljit_w); +#endif + compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) +{ + int size; + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + compiler->flags_saved = 0; + FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); + + SLJIT_ASSERT(compiler->local_size > 0); + if (compiler->local_size <= 127) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); + INC_SIZE(4); + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (0 << 3) | 4; + *buf = compiler->local_size; + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!buf); + INC_SIZE(7); + *buf++ = REX_W; + *buf++ = 0x81; + *buf++ = 0xc0 | (0 << 3) | 4; + *(sljit_hw*)buf = compiler->local_size; + } + + size = 1 + compiler->saveds; +#ifndef _WIN64 + if (compiler->saveds >= 2) + size += compiler->saveds - 1; +#else + if (compiler->saveds >= 4) + size += compiler->saveds - 3; + if (compiler->temporaries >= 5) + size += (5 - 4) * 2; +#endif + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + + INC_SIZE(size); + +#ifdef _WIN64 + if (compiler->temporaries >= 5) { + *buf++ = REX_B; + POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); + } +#endif + if (compiler->saveds >= 1) + POP_REG(reg_map[SLJIT_SAVED_REG1]); + if (compiler->saveds >= 2) { +#ifndef _WIN64 + *buf++ = REX_B; +#endif + POP_REG(reg_lmap[SLJIT_SAVED_REG2]); + } + if (compiler->saveds >= 3) { +#ifndef _WIN64 + *buf++ = REX_B; +#endif + POP_REG(reg_lmap[SLJIT_SAVED_REG3]); + } + if (compiler->saveds >= 4) { + *buf++ = REX_B; + POP_REG(reg_lmap[SLJIT_SAVED_EREG1]); + } + if (compiler->saveds >= 5) { + *buf++ = REX_B; + POP_REG(reg_lmap[SLJIT_SAVED_EREG2]); + } + + RET(); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm) +{ + sljit_ub *buf; + + if (rex != 0) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw)); + FAIL_IF(!buf); + INC_SIZE(2 + sizeof(sljit_hw)); + *buf++ = rex; + *buf++ = opcode; + *(sljit_hw*)buf = imm; + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw)); + FAIL_IF(!buf); + INC_SIZE(1 + sizeof(sljit_hw)); + *buf++ = opcode; + *(sljit_hw*)buf = imm; + } + return SLJIT_SUCCESS; +} + +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, + /* The register or immediate operand. */ + int a, sljit_w imma, + /* The general operand (not immediate). */ + int b, sljit_w immb) +{ + sljit_ub *buf; + sljit_ub *buf_ptr; + sljit_ub rex = 0; + int flags = size & ~0xf; + int inst_size; + + /* The immediate operand must be 32 bit. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); + /* Both cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); + /* Size flags not allowed for typed instructions. */ + SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0); + /* Both size flags cannot be switched on. */ + SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + /* SSE2 and immediate is not possible. */ + SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); +#endif + + size &= 0xf; + inst_size = size; + + if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) { + if (emit_load_imm64(compiler, TMP_REG3, immb)) + return NULL; + immb = 0; + if (b & 0xf) + b |= TMP_REG3 << 4; + else + b |= TMP_REG3; + } + + if (!compiler->mode32 && !(flags & EX86_NO_REXW)) + rex |= REX_W; + else if (flags & EX86_REX) + rex |= REX; + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + inst_size++; +#endif + if (flags & EX86_PREF_66) + inst_size++; + + /* Calculate size of b. */ + inst_size += 1; /* mod r/m byte. */ + if (b & SLJIT_MEM) { + if ((b & 0x0f) == SLJIT_UNUSED) + inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */ + else { + if (reg_map[b & 0x0f] >= 8) + rex |= REX_B; + if (immb != 0 && !(b & 0xf0)) { + /* Immediate operand. */ + if (immb <= 127 && immb >= -128) + inst_size += sizeof(sljit_b); + else + inst_size += sizeof(sljit_hw); + } + } + + if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) + b |= SLJIT_LOCALS_REG << 4; + + if ((b & 0xf0) != SLJIT_UNUSED) { + inst_size += 1; /* SIB byte. */ + if (reg_map[(b >> 4) & 0x0f] >= 8) + rex |= REX_X; + } + } +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + else if (!(flags & EX86_SSE2) && reg_map[b] >= 8) + rex |= REX_B; +#else + else if (reg_map[b] >= 8) + rex |= REX_B; +#endif + + if (a & SLJIT_IMM) { + if (flags & EX86_BIN_INS) { + if (imma <= 127 && imma >= -128) { + inst_size += 1; + flags |= EX86_BYTE_ARG; + } else + inst_size += 4; + } + else if (flags & EX86_SHIFT_INS) { + imma &= compiler->mode32 ? 0x1f : 0x3f; + if (imma != 1) { + inst_size ++; + flags |= EX86_BYTE_ARG; + } + } else if (flags & EX86_BYTE_ARG) + inst_size++; + else if (flags & EX86_HALF_ARG) + inst_size += sizeof(short); + else + inst_size += sizeof(sljit_hw); + } + else { + SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); + /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (!(flags & EX86_SSE2) && reg_map[a] >= 8) + rex |= REX_R; +#else + if (reg_map[a] >= 8) + rex |= REX_R; +#endif + } + + if (rex) + inst_size++; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!buf); + + /* Encoding the byte. */ + INC_SIZE(inst_size); +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + if (flags & EX86_PREF_F2) + *buf++ = 0xf2; +#endif + if (flags & EX86_PREF_66) + *buf++ = 0x66; + if (rex) + *buf++ = rex; + buf_ptr = buf + size; + + /* Encode mod/rm byte. */ + if (!(flags & EX86_SHIFT_INS)) { + if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; + + if ((a & SLJIT_IMM) || (a == 0)) + *buf_ptr = 0; +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + else if (!(flags & EX86_SSE2)) + *buf_ptr = reg_lmap[a] << 3; + else + *buf_ptr = a << 3; +#else + else + *buf_ptr = reg_lmap[a] << 3; +#endif + } + else { + if (a & SLJIT_IMM) { + if (imma == 1) + *buf = 0xd1; + else + *buf = 0xc1; + } else + *buf = 0xd3; + *buf_ptr = 0; + } + + if (!(b & SLJIT_MEM)) +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b); +#else + *buf_ptr++ |= 0xc0 + reg_lmap[b]; +#endif + else if ((b & 0x0f) != SLJIT_UNUSED) { + if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr |= 0x40; + else + *buf_ptr |= 0x80; + } + + if ((b & 0xf0) == SLJIT_UNUSED) + *buf_ptr++ |= reg_lmap[b & 0x0f]; + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3); + } + + if (immb != 0) { + if (immb <= 127 && immb >= -128) + *buf_ptr++ = immb; /* 8 bit displacement. */ + else { + *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_hw); + } + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6); + } + } + else { + *buf_ptr++ |= 0x04; + *buf_ptr++ = 0x25; + *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_hw); + } + + if (a & SLJIT_IMM) { + if (flags & EX86_BYTE_ARG) + *buf_ptr = imma; + else if (flags & EX86_HALF_ARG) + *(short*)buf_ptr = imma; + else if (!(flags & EX86_SHIFT_INS)) + *(sljit_hw*)buf_ptr = imma; + } + + return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); +} + +/* --------------------------------------------------------------------- */ +/* Call / return instructions */ +/* --------------------------------------------------------------------- */ + +static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) +{ + sljit_ub *buf; + +#ifndef _WIN64 + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!buf); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; + } + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; +#else + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!buf); + INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); + if (type >= SLJIT_CALL3) { + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; + } + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) +{ + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_fast_enter(compiler, dst, dstw); + ADJUST_LOCAL_OFFSET(dst, dstw); + + /* For UNUSED dst. Uncommon, but possible. */ + if (dst == SLJIT_UNUSED) + dst = TMP_REGISTER; + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + if (reg_map[dst] < 8) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1); + POP_REG(reg_lmap[dst]); + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); + + INC_SIZE(2); + *buf++ = REX_B; + POP_REG(reg_lmap[dst]); + } + } + else if (dst & SLJIT_MEM) { + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!buf); + *buf++ = 0x8f; + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) +{ + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_fast_return(compiler, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw)); + src = TMP_REGISTER; + } + + if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { + if (reg_map[src] < 8) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1 + 1); + PUSH_REG(reg_lmap[src]); + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + FAIL_IF(!buf); + + INC_SIZE(2 + 1); + *buf++ = REX_B; + PUSH_REG(reg_lmap[src]); + } + } + else if (src & SLJIT_MEM) { + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!buf); + *buf++ = 0xff; + *buf |= 6 << 3; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + } + else { + SLJIT_ASSERT(IS_HALFWORD(srcw)); + /* SLJIT_IMM. */ + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!buf); + + INC_SIZE(5 + 1); + *buf++ = 0x68; + *(sljit_hw*)buf = srcw; + buf += sizeof(sljit_hw); + } + + RET(); + return SLJIT_SUCCESS; +} + + +/* --------------------------------------------------------------------- */ +/* Extend input */ +/* --------------------------------------------------------------------- */ + +static int emit_mov_int(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + int dst_r; + + compiler->mode32 = 0; + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; + return SLJIT_SUCCESS; + } + return emit_load_imm64(compiler, dst, srcw); + } + compiler->mode32 = 1; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; + compiler->mode32 = 0; + return SLJIT_SUCCESS; + } + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3)) + dst_r = src; + else { + if (sign) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x63; + } else { + compiler->mode32 = 1; + FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); + compiler->mode32 = 0; + } + } + + if (dst & SLJIT_MEM) { + compiler->mode32 = 1; + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; + compiler->mode32 = 0; + } + + return SLJIT_SUCCESS; +} diff -Nru pcre3-8.12/sljit/sljitNativeX86_common.c pcre3-8.31/sljit/sljitNativeX86_common.c --- pcre3-8.12/sljit/sljitNativeX86_common.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitNativeX86_common.c 2012-05-14 11:01:04.000000000 +0000 @@ -0,0 +1,2683 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() +{ + return "x86" SLJIT_CPUINFO; +} + +/* + 32b register indexes: + 0 - EAX + 1 - ECX + 2 - EDX + 3 - EBX + 4 - none + 5 - EBP + 6 - ESI + 7 - EDI +*/ + +/* + 64b register indexes: + 0 - RAX + 1 - RCX + 2 - RDX + 3 - RBX + 4 - none + 5 - RBP + 6 - RSI + 7 - RDI + 8 - R8 - From now on REX prefix is required + 9 - R9 + 10 - R10 + 11 - R11 + 12 - R12 + 13 - R13 + 14 - R14 + 15 - R15 +*/ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + +/* Last register + 1. */ +#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) + +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { + 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5 +}; + +#define CHECK_EXTRA_REGS(p, w, do) \ + if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \ + w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \ + p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ + do; \ + } \ + else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \ + w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \ + p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ + do; \ + } + +#else /* SLJIT_CONFIG_X86_32 */ + +/* Last register + 1. */ +#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) +#define TMP_REG2 (SLJIT_NO_REGISTERS + 2) +#define TMP_REG3 (SLJIT_NO_REGISTERS + 3) + +/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present + Note: avoid to use r12 and r13 for memory addessing + therefore r12 is better for SAVED_EREG than SAVED_REG. */ +#ifndef _WIN64 +/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { + 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9 +}; +/* low-map. reg_map & 0x7. */ +static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { + 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1 +}; +#else +/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { + 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9 +}; +/* low-map. reg_map & 0x7. */ +static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { + 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1 +}; +#endif + +#define REX_W 0x48 +#define REX_R 0x44 +#define REX_X 0x42 +#define REX_B 0x41 +#define REX 0x40 + +typedef unsigned int sljit_uhw; +typedef int sljit_hw; + +#define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll) +#define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll) + +#define CHECK_EXTRA_REGS(p, w, do) + +#endif /* SLJIT_CONFIG_X86_32 */ + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) +#define TMP_FREG (SLJIT_FLOAT_REG4 + 1) +#endif + +/* Size flags for emit_x86_instruction: */ +#define EX86_BIN_INS 0x0010 +#define EX86_SHIFT_INS 0x0020 +#define EX86_REX 0x0040 +#define EX86_NO_REXW 0x0080 +#define EX86_BYTE_ARG 0x0100 +#define EX86_HALF_ARG 0x0200 +#define EX86_PREF_66 0x0400 + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) +#define EX86_PREF_F2 0x0800 +#define EX86_SSE2 0x1000 +#endif + +#define INC_SIZE(s) (*buf++ = (s), compiler->size += (s)) +#define INC_CSIZE(s) (*code++ = (s), compiler->size += (s)) + +#define PUSH_REG(r) (*buf++ = (0x50 + (r))) +#define POP_REG(r) (*buf++ = (0x58 + (r))) +#define RET() (*buf++ = (0xc3)) +#define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0) +/* r32, r/m32 */ +#define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm)) + +static sljit_ub get_jump_code(int type) +{ + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_FLOAT_EQUAL: + return 0x84; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + return 0x85; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + return 0x82; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + return 0x83; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + return 0x87; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + return 0x86; + + case SLJIT_C_SIG_LESS: + return 0x8c; + + case SLJIT_C_SIG_GREATER_EQUAL: + return 0x8d; + + case SLJIT_C_SIG_GREATER: + return 0x8f; + + case SLJIT_C_SIG_LESS_EQUAL: + return 0x8e; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + return 0x80; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + return 0x81; + + case SLJIT_C_FLOAT_NAN: + return 0x8a; + + case SLJIT_C_FLOAT_NOT_NAN: + return 0x8b; + } + return 0; +} + +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type); +#endif + +static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type) +{ + int short_jump; + sljit_uw label_addr; + + if (jump->flags & JUMP_LABEL) + label_addr = (sljit_uw)(code + jump->u.label->size); + else + label_addr = jump->u.target; + short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll) + return generate_far_jump_code(jump, code_ptr, type); +#endif + + if (type == SLJIT_JUMP) { + if (short_jump) + *code_ptr++ = 0xeb; + else + *code_ptr++ = 0xe9; + jump->addr++; + } + else if (type >= SLJIT_FAST_CALL) { + short_jump = 0; + *code_ptr++ = 0xe8; + jump->addr++; + } + else if (short_jump) { + *code_ptr++ = get_jump_code(type) - 0x10; + jump->addr++; + } + else { + *code_ptr++ = 0x0f; + *code_ptr++ = get_jump_code(type); + jump->addr += 2; + } + + if (short_jump) { + jump->flags |= PATCH_MB; + code_ptr += sizeof(sljit_b); + } else { + jump->flags |= PATCH_MW; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code_ptr += sizeof(sljit_w); +#else + code_ptr += sizeof(sljit_hw); +#endif + } + + return code_ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) +{ + struct sljit_memory_fragment *buf; + sljit_ub *code; + sljit_ub *code_ptr; + sljit_ub *buf_ptr; + sljit_ub *buf_end; + sljit_ub len; + + struct sljit_label *label; + struct sljit_jump *jump; + struct sljit_const *const_; + + CHECK_ERROR_PTR(); + check_sljit_generate_code(compiler); + reverse_buf(compiler); + + /* Second code generation pass. */ + code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); + PTR_FAIL_WITH_EXEC_IF(code); + buf = compiler->buf; + + code_ptr = code; + label = compiler->labels; + jump = compiler->jumps; + const_ = compiler->consts; + do { + buf_ptr = buf->memory; + buf_end = buf_ptr + buf->used_size; + do { + len = *buf_ptr++; + if (len > 0) { + /* The code is already generated. */ + SLJIT_MEMMOVE(code_ptr, buf_ptr, len); + code_ptr += len; + buf_ptr += len; + } + else { + if (*buf_ptr >= 4) { + jump->addr = (sljit_uw)code_ptr; + if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) + code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4); + else + code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4); + jump = jump->next; + } + else if (*buf_ptr == 0) { + label->addr = (sljit_uw)code_ptr; + label->size = code_ptr - code; + label = label->next; + } + else if (*buf_ptr == 1) { + const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w); + const_ = const_->next; + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; + buf_ptr++; + *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w)); + code_ptr += sizeof(sljit_w); + buf_ptr += sizeof(sljit_w) - 1; +#else + code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr); + buf_ptr += sizeof(sljit_w); +#endif + } + buf_ptr++; + } + } while (buf_ptr < buf_end); + SLJIT_ASSERT(buf_ptr == buf_end); + buf = buf->next; + } while (buf); + + SLJIT_ASSERT(!label); + SLJIT_ASSERT(!jump); + SLJIT_ASSERT(!const_); + + jump = compiler->jumps; + while (jump) { + if (jump->flags & PATCH_MB) { + SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127); + *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))); + } else if (jump->flags & PATCH_MW) { + if (jump->flags & JUMP_LABEL) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w))); +#else + SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); + *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))); +#endif + } + else { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w))); +#else + SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); + *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw))); +#endif + } + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + else if (jump->flags & PATCH_MD) + *(sljit_w*)jump->addr = jump->u.label->addr; +#endif + + jump = jump->next; + } + + /* Maybe we waste some space because of short jumps. */ + SLJIT_ASSERT(code_ptr <= code + compiler->size); + compiler->error = SLJIT_ERR_COMPILED; + compiler->executable_size = compiler->size; + return (void*)code; +} + +/* --------------------------------------------------------------------- */ +/* Operators */ +/* --------------------------------------------------------------------- */ + +static int emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +static int emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +static int emit_mov(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw); + +static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler) +{ + sljit_ub *buf; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!buf); + INC_SIZE(5); +#else + buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!buf); + INC_SIZE(6); + *buf++ = REX_W; +#endif + *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */ + *buf++ = 0x64; + *buf++ = 0x24; + *buf++ = (sljit_ub)sizeof(sljit_w); + *buf++ = 0x9c; /* pushfd / pushfq */ + compiler->flags_saved = 1; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags) +{ + sljit_ub *buf; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!buf); + INC_SIZE(5); + *buf++ = 0x9d; /* popfd */ +#else + buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!buf); + INC_SIZE(6); + *buf++ = 0x9d; /* popfq */ + *buf++ = REX_W; +#endif + *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */ + *buf++ = 0x64; + *buf++ = 0x24; + *buf++ = (sljit_ub)-(int)sizeof(sljit_w); + compiler->flags_saved = keep_flags; + return SLJIT_SUCCESS; +} + +#ifdef _WIN32 +#include + +static void SLJIT_CALL sljit_grow_stack(sljit_w local_size) +{ + /* Workaround for calling the internal _chkstk() function on Windows. + This function touches all 4k pages belongs to the requested stack space, + which size is passed in local_size. This is necessary on Windows where + the stack can only grow in 4k steps. However, this function just burn + CPU cycles if the stack is large enough, but you don't know it in advance. + I think this is a bad design even if it has some reasons. */ + alloca(local_size); +} + +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#include "sljitNativeX86_32.c" +#else +#include "sljitNativeX86_64.c" +#endif + +static int emit_mov(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + + if (dst == SLJIT_UNUSED) { + /* No destination, doesn't need to setup flags. */ + if (src & SLJIT_MEM) { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; + } + return SLJIT_SUCCESS; + } + if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; + return SLJIT_SUCCESS; + } + if (src & SLJIT_IMM) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); +#else + if (!compiler->mode32) { + if (NOT_HALFWORD(srcw)) + return emit_load_imm64(compiler, dst, srcw); + } + else + return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw); +#endif + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (!compiler->mode32 && NOT_HALFWORD(srcw)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw)); + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; + return SLJIT_SUCCESS; + } +#endif + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; + return SLJIT_SUCCESS; + } + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; + return SLJIT_SUCCESS; + } + + /* Memory to memory move. Requires two instruction. */ + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; + return SLJIT_SUCCESS; +} + +#define EMIT_MOV(compiler, dst, dstw, src, srcw) \ + FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) +{ + sljit_ub *buf; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + int size; +#endif + + CHECK_ERROR(); + check_sljit_emit_op0(compiler, op); + + switch (GET_OPCODE(op)) { + case SLJIT_BREAKPOINT: + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + *buf = 0xcc; + break; + case SLJIT_NOP: + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + *buf = 0x90; + break; + case SLJIT_UMUL: + case SLJIT_SMUL: + case SLJIT_UDIV: + case SLJIT_SDIV: + compiler->flags_saved = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#ifdef _WIN64 + SLJIT_COMPILE_ASSERT( + reg_map[SLJIT_TEMPORARY_REG1] == 0 + && reg_map[SLJIT_TEMPORARY_REG2] == 2 + && reg_map[TMP_REGISTER] > 7, + invalid_register_assignment_for_div_mul); +#else + SLJIT_COMPILE_ASSERT( + reg_map[SLJIT_TEMPORARY_REG1] == 0 + && reg_map[SLJIT_TEMPORARY_REG2] < 7 + && reg_map[TMP_REGISTER] == 2, + invalid_register_assignment_for_div_mul); +#endif + compiler->mode32 = op & SLJIT_INT_OP; +#endif + + op = GET_OPCODE(op); + if (op == SLJIT_UDIV) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); + buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0); +#else + buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); +#endif + FAIL_IF(!buf); + *buf = 0x33; + } + + if (op == SLJIT_SDIV) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); +#endif + + /* CDQ instruction */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + *buf = 0x99; +#else + if (compiler->mode32) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); + *buf = 0x99; + } else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); + INC_SIZE(2); + *buf++ = REX_W; + *buf = 0x99; + } +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); + INC_SIZE(2); + *buf++ = 0xf7; + *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]); +#else +#ifdef _WIN64 + size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; +#else + size = (!compiler->mode32) ? 3 : 2; +#endif + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + INC_SIZE(size); +#ifdef _WIN64 + if (!compiler->mode32) + *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0); + else if (op >= SLJIT_UDIV) + *buf++ = REX_B; + *buf++ = 0xf7; + *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]); +#else + if (!compiler->mode32) + *buf++ = REX_W; + *buf++ = 0xf7; + *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2]; +#endif +#endif + switch (op) { + case SLJIT_UMUL: + *buf |= 4 << 3; + break; + case SLJIT_SMUL: + *buf |= 5 << 3; + break; + case SLJIT_UDIV: + *buf |= 6 << 3; + break; + case SLJIT_SDIV: + *buf |= 7 << 3; + break; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) + EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0); +#endif + break; + } + + return SLJIT_SUCCESS; +} + +#define ENCODE_PREFIX(prefix) \ + do { \ + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + FAIL_IF(!code); \ + INC_CSIZE(1); \ + *code = (prefix); \ + } while (0) + +static int emit_mov_byte(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + int dst_r; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + int work_r; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); +#else + return emit_load_imm64(compiler, dst, srcw); +#endif + } + code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc6; + return SLJIT_SUCCESS; + } + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (reg_map[src] >= 4) { + SLJIT_ASSERT(dst_r == TMP_REGISTER); + EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); + } else + dst_r = src; +#else + dst_r = src; +#endif + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) { + /* src, dst are registers. */ + SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER); + if (reg_map[dst] < 4) { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbe : 0xb6; + } + else { + if (dst != src) + EMIT_MOV(compiler, dst, 0, src, 0); + if (sign) { + /* shl reg, 24 */ + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!code); + *code |= 0x4 << 3; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!code); + /* shr/sar reg, 24 */ + *code |= 0x7 << 3; + } + else { + /* and dst, 0xff */ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0); + FAIL_IF(!code); + *(code + 1) |= 0x4 << 3; + } + } + return SLJIT_SUCCESS; + } +#endif + else { + /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ + code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbe : 0xb6; + } + + if (dst & SLJIT_MEM) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_r == TMP_REGISTER) { + /* Find a non-used register, whose reg_map[src] < 4. */ + if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) { + if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4)) + work_r = SLJIT_TEMPORARY_REG3; + else + work_r = SLJIT_TEMPORARY_REG2; + } + else { + if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) + work_r = SLJIT_TEMPORARY_REG1; + else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2) + work_r = SLJIT_TEMPORARY_REG3; + else + work_r = SLJIT_TEMPORARY_REG2; + } + + if (work_r == SLJIT_TEMPORARY_REG1) { + ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); + } + else { + code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!code); + *code = 0x87; + } + + code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; + + if (work_r == SLJIT_TEMPORARY_REG1) { + ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); + } + else { + code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!code); + *code = 0x87; + } + } + else { + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; + } +#else + code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; +#endif + } + + return SLJIT_SUCCESS; +} + +static int emit_mov_half(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + int dst_r; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM)) + return SLJIT_SUCCESS; /* Empty instruction. */ + + if (src & SLJIT_IMM) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); +#else + return emit_load_imm64(compiler, dst, srcw); +#endif + } + code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; + return SLJIT_SUCCESS; + } + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + + if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) + dst_r = src; + else { + code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbf : 0xb7; + } + + if (dst & SLJIT_MEM) { + code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; + } + + return SLJIT_SUCCESS; +} + +static int emit_unary(struct sljit_compiler *compiler, int un_index, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; + return SLJIT_SUCCESS; + } + if (dst == src && dstw == srcw) { + /* Same input and output */ + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; + return SLJIT_SUCCESS; + } + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_MOV(compiler, dst, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; +} + +static int emit_not_with_flags(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x0b; + return SLJIT_SUCCESS; + } + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_MOV(compiler, dst, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!code); + *code = 0x0b; + return SLJIT_SUCCESS; + } + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x0b; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; +} + +static int emit_clz(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + int dst_r; + + SLJIT_UNUSED_ARG(op); + if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + /* Just set the zero flag. */ + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); +#else + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); +#endif + FAIL_IF(!code); + *code |= 0x5 << 3; + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); + src = TMP_REGISTER; + srcw = 0; + } + + code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xbd; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) + dst_r = dst; + else { + /* Find an unused temporary register. */ + if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) + dst_r = SLJIT_TEMPORARY_REG1; + else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4)) + dst_r = SLJIT_TEMPORARY_REG2; + else + dst_r = SLJIT_TEMPORARY_REG3; + EMIT_MOV(compiler, dst, dstw, dst_r, 0); + } + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); +#else + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2; + compiler->mode32 = 0; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op & SLJIT_INT_OP; +#endif + + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0x45; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); +#else + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); +#endif + FAIL_IF(!code); + *(code + 1) |= 0x6 << 3; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst & SLJIT_MEM) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x87; + } +#else + if (dst & SLJIT_MEM) + EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0); +#endif + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + sljit_ub* code; + int update = 0; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + int dst_is_ereg = 0; + int src_is_ereg = 0; +#else + #define src_is_ereg 0 +#endif + + CHECK_ERROR(); + check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); + CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op & SLJIT_INT_OP; +#endif + + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { + op = GET_OPCODE(op); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); + if (op >= SLJIT_MOVU) { + update = 1; + op -= 7; + } + + if (src & SLJIT_IMM) { + switch (op) { + case SLJIT_MOV_UB: + srcw = (unsigned char)srcw; + break; + case SLJIT_MOV_SB: + srcw = (signed char)srcw; + break; + case SLJIT_MOV_UH: + srcw = (unsigned short)srcw; + break; + case SLJIT_MOV_SH: + srcw = (signed short)srcw; + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case SLJIT_MOV_UI: + srcw = (unsigned int)srcw; + break; + case SLJIT_MOV_SI: + srcw = (signed int)srcw; + break; +#endif + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg)) + return emit_mov(compiler, dst, dstw, src, srcw); +#endif + } + + if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) { + code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8d; + src &= SLJIT_MEM | 0xf; + srcw = 0; + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) { + SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG)); + dst = TMP_REGISTER; + } +#endif + + switch (op) { + case SLJIT_MOV: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: +#endif + FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); + break; + case SLJIT_MOV_UB: + FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw)); + break; + case SLJIT_MOV_SB: + FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw)); + break; + case SLJIT_MOV_UH: + FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw)); + break; + case SLJIT_MOV_SH: + FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw)); + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case SLJIT_MOV_UI: + FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw)); + break; + case SLJIT_MOV_SI: + FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw)); + break; +#endif + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER) + return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0); +#endif + + if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) { + code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x8d; + } + return SLJIT_SUCCESS; + } + + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + + switch (GET_OPCODE(op)) { + case SLJIT_NOT: + if (SLJIT_UNLIKELY(op & SLJIT_SET_E)) + return emit_not_with_flags(compiler, dst, dstw, src, srcw); + return emit_unary(compiler, 0x2, dst, dstw, src, srcw); + + case SLJIT_NEG: + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_unary(compiler, 0x3, dst, dstw, src, srcw); + + case SLJIT_CLZ: + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_clz(compiler, op, dst, dstw, src, srcw); + } + + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + #undef src_is_ereg +#endif +} + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ + if (IS_HALFWORD(immw) || compiler->mode32) { \ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!code); \ + *(code + 1) |= (_op_imm_); \ + } \ + else { \ + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ + FAIL_IF(!code); \ + *code = (_op_mr_); \ + } + +#define BINARY_EAX_IMM(_op_eax_imm_, immw) \ + FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw)) + +#else + +#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!code); \ + *(code + 1) |= (_op_imm_); + +#define BINARY_EAX_IMM(_op_eax_imm_, immw) \ + FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw)) + +#endif + +static int emit_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + } + else { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + return SLJIT_SUCCESS; + } + + if (dst == src1 && dstw == src1w) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src2w); + } + else { + BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); + } + } + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) { + /* Special exception for sljit_emit_cond_value. */ + code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + return SLJIT_SUCCESS; + } + + /* Only for cumulative operations. */ + if (dst == src2 && dstw == src2w) { + if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src1w); + } + else { + BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); + } + } + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); + FAIL_IF(!code); + *code = op_rm; + } + else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + } + else { + /* This version requires less memory writing. */ + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + } + else { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static int emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + } + else { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + return SLJIT_SUCCESS; + } + + if (dst == src1 && dstw == src1w) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(op_eax_imm, src2w); + } + else { + BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); + } + } + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; + } + return SLJIT_SUCCESS; + } + + /* General version. */ + if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, dst, 0); + } + else { + code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + } + else { + /* This version requires less memory writing. */ + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + if (src2 & SLJIT_IMM) { + BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); + } + else { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; + } + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static int emit_mul(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + int dst_r; + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + + /* Register destination. */ + if (dst_r == src1 && !(src2 & SLJIT_IMM)) { + code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; + } + else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { + code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; + } + else if (src1 & SLJIT_IMM) { + if (src2 & SLJIT_IMM) { + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); + src2 = dst_r; + src2w = 0; + } + + if (src1w <= 127 && src1w >= -128) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x6b; + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!code); + INC_CSIZE(1); + *code = (sljit_b)src1w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_w*)code = src1w; + } +#else + else if (IS_HALFWORD(src1w)) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_hw*)code = (sljit_hw)src1w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); + if (dst_r != src2) + EMIT_MOV(compiler, dst_r, 0, src2, src2w); + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; + } +#endif + } + else if (src2 & SLJIT_IMM) { + /* Note: src1 is NOT immediate. */ + + if (src2w <= 127 && src2w >= -128) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x6b; + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!code); + INC_CSIZE(1); + *code = (sljit_b)src2w; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + else { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_w*)code = src2w; + } +#else + else if (IS_HALFWORD(src2w)) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_hw*)code = (sljit_hw)src2w; + } + else { + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); + if (dst_r != src1) + EMIT_MOV(compiler, dst_r, 0, src1, src1w); + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; + } +#endif + } + else { + /* Neither argument is immediate. */ + if (ADDRESSING_DEPENDS_ON(src2, dst_r)) + dst_r = TMP_REGISTER; + EMIT_MOV(compiler, dst_r, 0, src1, src1w); + code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; + } + + if (dst_r == TMP_REGISTER) + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + + return SLJIT_SUCCESS; +} + +static int emit_lea_binary(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + int dst_r, done = 0; + + /* These cases better be left to handled by normal way. */ + if (dst == src1 && dstw == src1w) + return SLJIT_ERR_UNSUPPORTED; + if (dst == src2 && dstw == src2w) + return SLJIT_ERR_UNSUPPORTED; + + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); + FAIL_IF(!code); + *code = 0x8d; + done = 1; + } +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w); +#else + if (src2 & SLJIT_IMM) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); +#endif + FAIL_IF(!code); + *code = 0x8d; + done = 1; + } + } + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w); +#else + if (src1 & SLJIT_IMM) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); +#endif + FAIL_IF(!code); + *code = 0x8d; + done = 1; + } + } + + if (done) { + if (dst_r == TMP_REGISTER) + return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; + } + return SLJIT_ERR_UNSUPPORTED; +} + +static int emit_cmp_binary(struct sljit_compiler *compiler, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(0x3d, src2w); + return SLJIT_SUCCESS; + } + + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if (src2 & SLJIT_IMM) { + BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0); + } + else { + code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x3b; + } + return SLJIT_SUCCESS; + } + + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) { + code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x39; + return SLJIT_SUCCESS; + } + + if (src2 & SLJIT_IMM) { + if (src1 & SLJIT_IMM) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + src1 = TMP_REGISTER; + src1w = 0; + } + BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w); + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x3b; + } + return SLJIT_SUCCESS; +} + +static int emit_test_binary(struct sljit_compiler *compiler, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { +#else + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { +#endif + BINARY_EAX_IMM(0xa9, src2w); + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { +#else + if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { +#endif + BINARY_EAX_IMM(0xa9, src1w); + return SLJIT_SUCCESS; + } + + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src2w) || compiler->mode32) { + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!code); + *code = 0xf7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); + FAIL_IF(!code); + *code = 0x85; + } +#else + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!code); + *code = 0xf7; +#endif + } + else { + code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x85; + } + return SLJIT_SUCCESS; + } + + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src1w) || compiler->mode32) { + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); + FAIL_IF(!code); + *code = 0xf7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); + FAIL_IF(!code); + *code = 0x85; + } +#else + code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); + FAIL_IF(!code); + *code = 0xf7; +#endif + } + else { + code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x85; + } + return SLJIT_SUCCESS; + } + + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (IS_HALFWORD(src2w) || compiler->mode32) { + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0xf7; + } + else { + FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x85; + } +#else + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0xf7; +#endif + } + else { + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x85; + } + return SLJIT_SUCCESS; +} + +static int emit_shift(struct sljit_compiler *compiler, + sljit_ub mode, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + sljit_ub* code; + + if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { + if (dst == src1 && dstw == src1w) { + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_UNUSED) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; + return SLJIT_SUCCESS; + } + if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + return SLJIT_SUCCESS; + } + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_MOV(compiler, dst, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); + FAIL_IF(!code); + *code |= mode; + return SLJIT_SUCCESS; + } + + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + return SLJIT_SUCCESS; + } + + if (dst == SLJIT_PREF_SHIFT_REG) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + } + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { + if (src1 != dst) + EMIT_MOV(compiler, dst, 0, src1, src1w); + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); + FAIL_IF(!code); + *code |= mode; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + } + else { + /* This case is really difficult, since ecx itself may used for + addressing, and we must ensure to work even in that case. */ + EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0); +#else + /* [esp+0] contains the flags. */ + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w), SLJIT_PREF_SHIFT_REG, 0); +#endif + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0); +#else + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w)); +#endif + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + + return SLJIT_SUCCESS; +} + +static int emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_ub mode, int set_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + /* The CPU does not set flags if the shift count is 0. */ + if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0)) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); +#else + if ((src2w & 0x1f) != 0) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); +#endif + if (!set_flags) + return emit_mov(compiler, dst, dstw, src1, src1w); + /* OR dst, src, 0 */ + return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d, + dst, dstw, src1, src1w, SLJIT_IMM, 0); + } + + if (!set_flags) + return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); + + if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)) + FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); + + FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) + return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + CHECK_ERROR(); + check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + ADJUST_LOCAL_OFFSET(dst, dstw); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + CHECK_EXTRA_REGS(src1, src1w, (void)0); + CHECK_EXTRA_REGS(src2, src2w, (void)0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op & SLJIT_INT_OP; +#endif + + if (GET_OPCODE(op) >= SLJIT_MUL) { + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + } + + switch (GET_OPCODE(op)) { + case SLJIT_ADD: + if (!GET_FLAGS(op)) { + if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED) + return compiler->error; + } + else + compiler->flags_saved = 0; + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_ADDC: + if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ + FAIL_IF(emit_restore_flags(compiler, 1)); + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) + FAIL_IF(emit_save_flags(compiler)); + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SUB: + if (!GET_FLAGS(op)) { + if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) + return compiler->error; + } + else + compiler->flags_saved = 0; + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + FAIL_IF(emit_save_flags(compiler)); + if (dst == SLJIT_UNUSED) + return emit_cmp_binary(compiler, src1, src1w, src2, src2w); + return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SUBC: + if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ + FAIL_IF(emit_restore_flags(compiler, 1)); + else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS)) + FAIL_IF(emit_save_flags(compiler)); + if (SLJIT_UNLIKELY(GET_FLAGS(op))) + compiler->flags_saved = 0; + return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_MUL: + return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_AND: + if (dst == SLJIT_UNUSED) + return emit_test_binary(compiler, src1, src1w, src2, src2w); + return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_OR: + return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35, + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_SHL: + return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_LSHR: + return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + case SLJIT_ASHR: + return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op), + dst, dstw, src1, src1w, src2, src2w); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) +{ + check_sljit_get_register_index(reg); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2 + || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2) + return -1; +#endif + return reg_map[reg]; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) +{ + sljit_ub *buf; + + CHECK_ERROR(); + check_sljit_emit_op_custom(compiler, instruction, size); + SLJIT_ASSERT(size > 0 && size < 16); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); + INC_SIZE(size); + SLJIT_MEMMOVE(buf, instruction, size); + return SLJIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ +/* Floating point operators */ +/* --------------------------------------------------------------------- */ + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + +/* Alignment + 2 * 16 bytes. */ +static sljit_i sse2_data[3 + 4 + 4]; +static sljit_i *sse2_buffer; + +static void init_compiler() +{ + sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf); + sse2_buffer[0] = 0; + sse2_buffer[1] = 0x80000000; + sse2_buffer[4] = 0xffffffff; + sse2_buffer[5] = 0x7fffffff; +} + +#endif + +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) +{ +#if (defined SLJIT_SSE2 && SLJIT_SSE2) +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + static int sse2_available = -1; + int features; + + if (sse2_available != -1) + return sse2_available; + +#ifdef __GNUC__ + /* AT&T syntax. */ + asm ( + "pushl %%ebx\n" + "movl $0x1, %%eax\n" + "cpuid\n" + "popl %%ebx\n" + "movl %%edx, %0\n" + : "=g" (features) + : + : "%eax", "%ecx", "%edx" + ); +#elif defined(_MSC_VER) || defined(__BORLANDC__) + /* Intel syntax. */ + __asm { + mov eax, 1 + push ebx + cpuid + pop ebx + mov features, edx + } +#else + #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" +#endif + sse2_available = (features >> 26) & 0x1; + return sse2_available; +#else + return 1; +#endif +#else + return 0; +#endif +} + +#if (defined SLJIT_SSE2 && SLJIT_SSE2) + +static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, + int xmm1, int xmm2, sljit_w xmm2w) +{ + sljit_ub *buf; + + buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!buf); + *buf++ = 0x0f; + *buf = opcode; + return SLJIT_SUCCESS; +} + +static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, + int xmm1, int xmm2, sljit_w xmm2w) +{ + sljit_ub *buf; + + buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!buf); + *buf++ = 0x0f; + *buf = opcode; + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler, + int dst, int src, sljit_w srcw) +{ + return emit_sse2(compiler, 0x10, dst, src, srcw); +} + +static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler, + int dst, sljit_w dstw, int src) +{ + return emit_sse2(compiler, 0x11, src, dst, dstw); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + if (GET_OPCODE(op) == SLJIT_FCMP) { + compiler->flags_saved = 0; + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) + dst_r = dst; + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw)); + } + return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw); + } + + if (op == SLJIT_FMOV) { + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) + return emit_sse2_load(compiler, dst, src, srcw); + if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) + return emit_sse2_store(compiler, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); + } + + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { + dst_r = dst; + if (dst != src) + FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); + } + + switch (op) { + case SLJIT_FNEG: + FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer)); + break; + + case SLJIT_FABS: + FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4))); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + int dst_r; + + CHECK_ERROR(); + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { + dst_r = dst; + if (dst == src1) + ; /* Do nothing here. */ + else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) { + /* Swap arguments. */ + src2 = src1; + src2w = src1w; + } + else if (dst != src2) + FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w)); + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); + } + } + else { + dst_r = TMP_FREG; + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); + } + + switch (op) { + case SLJIT_FADD: + FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w)); + break; + + case SLJIT_FSUB: + FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w)); + break; + + case SLJIT_FMUL: + FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w)); + break; + + case SLJIT_FDIV: + FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w)); + break; + } + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +#else + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + CHECK_ERROR(); + /* Should cause an assertion fail. */ + check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); + compiler->error = SLJIT_ERR_UNSUPPORTED; + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) +{ + CHECK_ERROR(); + /* Should cause an assertion fail. */ + check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); + compiler->error = SLJIT_ERR_UNSUPPORTED; + return SLJIT_ERR_UNSUPPORTED; +} + +#endif + +/* --------------------------------------------------------------------- */ +/* Conditional instructions */ +/* --------------------------------------------------------------------- */ + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) +{ + sljit_ub *buf; + struct sljit_label *label; + + CHECK_ERROR_PTR(); + check_sljit_emit_label(compiler); + + /* We should restore the flags before the label, + since other taken jumps has their own flags as well. */ + if (SLJIT_UNLIKELY(compiler->flags_saved)) + PTR_FAIL_IF(emit_restore_flags(compiler, 0)); + + if (compiler->last_label && compiler->last_label->size == compiler->size) + return compiler->last_label; + + label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); + PTR_FAIL_IF(!label); + set_label(label, compiler); + + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!buf); + + *buf++ = 0; + *buf++ = 0; + + return label; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) +{ + sljit_ub *buf; + struct sljit_jump *jump; + + CHECK_ERROR_PTR(); + check_sljit_emit_jump(compiler, type); + + if (SLJIT_UNLIKELY(compiler->flags_saved)) { + if ((type & 0xff) <= SLJIT_JUMP) + PTR_FAIL_IF(emit_restore_flags(compiler, 0)); + compiler->flags_saved = 0; + } + + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + PTR_FAIL_IF_NULL(jump); + set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + type &= 0xff; + + if (type >= SLJIT_CALL1) + PTR_FAIL_IF(call_with_args(compiler, type)); + + /* Worst case size. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->size += (type >= SLJIT_JUMP) ? 5 : 6; +#else + compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); +#endif + + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF_NULL(buf); + + *buf++ = 0; + *buf++ = type + 4; + return jump; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) +{ + sljit_ub *code; + struct sljit_jump *jump; + + CHECK_ERROR(); + check_sljit_emit_ijump(compiler, type, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (SLJIT_UNLIKELY(compiler->flags_saved)) { + if (type <= SLJIT_JUMP) + FAIL_IF(emit_restore_flags(compiler, 0)); + compiler->flags_saved = 0; + } + + if (type >= SLJIT_CALL1) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) + if (src == SLJIT_TEMPORARY_REG3) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); + src = TMP_REGISTER; + } + if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3) + srcw += sizeof(sljit_w); +#else + if (src == SLJIT_MEM1(SLJIT_LOCALS_REG)) + srcw += sizeof(sljit_w) * (type - SLJIT_CALL0); +#endif +#endif +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) + if (src == SLJIT_TEMPORARY_REG3) { + EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); + src = TMP_REGISTER; + } +#endif + FAIL_IF(call_with_args(compiler, type)); + } + + if (src == SLJIT_IMM) { + jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); + FAIL_IF_NULL(jump); + set_jump(jump, compiler, JUMP_ADDR); + jump->u.target = srcw; + + /* Worst case size. */ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + compiler->size += 5; +#else + compiler->size += 10 + 3; +#endif + + code = (sljit_ub*)ensure_buf(compiler, 2); + FAIL_IF_NULL(code); + + *code++ = 0; + *code++ = type + 4; + } + else { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; +#endif + code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0xff; + *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3); + } + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) +{ + sljit_ub *buf; + sljit_ub cond_set = 0; + int dst_save = dst; + sljit_w dstw_save = dstw; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + int reg; +#endif + + CHECK_ERROR(); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); + + if (dst == SLJIT_UNUSED) + return SLJIT_SUCCESS; + + ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK_EXTRA_REGS(dst, dstw, (void)0); + if (SLJIT_UNLIKELY(compiler->flags_saved)) + FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS)); + + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_FLOAT_EQUAL: + cond_set = 0x94; + break; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + cond_set = 0x95; + break; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + cond_set = 0x92; + break; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + cond_set = 0x93; + break; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + cond_set = 0x97; + break; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + cond_set = 0x96; + break; + + case SLJIT_C_SIG_LESS: + cond_set = 0x9c; + break; + + case SLJIT_C_SIG_GREATER_EQUAL: + cond_set = 0x9d; + break; + + case SLJIT_C_SIG_GREATER: + cond_set = 0x9f; + break; + + case SLJIT_C_SIG_LESS_EQUAL: + cond_set = 0x9e; + break; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + cond_set = 0x90; + break; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + cond_set = 0x91; + break; + + case SLJIT_C_FLOAT_NAN: + cond_set = 0x9a; + break; + + case SLJIT_C_FLOAT_NOT_NAN: + cond_set = 0x9b; + break; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + FAIL_IF(!buf); + INC_SIZE(4 + 4); + /* Set low register to conditional flag. */ + *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B; + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_lmap[reg]; + *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg]; + + if (reg == TMP_REGISTER) { + if (op == SLJIT_MOV) { + compiler->mode32 = 0; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + else { +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); + } + } +#else + if (op == SLJIT_MOV) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!buf); + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_map[dst]; + + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst]; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!buf); + INC_SIZE(3 + 3); + /* Set al to conditional flag. */ + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0; + + *buf++ = 0x0f; + *buf++ = 0xb6; + if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS) + *buf = 0xC0 | (reg_map[dst] << 3); + else { + *buf = 0xC0; + EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0); + } + + EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0); + } + } + else { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { + EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!buf); + INC_SIZE(3); + + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_map[dst]; + } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); + + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1); + FAIL_IF(!buf); + INC_SIZE(3 + 3 + 1); + /* Set al to conditional flag. */ + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0; + + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf++ = 0xC0; + + *buf++ = 0x90 + reg_map[TMP_REGISTER]; + } +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); + } +#endif + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) +{ + CHECK_ERROR(); + check_sljit_get_local_base(compiler, dst, dstw, offset); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; +#endif + + ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (NOT_HALFWORD(offset)) { + FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset)); +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) + SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED); + return compiler->error; +#else + return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0); +#endif + } +#endif + + if (offset != 0) + return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset); + return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) +{ + sljit_ub *buf; + struct sljit_const *const_; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + int reg; +#endif + + CHECK_ERROR_PTR(); + check_sljit_emit_const(compiler, dst, dstw, init_value); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); + PTR_FAIL_IF(!const_); + set_const(const_, compiler); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; + + if (emit_load_imm64(compiler, reg, init_value)) + return NULL; +#else + if (dst == SLJIT_UNUSED) + dst = TMP_REGISTER; + + if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value)) + return NULL; +#endif + + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!buf); + + *buf++ = 0; + *buf++ = 1; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (reg == TMP_REGISTER && dst != SLJIT_UNUSED) + if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0)) + return NULL; +#endif + + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) +{ +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + *(sljit_w*)addr = new_addr - (addr + 4); +#else + *(sljit_uw*)addr = new_addr; +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) +{ + *(sljit_w*)addr = new_constant; +} diff -Nru pcre3-8.12/sljit/sljitUtils.c pcre3-8.31/sljit/sljitUtils.c --- pcre3-8.12/sljit/sljitUtils.c 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/sljit/sljitUtils.c 2012-03-17 12:18:50.000000000 +0000 @@ -0,0 +1,274 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) 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 HOLDER(S) 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. + */ + +/* ------------------------------------------------------------------------ */ +/* Locks */ +/* ------------------------------------------------------------------------ */ + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + /* Always successful. */ +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + /* Always successful. */ +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + /* Always successful. */ +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + /* Always successful. */ +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */ + +#include "windows.h" + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +static HANDLE allocator_mutex = 0; + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + /* No idea what to do if an error occures. Static mutexes should never fail... */ + if (!allocator_mutex) + allocator_mutex = CreateMutex(NULL, TRUE, NULL); + else + WaitForSingleObject(allocator_mutex, INFINITE); +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + ReleaseMutex(allocator_mutex); +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +static HANDLE global_mutex = 0; + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + /* No idea what to do if an error occures. Static mutexes should never fail... */ + if (!global_mutex) + global_mutex = CreateMutex(NULL, TRUE, NULL); + else + WaitForSingleObject(global_mutex, INFINITE); +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + ReleaseMutex(global_mutex); +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#else /* _WIN32 */ + +#include "pthread.h" + +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) + +static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; + +static SLJIT_INLINE void allocator_grab_lock(void) +{ + pthread_mutex_lock(&allocator_mutex); +} + +static SLJIT_INLINE void allocator_release_lock(void) +{ + pthread_mutex_unlock(&allocator_mutex); +} + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + +#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) + +static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) +{ + pthread_mutex_lock(&global_mutex); +} + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) +{ + pthread_mutex_unlock(&global_mutex); +} + +#endif /* SLJIT_UTIL_GLOBAL_LOCK */ + +#endif /* _WIN32 */ + +/* ------------------------------------------------------------------------ */ +/* Stack */ +/* ------------------------------------------------------------------------ */ + +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) + +#ifdef _WIN32 +#include "windows.h" +#else +#include +#include +#endif + +/* Planning to make it even more clever in the future. */ +static sljit_w sljit_page_align = 0; + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit) +{ + struct sljit_stack *stack; + union { + void *ptr; + sljit_uw uw; + } base; +#ifdef _WIN32 + SYSTEM_INFO si; +#endif + + if (limit > max_limit || limit < 1) + return NULL; + +#ifdef _WIN32 + if (!sljit_page_align) { + GetSystemInfo(&si); + sljit_page_align = si.dwPageSize - 1; + } +#else + if (!sljit_page_align) { + sljit_page_align = sysconf(_SC_PAGESIZE); + /* Should never happen. */ + if (sljit_page_align < 0) + sljit_page_align = 4096; + sljit_page_align--; + } +#endif + + /* Align limit and max_limit. */ + max_limit = (max_limit + sljit_page_align) & ~sljit_page_align; + + stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack)); + if (!stack) + return NULL; + +#ifdef _WIN32 + base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE); + if (!base.ptr) { + SLJIT_FREE(stack); + return NULL; + } + stack->base = base.uw; + stack->limit = stack->base; + stack->max_limit = stack->base + max_limit; + if (sljit_stack_resize(stack, stack->base + limit)) { + sljit_free_stack(stack); + return NULL; + } +#else + base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (base.ptr == MAP_FAILED) { + SLJIT_FREE(stack); + return NULL; + } + stack->base = base.uw; + stack->limit = stack->base + limit; + stack->max_limit = stack->base + max_limit; +#endif + stack->top = stack->base; + return stack; +} + +#undef PAGE_ALIGN + +SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack) +{ +#ifdef _WIN32 + VirtualFree((void*)stack->base, 0, MEM_RELEASE); +#else + munmap((void*)stack->base, stack->max_limit - stack->base); +#endif + SLJIT_FREE(stack); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) +{ + sljit_uw aligned_old_limit; + sljit_uw aligned_new_limit; + + if ((new_limit > stack->max_limit) || (new_limit < stack->base)) + return -1; +#ifdef _WIN32 + aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; + aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; + if (aligned_new_limit != aligned_old_limit) { + if (aligned_new_limit > aligned_old_limit) { + if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE)) + return -1; + } + else { + if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT)) + return -1; + } + } + stack->limit = new_limit; + return 0; +#else + if (new_limit >= stack->limit) { + stack->limit = new_limit; + return 0; + } + aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; + aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; + if (aligned_new_limit < aligned_old_limit) + posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); + stack->limit = new_limit; + return 0; +#endif +} + +#endif /* SLJIT_UTIL_STACK */ + +#endif Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/grepbinary and /tmp/KWffpnYXzW/pcre3-8.31/testdata/grepbinary differ diff -Nru pcre3-8.12/testdata/grepfilelist pcre3-8.31/testdata/grepfilelist --- pcre3-8.12/testdata/grepfilelist 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/grepfilelist 2012-02-28 16:27:00.000000000 +0000 @@ -0,0 +1,3 @@ +testdata/grepinputv + +testdata/grepinputx diff -Nru pcre3-8.12/testdata/grepinput pcre3-8.31/testdata/grepinput --- pcre3-8.12/testdata/grepinput 2007-03-05 12:35:12.000000000 +0000 +++ pcre3-8.31/testdata/grepinput 2011-07-22 17:29:52.000000000 +0000 @@ -602,6 +602,8 @@ AB.VE AB.VE the turtle +010203040506 + PUT NEW DATA ABOVE THIS LINE. ============================= diff -Nru pcre3-8.12/testdata/grepoutput pcre3-8.31/testdata/grepoutput --- pcre3-8.12/testdata/grepoutput 2011-01-15 11:16:58.000000000 +0000 +++ pcre3-8.31/testdata/grepoutput 2012-03-04 16:52:16.000000000 +0000 @@ -10,7 +10,7 @@ 7:PATTERN at the start of a line. 8:In the middle of a line, PATTERN appears. 10:This pattern is in lower case. -608:Check up on PATTERN near the end. +610:Check up on PATTERN near the end. RC=0 ---------------------------- Test 4 ------------------------------ 4 @@ -19,7 +19,7 @@ ./testdata/grepinput:7:PATTERN at the start of a line. ./testdata/grepinput:8:In the middle of a line, PATTERN appears. ./testdata/grepinput:10:This pattern is in lower case. -./testdata/grepinput:608:Check up on PATTERN near the end. +./testdata/grepinput:610:Check up on PATTERN near the end. ./testdata/grepinputx:3:Here is the pattern again. ./testdata/grepinputx:5:Pattern ./testdata/grepinputx:42:This line contains pattern not on a line by itself. @@ -28,7 +28,7 @@ 7:PATTERN at the start of a line. 8:In the middle of a line, PATTERN appears. 10:This pattern is in lower case. -608:Check up on PATTERN near the end. +610:Check up on PATTERN near the end. 3:Here is the pattern again. 5:Pattern 42:This line contains pattern not on a line by itself. @@ -323,10 +323,10 @@ ./testdata/grepinput-9- ./testdata/grepinput:10:This pattern is in lower case. -- -./testdata/grepinput-605-PUT NEW DATA ABOVE THIS LINE. -./testdata/grepinput-606-============================= -./testdata/grepinput-607- -./testdata/grepinput:608:Check up on PATTERN near the end. +./testdata/grepinput-607-PUT NEW DATA ABOVE THIS LINE. +./testdata/grepinput-608-============================= +./testdata/grepinput-609- +./testdata/grepinput:610:Check up on PATTERN near the end. -- ./testdata/grepinputx-1-This is a second file of input for the pcregrep tests. ./testdata/grepinputx-2- @@ -348,8 +348,8 @@ ./testdata/grepinput-12-Here follows a whole lot of stuff that makes the file over 24K long. ./testdata/grepinput-13- -- -./testdata/grepinput:608:Check up on PATTERN near the end. -./testdata/grepinput-609-This is the last line of this file. +./testdata/grepinput:610:Check up on PATTERN near the end. +./testdata/grepinput-611-This is the last line of this file. -- ./testdata/grepinputx:3:Here is the pattern again. ./testdata/grepinputx-4- @@ -380,6 +380,7 @@ ---------------------------- Test 37 ----------------------------- aaaaa0 aaaaa2 +010203040506 RC=0 ======== STDERR ======== pcregrep: pcre_exec() gave error -8 while matching this text: @@ -390,7 +391,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. ---------------------------- Test 38 ------------------------------ This line contains a binary zero here >< for testing. @@ -514,7 +515,7 @@ that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 63 ----------------------------- @@ -524,7 +525,7 @@ that the pcregrep command is working correctly. The file must be more than 24K long so that it needs more than a single read -pcregrep: Error -8 or -21 means that a resource limit was exceeded. +pcregrep: Error -8, -21 or -27 means that a resource limit was exceeded. pcregrep: Check your regex for nested unlimited loops. RC=1 ---------------------------- Test 64 ------------------------------ @@ -593,3 +594,77 @@ triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt RC=0 +---------------------------- Test 71 ----------------------------- +01 +RC=0 +---------------------------- Test 72 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 73 ----------------------------- +01 +RC=0 +---------------------------- Test 74 ----------------------------- +01 +02 +RC=0 +---------------------------- Test 75 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 76 ----------------------------- +01 +02 +RC=0 +---------------------------- Test 77 ----------------------------- +01 +03 +RC=0 +---------------------------- Test 78 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 79 ----------------------------- +01 +03 +RC=0 +---------------------------- Test 80 ----------------------------- +01 +RC=0 +---------------------------- Test 81 ----------------------------- +010203040506 +RC=0 +---------------------------- Test 82 ----------------------------- +01 +RC=0 +---------------------------- Test 83 ----------------------------- +pcregrep: line 4 of file ./testdata/grepinput3 is too long for the internal buffer +pcregrep: check the --buffer-size option +RC=2 +---------------------------- Test 84 ----------------------------- +testdata/grepinputv:fox jumps +testdata/grepinputx:complete pair +testdata/grepinputx:That was a complete pair +testdata/grepinputx:complete pair +RC=0 +---------------------------- Test 85 ----------------------------- +./testdata/grepinput3:Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +RC=0 +---------------------------- Test 86 ----------------------------- +Binary file ./testdata/grepbinary matches +RC=0 +---------------------------- Test 87 ----------------------------- +RC=1 +---------------------------- Test 88 ----------------------------- +Binary file ./testdata/grepbinary matches +RC=0 +---------------------------- Test 89 ----------------------------- +RC=1 +---------------------------- Test 90 ----------------------------- +RC=1 +---------------------------- Test 91 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 +---------------------------- Test 92 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 +---------------------------- Test 93 ----------------------------- +The quick brown fx jumps over the lazy dog. +RC=0 diff -Nru pcre3-8.12/testdata/greppatN4 pcre3-8.31/testdata/greppatN4 --- pcre3-8.12/testdata/greppatN4 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/greppatN4 2011-12-29 17:19:20.000000000 +0000 @@ -0,0 +1,2 @@ +xxx +jkl \ No newline at end of file Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved16 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved16 differ Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved16BE-1 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved16BE-1 differ Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved16BE-2 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved16BE-2 differ Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved16LE-1 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved16LE-1 differ Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved16LE-2 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved16LE-2 differ Binary files /tmp/U7q3q5uV1x/pcre3-8.12/testdata/saved8 and /tmp/KWffpnYXzW/pcre3-8.31/testdata/saved8 differ diff -Nru pcre3-8.12/testdata/testinput1 pcre3-8.31/testdata/testinput1 --- pcre3-8.12/testdata/testinput1 2010-11-20 17:29:13.000000000 +0000 +++ pcre3-8.31/testdata/testinput1 2012-06-16 17:51:59.000000000 +0000 @@ -1,5 +1,6 @@ /-- This set of tests is for features that are compatible with all versions of - Perl 5, in non-UTF-8 mode. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and + 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox @@ -4079,4 +4080,1186 @@ /^\c/ ? +/(abc)\1/i + abc + +/(abc)\1/ + abc + +/[^a]*/i + 12abc + 12ABC + +/[^a]*+/i + 12abc + 12ABC + +/[^a]*?X/i + ** Failers + 12abc + 12ABC + +/[^a]+?X/i + ** Failers + 12abc + 12ABC + +/[^a]?X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]??X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]?+X/i + 12aXbcX + 12AXBCX + BCX + +/[^a]{2,3}/i + abcdef + ABCDEF + +/[^a]{2,3}?/i + abcdef + ABCDEF + +/[^a]{2,3}+/i + abcdef + ABCDEF + +/((a|)+)+Z/ + Z + +/(a)b|(a)c/ + ac + +/(?>(a))b|(a)c/ + ac + +/(?=(a))ab|(a)c/ + ac + +/((?>(a))b|(a)c)/ + ac + +/((?>(a))b|(a)c)++/ + ac + +/(?:(?>(a))b|(a)c)++/ + ac + +/(?=(?>(a))b|(a)c)(..)/ + ac + +/(?>(?>(a))b|(a)c)/ + ac + +/(?:(?>([ab])))+a=/+ + =ba= + +/(?>([ab]))+a=/+ + =ba= + +/((?>(a+)b)+(aabab))/ + aaaabaaabaabab + +/(?>a+|ab)+?c/ + aabc + +/(?>a+|ab)+c/ + aabc + +/(?:a+|ab)+c/ + aabc + +/(?(?=(a))a)/ + a + +/(?(?=(a))a)(b)/ + ab + +/^(?:a|ab)++c/ + aaaabc + +/^(?>a|ab)++c/ + aaaabc + +/^(?:a|ab)+c/ + aaaabc + +/(?=abc){3}abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)+abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)++abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc){0}xyz/ + xyz + +/(?=abc){1}xyz/ + ** Failers + xyz + +/(?=(a))?./ + ab + bc + +/(?=(a))??./ + ab + bc + +/^(?=(a)){0}b(?1)/ + backgammon + +/^(?=(?1))?[az]([abc])d/ + abd + zcdxx + +/^(?!a){0}\w+/ + aaaaa + +/(?<=(abc))?xyz/ + abcxyz + pqrxyz + +/^[\g]+/ + ggg<<>> + ** Failers + \\ga + +/^[\ga]+/ + gggagagaxyz + +/^[:a[:digit:]]+/ + aaaa444:::Z + +/^[:a[:digit:]:b]+/ + aaaa444:::bbbZ + +/[:a]xxx[b:]/ + :xxx: + +/(?<=a{2})b/i + xaabc + ** Failers + xabc + +/(?XNNNYZ + > X NYQZ + ** Failers + >XYZ + > X NY Z + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/(foo)\Kbar/ + foobar + +/(foo)(\Kbar|baz)/ + foobar + foobaz + +/(foo\Kbar)baz/ + foobarbaz + +/abc\K|def\K/g+ + Xabcdefghi + +/ab\Kc|de\Kf/g+ + Xabcdefghi + +/(?=C)/g+ + ABCDECBA + +/^abc\K/+ + abcdef + ** Failers + defabcxyz + +/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ + ababababbbabZXXXX + +/(?tom|bon)-\g{A}/ + tom-tom + bon-bon + +/(^(a|b\g{-1}))/ + bacxxx + +/(?|(abc)|(xyz))\1/ + abcabc + xyzxyz + ** Failers + abcxyz + xyzabc + +/(?|(abc)|(xyz))(?1)/ + abcabc + xyzabc + ** Failers + xyzxyz + +/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ + XYabcdY + +/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ + XYabcdY + +/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ + XYabcdY + +/(?'abc'\w+):\k{2}/ + a:aaxyz + ab:ababxyz + ** Failers + a:axyz + ab:abxyz + +/(?'abc'\w+):\g{abc}{2}/ + a:aaxyz + ab:ababxyz + ** Failers + a:axyz + ab:abxyz + +/^(?a)? (?()b|c) (?('ab')d|e)/x + abd + ce + +/^(a.)\g-1Z/ + aXaXZ + +/^(a.)\g{-1}Z/ + aXaXZ + +/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x + abcd + +/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) + (?(DEFINE) + (?[a-z]+) + (?\d+) + )/x + metcalfe 33 + +/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ + 1.2.3.4 + 131.111.10.206 + 10.0.0.0 + ** Failers + 10.6 + 455.3.4.5 + +/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ + 1.2.3.4 + 131.111.10.206 + 10.0.0.0 + ** Failers + 10.6 + 455.3.4.5 + +/^(\w++|\s++)*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d++)(\w)/ + 12345a + *** Failers + 12345+ + +/a++b/ + aaab + +/(a++b)/ + aaab + +/(a++)b/ + aaab + +/([^()]++|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(([^()]++|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/^([^()]|\((?1)*\))*$/ + abc + a(b)c + a(b(c))d + *** Failers) + a(b(c)d + +/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x + <> + + hij> + hij> + def> + + *** Failers + a)(?<=b(?&X))/ + baz + +/^(?|(abc)|(def))\1/ + abcabc + defdef + ** Failers + abcdef + defabc + +/^(?|(abc)|(def))(?1)/ + abcabc + defabc + ** Failers + defdef + abcdef + +/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ + a\"aaaaa + b\"aaaaa + ** Failers + b\"11111 + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + CCD + ** Failers + CAD + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + BCD + ** Failers + ABCD + CAD + BAD + +/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ + AAD + ACD + BAD + BCD + BAX + ** Failers + ACX + ABC + +/(?(DEFINE)(A))B(?1)C/ + BAC + +/(?(DEFINE)((A)\2))B(?1)C/ + BAAC + +/(? \( ( [^()]++ | (?&pn) )* \) )/x + (ab(cd)ef) + +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?=a(*ACCEPT)b)/ + ac + +/^(?(?!a(*SKIP)b))/ + ac + +/(?>a\Kb)/ + ab + +/((?>a\Kb))/ + ab + +/(a\Kb)/ + ab + +/^a\Kcz|ac/ + ac + +/(?>a\Kbz|ab)/ + ab + +/^(?&t)(?(DEFINE)(?a\Kb))$/ + ab + +/^([^()]|\((?1)*\))*$/ + a(b)c + a(b(c)d)e + +/(?P(?P0)(?P>L1)|(?P>L2))/ + 0 + 00 + 0000 + +/(?P(?P0)|(?P>L2)(?P>L1))/ + 0 + 00 + 0000 + +/--- This one does fail, as expected, in Perl. It needs the complex item at the + end of the pattern. A single letter instead of (B|D) makes it not fail, + which I think is a Perl bug. --- / + +/A(*COMMIT)(B|D)/ + ACABX + +/--- Check the use of names for failure ---/ + +/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K + ** Failers + AC + CB + +/--- Force no study, otherwise mark is not seen. The studied version is in + test 2 because it isn't Perl-compatible. ---/ + +/(*MARK:A)(*SKIP:B)(C|X)/KSS + C + D + +/^(A(*THEN:A)B|C(*THEN:B)D)/K + ** Failers + CB + +/^(?:A(*THEN:A)B|C(*THEN:B)D)/K + CB + +/^(?>A(*THEN:A)B|C(*THEN:B)D)/K + CB + +/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note +that we have to have something complicated such as (B|Z) at the end because, +for Perl, a simple character somehow causes an unwanted optimization to mess +with the handling of backtracking verbs. ---/ + +/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Test skipping over a non-matching mark. ---/ + +/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Check shorthand for MARK ---/ + +/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + +/--- Don't loop! Force no study, otherwise mark is not seen. ---/ + +/(*:A)A+(*SKIP:A)(B|Z)/KSS + AAAC + +/--- This should succeed, as a non-existent skip name disables the skip ---/ + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK + AAAC + +/--- COMMIT at the start of a pattern should act like an anchor. Again, +however, we need the complication for Perl. ---/ + +/(*COMMIT)(A|P)(B|P)(C|P)/ + ABCDEFG + ** Failers + DEFGABC + +/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ + +/(\w+)(?>b(*COMMIT))\w{2}/ + abbb + +/(\w+)b(*COMMIT)\w{2}/ + abbb + +/--- Check opening parens in comment when seeking forward reference. ---/ + +/(?&t)(?#()(?(DEFINE)(?a))/ + bac + +/--- COMMIT should override THEN ---/ + +/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ + yes + +/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ + yes + +/b?(*SKIP)c/ + bc + abc + +/(*SKIP)bc/ + a + +/(*SKIP)b/ + a + +/(?P(?P=abn)xxx|)+/ + xxx + +/(?i:([^b]))(?1)/ + aa + aA + ** Failers + ab + aB + Ba + ba + +/^(?&t)*+(?(DEFINE)(?a))\w$/ + aaaaaaX + ** Failers + aaaaaa + +/^(?&t)*(?(DEFINE)(?a))\w$/ + aaaaaaX + aaaaaa + +/^(a)*+(\w)/ + aaaaX + YZ + ** Failers + aaaa + +/^(?:a)*+(\w)/ + aaaaX + YZ + ** Failers + aaaa + +/^(a)++(\w)/ + aaaaX + ** Failers + aaaa + YZ + +/^(?:a)++(\w)/ + aaaaX + ** Failers + aaaa + YZ + +/^(a)?+(\w)/ + aaaaX + YZ + +/^(?:a)?+(\w)/ + aaaaX + YZ + +/^(a){2,}+(\w)/ + aaaaX + ** Failers + aaa + YZ + +/^(?:a){2,}+(\w)/ + aaaaX + ** Failers + aaa + YZ + +/(a|)*(?1)b/ + b + ab + aab + +/(a)++(?1)b/ + ** Failers + ab + aab + +/(a)*+(?1)b/ + ** Failers + ab + aab + +/(?1)(?:(b)){0}/ + b + +/(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x + foo(bar(baz)+baz(bop)) + +/(A (A|B(*ACCEPT)|C) D)(E)/x + AB + +/\A.*?(?:a|b(*THEN)c)/ + ba + +/\A.*?(?:a|bc)/ + ba + +/\A.*?(a|b(*THEN)c)/ + ba + +/\A.*?(a|bc)/ + ba + +/\A.*?(?:a|b(*THEN)c)++/ + ba + +/\A.*?(?:a|bc)++/ + ba + +/\A.*?(a|b(*THEN)c)++/ + ba + +/\A.*?(a|bc)++/ + ba + +/\A.*?(?:a|b(*THEN)c|d)/ + ba + +/\A.*?(?:a|bc|d)/ + ba + +/(?:(b))++/ + beetle + +/(?(?=(a(*ACCEPT)z))a)/ + a + +/^(a)(?1)+ab/ + aaaab + +/^(a)(?1)++ab/ + aaaab + +/^(?=a(*:M))aZ/K + aZbc + +/^(?!(*:M)b)aZ/K + aZbc + +/(?(DEFINE)(a))?b(?1)/ + backgammon + +/^\N+/ + abc\ndef + +/^\N{1,}/ + abc\ndef + +/(?(R)a+|(?R)b)/ + aaaabcde + +/(?(R)a+|((?R))b)/ + aaaabcde + +/((?(R)a+|(?1)b))/ + aaaabcde + +/((?(R1)a+|(?1)b))/ + aaaabcde + +/a(*:any +name)/K + abc + +/(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ + a + ba + bba + +/--- Checking revised (*THEN) handling ---/ + +/--- Capture ---/ + +/^.*? (a(*THEN)b) c/x + aabc + +/^.*? (a(*THEN)b|(*F)) c/x + aabc + +/^.*? ( (a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? ( (a(*THEN)b) ) c/x + aabc + +/--- Non-capture ---/ + +/^.*? (?:a(*THEN)b) c/x + aabc + +/^.*? (?:a(*THEN)b|(*F)) c/x + aabc + +/^.*? (?: (?:a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? (?: (?:a(*THEN)b) ) c/x + aabc + +/--- Atomic ---/ + +/^.*? (?>a(*THEN)b) c/x + aabc + +/^.*? (?>a(*THEN)b|(*F)) c/x + aabc + +/^.*? (?> (?>a(*THEN)b) | (*F) ) c/x + aabc + +/^.*? (?> (?>a(*THEN)b) ) c/x + aabc + +/--- Possessive capture ---/ + +/^.*? (a(*THEN)b)++ c/x + aabc + +/^.*? (a(*THEN)b|(*F))++ c/x + aabc + +/^.*? ( (a(*THEN)b)++ | (*F) )++ c/x + aabc + +/^.*? ( (a(*THEN)b)++ )++ c/x + aabc + +/--- Possessive non-capture ---/ + +/^.*? (?:a(*THEN)b)++ c/x + aabc + +/^.*? (?:a(*THEN)b|(*F))++ c/x + aabc + +/^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x + aabc + +/^.*? (?: (?:a(*THEN)b)++ )++ c/x + aabc + +/--- Condition assertion ---/ + +/^(?(?=a(*THEN)b)ab|ac)/ + ac + +/--- Condition ---/ + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba + +/^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ + ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac + +/--- Assertion ---/ + +/^.*(?=a(*THEN)b)/ + aabc + +/------------------------------/ + +/(?>a(*:m))/imsxSK + a + +/(?>(a)(*:m))/imsxSK + a + +/(?<=a(*ACCEPT)b)c/ + xacd + +/(?<=(a(*ACCEPT)b))c/ + xacd + +/(?<=(a(*COMMIT)b))c/ + xabcd + ** Failers + xacd + +/(?a?)*)*c/ + aac + /-- End of testinput1 --/ diff -Nru pcre3-8.12/testdata/testinput10 pcre3-8.31/testdata/testinput10 --- pcre3-8.12/testdata/testinput10 2010-10-10 15:36:47.000000000 +0000 +++ pcre3-8.31/testdata/testinput10 2012-06-01 18:31:43.000000000 +0000 @@ -1,137 +1,1029 @@ -/-- These are a few representative patterns whose lengths and offsets are to be -shown when the link size is 2. This is just a doublecheck test to ensure the -sizes don't go horribly wrong when something is changed. The pattern contents -are all themselves checked in other tests. Unicode, including property support, -is required for these tests. --/ - -/((?i)b)/BM - -/(?s)(.*X|^B)/BM - -/(?s:.*X|^B)/BM - -/^[[:alnum:]]/BM - -/#/IxMD - -/a#/IxMD - -/x?+/BM - -/x++/BM - -/x{1,3}+/BM - -/(x)*+/BM - -/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM - -|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM - -|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM - -/(a(?1)b)/BM - -/(a(?1)+b)/BM - -/a(?Pb|c)d(?Pe)/BM - -/(?:a(?Pc(?Pd)))(?Pa)/BM - -/(?Pa)...(?P=a)bbb(?P>a)d/BM - -/abc(?C255)de(?C)f/BM - -/abcde/CBM - -/\x{100}/8BM - -/\x{1000}/8BM - -/\x{10000}/8BM - -/\x{100000}/8BM - -/\x{1000000}/8BM - -/\x{4000000}/8BM - -/\x{7fffFFFF}/8BM - -/[\x{ff}]/8BM - -/[\x{100}]/8BM - -/\x80/8BM - -/\xff/8BM - -/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +/-- This set of tests check Unicode property support with the DFA matching + functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest + when running it. --/ + +/\pL\P{Nd}/8 + AB + *** Failers + A0 + 00 + +/\X./8 + AB + A\x{300}BC + A\x{300}\x{301}\x{302}BC + *** Failers + \x{300} + +/\X\X/8 + ABC + A\x{300}B\x{300}\x{301}C + A\x{300}\x{301}\x{302}BC + *** Failers + \x{300} + +/^\pL+/8 + abcd + a + *** Failers + +/^\PL+/8 + 1234 + = + *** Failers + abcd + +/^\X+/8 + abcdA\x{300}\x{301}\x{302} + A\x{300}\x{301}\x{302} + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} + a + *** Failers + \x{300}\x{301}\x{302} + +/\X?abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc + *** Failers + +/^\X?abc/8 + abc + A\x{300}abc + *** Failers + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc + +/\X*abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + \x{300}abc + *** Failers + +/^\X*abc/8 + abc + A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + *** Failers + \x{300}abc + +/^\pL?=./8 + A=b + =c + *** Failers + 1=2 + AAAA=b + +/^\pL*=./8 + AAAA=b + =c + *** Failers + 1=2 + +/^\X{2,3}X/8 + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + *** Failers + X + A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + +/^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + ** Failers + \x{0b} -/[^a]/BM +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/[^a]/8BM +/^>\p{Xsp}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} -/[^\xaa]/BM +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/[^\xaa]/8BM +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} -/[^\d]/8WB +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^\p{Xwd}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] -/[[:^alpha:][:^cntrl:]]+/8WB +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/[[:^cntrl:][:^alpha:]]+/8WB +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_12\x{6ca}\x{a6c}\x{10a7} + +/^[\p{Xwd}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ + +/-- Caseless single negated characters > 127 need UCP support --/ -/[[:alpha:]]+/8WB +/[^\x{100}]/8i + \x{100}\x{101}X -/[[:^alpha:]\S]+/8WB +/[^\x{100}]+/8i + \x{100}\x{101}XX -/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P -/-- End of testinput10 --/ +/-- End of testinput10 --/ diff -Nru pcre3-8.12/testdata/testinput11 pcre3-8.31/testdata/testinput11 --- pcre3-8.12/testdata/testinput11 2010-11-23 15:30:39.000000000 +0000 +++ pcre3-8.31/testdata/testinput11 2011-12-28 16:57:55.000000000 +0000 @@ -1,510 +1,135 @@ -/-- These tests are for the Perl >= 5.10 features that PCRE supports. --/ +/-- These are a few representative patterns whose lengths and offsets are to be +shown when the link size is 2. This is just a doublecheck test to ensure the +sizes don't go horribly wrong when something is changed. The pattern contents +are all themselves checked in other tests. Unicode, including property support, +is required for these tests. --/ -/\H\h\V\v/ - X X\x0a - X\x09X\x0b - ** Failers - \xa0 X\x0a - -/\H*\h+\V?\v{3,4}/ - \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c - ** Failers - \x09\x20\xa0\x0a\x0b - -/\H{3,4}/ - XY ABCDE - XY PQR ST - -/.\h{3,4}./ - XY AB PQRS +/((?i)b)/BM -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - > X NYQZ - ** Failers - >XYZ - > X NY Z - -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - -/(foo)\Kbar/ - foobar - -/(foo)(\Kbar|baz)/ - foobar - foobaz +/(?s)(.*X|^B)/BM -/(foo\Kbar)baz/ - foobarbaz +/(?s:.*X|^B)/BM -/abc\K|def\K/g+ - Xabcdefghi +/^[[:alnum:]]/BM -/ab\Kc|de\Kf/g+ - Xabcdefghi - -/(?=C)/g+ - ABCDECBA - -/^abc\K/+ - abcdef - ** Failers - defabcxyz - -/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ - ababababbbabZXXXX - -/(?tom|bon)-\g{A}/ - tom-tom - bon-bon - -/(^(a|b\g{-1}))/ - bacxxx +/#/IxMD -/(?|(abc)|(xyz))\1/ - abcabc - xyzxyz - ** Failers - abcxyz - xyzabc - -/(?|(abc)|(xyz))(?1)/ - abcabc - xyzabc - ** Failers - xyzxyz - -/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ - XYabcdY - -/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ - XYabcdY - -/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ - XYabcdY - -/(?'abc'\w+):\k{2}/ - a:aaxyz - ab:ababxyz - ** Failers - a:axyz - ab:abxyz - -/(?'abc'\w+):\g{abc}{2}/ - a:aaxyz - ab:ababxyz - ** Failers - a:axyz - ab:abxyz - -/^(?a)? (?()b|c) (?('ab')d|e)/x - abd - ce - -/^(a.)\g-1Z/ - aXaXZ - -/^(a.)\g{-1}Z/ - aXaXZ - -/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x - abcd - -/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) - (?(DEFINE) - (?[a-z]+) - (?\d+) - )/x - metcalfe 33 - -/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ - 1.2.3.4 - 131.111.10.206 - 10.0.0.0 - ** Failers - 10.6 - 455.3.4.5 - -/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ - 1.2.3.4 - 131.111.10.206 - 10.0.0.0 - ** Failers - 10.6 - 455.3.4.5 - -/^(\w++|\s++)*$/ - now is the time for all good men to come to the aid of the party - *** Failers - this is not a line with only words and spaces! - -/(\d++)(\w)/ - 12345a - *** Failers - 12345+ - -/a++b/ - aaab - -/(a++b)/ - aaab - -/(a++)b/ - aaab - -/([^()]++|\([^()]*\))+/ - ((abc(ade)ufh()()x - -/\(([^()]++|\([^()]+\))+\)/ - (abc) - (abc(def)xyz) - *** Failers - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/^([^()]|\((?1)*\))*$/ - abc - a(b)c - a(b(c))d - *** Failers) - a(b(c)d - -/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x - <> - - hij> - hij> - def> - - *** Failers - a)(?<=b(?&X))/ - baz +/(x)*+/BM -/^(?|(abc)|(def))\1/ - abcabc - defdef - ** Failers - abcdef - defabc - -/^(?|(abc)|(def))(?1)/ - abcabc - defabc - ** Failers - defdef - abcdef - -/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ - a\"aaaaa - b\"aaaaa - ** Failers - b\"11111 - -/(?:(?1)|B)(A(*F)|C)/ - ABCD - CCD - ** Failers - CAD - -/^(?:(?1)|B)(A(*F)|C)/ - CCD - BCD - ** Failers - ABCD - CAD - BAD - -/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ - AAD - ACD - BAD - BCD - BAX - ** Failers - ACX - ABC - -/(?(DEFINE)(A))B(?1)C/ - BAC +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM -/(?(DEFINE)((A)\2))B(?1)C/ - BAAC +|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM -/(? \( ( [^()]++ | (?&pn) )* \) )/x - (ab(cd)ef) +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM -/^(?!a(*SKIP)b)/ - ac - -/^(?=a(*SKIP)b|ac)/ - ** Failers - ac - -/^(?=a(*THEN)b|ac)/ - ac - -/^(?=a(*PRUNE)b)/ - ab - ** Failers - ac +/(a(?1)b)/BM -/^(?=a(*ACCEPT)b)/ - ac +/(a(?1)+b)/BM -/^(?(?!a(*SKIP)b))/ - ac +/a(?Pb|c)d(?Pe)/BM -/(?>a\Kb)/ - ab +/(?:a(?Pc(?Pd)))(?Pa)/BM -/((?>a\Kb))/ - ab +/(?Pa)...(?P=a)bbb(?P>a)d/BM -/(a\Kb)/ - ab - -/^a\Kcz|ac/ - ac - -/(?>a\Kbz|ab)/ - ab +/abc(?C255)de(?C)f/BM -/^(?&t)(?(DEFINE)(?a\Kb))$/ - ab +/abcde/CBM -/^([^()]|\((?1)*\))*$/ - a(b)c - a(b(c)d)e - -/(?P(?P0)(?P>L1)|(?P>L2))/ - 0 - 00 - 0000 - -/(?P(?P0)|(?P>L2)(?P>L1))/ - 0 - 00 - 0000 - -/--- This one does fail, as expected, in Perl. It needs the complex item at the - end of the pattern. A single letter instead of (B|D) makes it not fail, - which I think is a Perl bug. --- / - -/A(*COMMIT)(B|D)/ - ACABX - -/--- Check the use of names for failure ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - ** Failers - AC - CB - -/(*MARK:A)(*SKIP:B)(C|X)/K - C - D - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - ** Failers - CB +/\x{100}/8BM -/^(?:A(*THEN:A)B|C(*THEN:B)D)/K - CB - -/^(?>A(*THEN:A)B|C(*THEN:B)D)/K - CB - -/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note -that we have to have something complicated such as (B|Z) at the end because, -for Perl, a simple character somehow causes an unwanted optimization to mess -with the handling of backtracking verbs. ---/ +/\x{1000}/8BM -/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC - -/--- Test skipping over a non-matching mark. ---/ +/\x{10000}/8BM -/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK - AAAC - -/--- Check shorthand for MARK ---/ +/\x{100000}/8BM -/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC +/\x{10ffff}/8BM -/--- Don't loop! ---/ +/\x{110000}/8BM -/(*:A)A+(*SKIP:A)(B|Z)/K - AAAC +/[\x{ff}]/8BM -/--- This should succeed, as a non-existent skip name disables the skip ---/ +/[\x{100}]/8BM -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK - AAAC +/\x80/8BM -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK - AAAC +/\xff/8BM -/--- We use something more complicated than individual letters here, because -that causes different behaviour in Perl. Perhaps it disables some optimization; -anyway, the result now matches PCRE in that no tag is passed back for the -failures. ---/ +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M -/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK - AABC - XXYZ - ** Failers - XAQQ - XAQQXZZ - AXQQQ - AXXQQQ - -/--- COMMIT at the start of a pattern should act like an anchor. Again, -however, we need the complication for Perl. ---/ +/\x{D55c}\x{ad6d}\x{C5B4}/D8M + +/\x{65e5}\x{672c}\x{8a9e}/D8M + +/[\x{100}]/8BM + +/[Z\x{100}]/8BM + +/^[\x{100}\E-\Q\E\x{150}]/B8M + +/^[\QÄ€\E-\QÅ\E]/B8M + +/^[\QÄ€\E-\QÅ\E/B8M + +/[\p{L}]/BM + +/[\p{^L}]/BM + +/[\P{L}]/BM + +/[\P{^L}]/BM + +/[abc\p{L}\x{0660}]/8BM + +/[\p{Nd}]/8BM + +/[\p{Nd}+-]+/8BM + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM + +/[\x{105}-\x{109}]/8iBM + +/( ( (?(1)0|) )* )/xBM + +/( (?(1)0|)* )/xBM + +/[a]/BM -/(*COMMIT)(A|P)(B|P)(C|P)/ - ABCDEFG - ** Failers - DEFGABC +/[a]/8BM -/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ +/[\xaa]/BM -/(\w+)(?>b(*COMMIT))\w{2}/ - abbb +/[\xaa]/8BM -/(\w+)b(*COMMIT)\w{2}/ - abbb +/[^a]/BM -/--- Check opening parens in comment when seeking forward reference. ---/ +/[^a]/8BM -/(?&t)(?#()(?(DEFINE)(?a))/ - bac +/[^\xaa]/BM -/--- COMMIT should override THEN ---/ +/[^\xaa]/8BM -/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ - yes +/[^\d]/8WB -/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ - yes +/[[:^alpha:][:^cntrl:]]+/8WB -/^((yes|no)(*THEN)(*F))?/ - yes +/[[:^cntrl:][:^alpha:]]+/8WB -/b?(*SKIP)c/ - bc - abc - -/(*SKIP)bc/ - a +/[[:alpha:]]+/8WB -/(*SKIP)b/ - a +/[[:^alpha:]\S]+/8WB -/(?P(?P=abn)xxx|)+/ - xxx +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B /-- End of testinput11 --/ diff -Nru pcre3-8.12/testdata/testinput12 pcre3-8.31/testdata/testinput12 --- pcre3-8.12/testdata/testinput12 2010-06-01 16:19:39.000000000 +0000 +++ pcre3-8.31/testdata/testinput12 2012-04-11 15:57:12.000000000 +0000 @@ -1,506 +1,83 @@ -/-- These tests for Unicode property support test PCRE's API and show some of - the compiled code. They are not Perl-compatible. --/ +/-- This test is run only when JIT support is available. It checks for a +successful and an unsuccessful JIT compile and save and restore behaviour, +and a couple of things that are different with JIT. --/ -/[\p{L}]/DZ +/abc/S+I -/[\p{^L}]/DZ +/ab(*THEN)/S+I -/[\P{L}]/DZ +/abc/S+I>testsavedregex -/[\P{^L}]/DZ - -/[abc\p{L}\x{0660}]/8DZ - -/[\p{Nd}]/8DZ - 1234 - -/[\p{Nd}+-]+/8DZ - 1234 - 12-34 - 12+\x{661}-34 - ** Failers - abcd - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ - -/AB\x{1fb0}/8DZ +\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} - >\x{a0} - ** Failers - \x{0b} - -/^>\p{Xsp}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}+?/8 - >\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xsp}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}/8 - >\x{1680}\x{2028}\x{0b} - >\x{a0} - ** Failers - \x{0b} - -/^>\p{Xps}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}+?/8 - >\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>[\p{Xps}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xps}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^\p{Xwd}/8 - ABCD - 1234 - \x{6ca} - \x{a6c} - \x{10a7} - _ABC - ** Failers - [] - -/^\p{Xwd}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}+?/8 - \x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}{2,9}/8 - A_B12\x{6ca}\x{a6c}\x{10a7} - -/^\p{Xwd}{2,9}?/8 - \x{6ca}\x{a6c}\x{10a7}_ - -/^[\p{Xwd}]/8 - ABCD1234_ - 1234abcd_ - \x{6ca} - \x{a6c} - \x{10a7} - _ABC - ** Failers - [] - -/^[\p{Xwd}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/-- A check not in UTF-8 mode --/ - -/^[\p{Xwd}]+/ - ABCD1234_ - -/-- Some negative checks --/ - -/^[\P{Xwd}]+/8 - !.+\x{019}\x{35a}AB - -/^[\p{^Xwd}]+/8 - !.+\x{019}\x{35a}AB - -/[\D]/WBZ8 - 1\x{3c8}2 - -/[\d]/WBZ8 - >\x{6f4}< - -/[\S]/WBZ8 - \x{1680}\x{6f4}\x{1680} - -/[\s]/WBZ8 - >\x{1680}< - -/[\W]/WBZ8 - A\x{1712}B - -/[\w]/WBZ8 - >\x{1723}< - -/\D/WBZ8 - 1\x{3c8}2 - -/\d/WBZ8 - >\x{6f4}< - -/\S/WBZ8 - \x{1680}\x{6f4}\x{1680} - -/\s/WBZ8 - >\x{1680}> - -/\W/WBZ8 - A\x{1712}B - -/\w/WBZ8 - >\x{1723}< - -/[[:alpha:]]/WBZ - -/[[:lower:]]/WBZ - -/[[:upper:]]/WBZ - -/[[:alnum:]]/WBZ - -/[[:ascii:]]/WBZ - -/[[:blank:]]/WBZ - -/[[:cntrl:]]/WBZ - -/[[:digit:]]/WBZ - -/[[:graph:]]/WBZ - -/[[:print:]]/WBZ - -/[[:punct:]]/WBZ - -/[[:space:]]/WBZ - -/[[:word:]]/WBZ - -/[[:xdigit:]]/WBZ - -/-- Unicode properties for \b abd \B --/ - -/\b...\B/8W - abc_ - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ - -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ - -/\b...\B/8 - abc_ - ** Failers - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ - -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ - -/\b...\B/W - abc_ - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ - -/-- POSIX interface --/ - -/\w/P - +++\x{c2} - -/\w/WP - +++\x{c2} - -/-- Some of these are silly, but they check various combinations --/ - -/[[:^alpha:][:^cntrl:]]+/8WBZ - 123 - abc - -/[[:^cntrl:][:^alpha:]]+/8WBZ - 123 - abc - -/[[:alpha:]]+/8WBZ - abc - -/[[:^alpha:]\S]+/8WBZ - 123 - abc - -/[^\d]+/8WBZ - abc123 - abc\x{123} - \x{660}abc - -/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI - \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} - \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} - -/\p{Xps}*/SI - -/\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ - -/\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ - -/\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ - -/\p{Han}+X\p{Greek}+\x{370}/BZ8 - -/\p{Xan}+!\p{Xan}+A/BZ - -/\p{Xsp}+!\p{Xsp}\t/BZ - -/\p{Xps}+!\p{Xps}\t/BZ - -/\p{Xwd}+!\p{Xwd}_/BZ - -/A+\p{N}A+\dB+\p{N}*B+\d*/WBZ /-- End of testinput12 --/ diff -Nru pcre3-8.12/testdata/testinput13 pcre3-8.31/testdata/testinput13 --- pcre3-8.12/testdata/testinput13 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput13 2011-12-28 16:57:55.000000000 +0000 @@ -0,0 +1,9 @@ +/-- This test is run only when JIT support is not available. It checks that an +attempt to use it has the expected behaviour. It also tests things that +are different without JIT. --/ + +/abc/S+I + +/a*/SI + +/-- End of testinput13 --/ diff -Nru pcre3-8.12/testdata/testinput14 pcre3-8.31/testdata/testinput14 --- pcre3-8.12/testdata/testinput14 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput14 2012-06-17 16:24:30.000000000 +0000 @@ -0,0 +1,327 @@ +/-- This set of tests is run only with the 8-bit library. It starts with all + the tests of the POSIX interface, because that is supported only with the + 8-bit library. --/ + +/abc/P + abc + *** Failers + +/^abc|def/P + abcdef + abcdef\B + +/.*((abc)$|(def))/P + defabc + \Zdefabc + +/the quick brown fox/P + the quick brown fox + *** Failers + The Quick Brown Fox + +/the quick brown fox/Pi + the quick brown fox + The Quick Brown Fox + +/abc.def/P + *** Failers + abc\ndef + +/abc$/P + abc + abc\n + +/(abc)\2/P + +/(abc\1)/P + abc + +/a*(b+)(z)(z)/P + aaaabbbbzzzz + aaaabbbbzzzz\O0 + aaaabbbbzzzz\O1 + aaaabbbbzzzz\O2 + aaaabbbbzzzz\O3 + aaaabbbbzzzz\O4 + aaaabbbbzzzz\O5 + +/ab.cd/P + ab-cd + ab=cd + ** Failers + ab\ncd + +/ab.cd/Ps + ab-cd + ab=cd + ab\ncd + +/a(b)c/PN + abc + +/a(?Pb)c/PN + abc + +/a?|b?/P + abc + ** Failers + ddd\N + +/\w+A/P + CDAAAAB + +/\w+A/PU + CDAAAAB + +/\Biss\B/I+P + Mississippi + +/abc/\P + +/-- End of POSIX tests --/ + +/a\Cb/ + aXb + a\nb + ** Failers (too big char) + A\x{123}B + +/\x{100}/I + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI + +/-- Although this saved pattern was compiled with link-size=2, it does no harm +to run this test with other link sizes because it is going to generated a +"compiled in wrong mode" error as soon as it is loaded, so the link size does +not matter. --/ + +\x09< + +/[\h]+/BZ + >\x09\x20\xa0< + +/[\v]/BZ + +/[\H]/BZ + +/[^\h]/BZ + +/[\V]/BZ + +/[\x0a\V]/BZ + +/\777/I + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K + XX + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K + XX + +/\u0100/ + +/[\u0100-\u0200]/ + +/-- End of testinput14 --/ diff -Nru pcre3-8.12/testdata/testinput15 pcre3-8.31/testdata/testinput15 --- pcre3-8.12/testdata/testinput15 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput15 2012-06-17 16:49:18.000000000 +0000 @@ -0,0 +1,316 @@ +/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit + library. --/ + +/X(\C{3})/8 + X\x{1234} + +/X(\C{4})/8 + X\x{1234}YZ + +/X\C*/8 + XYZabcdce + +/X\C*?/8 + XYZabcde + +/X\C{3,5}/8 + Xabcdefg + X\x{1234} + X\x{1234}YZ + X\x{1234}\x{512} + X\x{1234}\x{512}YZ + +/X\C{3,5}?/8 + Xabcdefg + X\x{1234} + X\x{1234}YZ + X\x{1234}\x{512} + +/a\Cb/8 + aXb + a\nb + +/a\C\Cb/8 + a\x{100}b + +/ab\Cde/8 + abXde + +/a\C\Cb/8 + a\x{100}b + ** Failers + a\x{12257}b + +/[Ã]/8 + +/Ã/8 + +/ÃÃÃxxx/8 + +/ÃÃÃxxx/8?DZSS + +/abc/8 + Ã] + Ã + ÃÃÃ + ÃÃÃ\? + \xe1\x88 + \P\xe1\x88 + \P\P\xe1\x88 + XX\xea + \O0XX\xea + \O1XX\xea + \O2XX\xea + XX\xf1 + XX\xf8 + XX\xfc + ZZ\xea\xaf\x20YY + ZZ\xfd\xbf\xbf\x2f\xbf\xbfYY + ZZ\xfd\xbf\xbf\xbf\x2f\xbfYY + ZZ\xfd\xbf\xbf\xbf\xbf\x2fYY + ZZ\xffYY + ZZ\xfeYY + +/anything/8 + \xc0\x80 + \xc1\x8f + \xe0\x9f\x80 + \xf0\x8f\x80\x80 + \xf8\x87\x80\x80\x80 + \xfc\x83\x80\x80\x80\x80 + \xfe\x80\x80\x80\x80\x80 + \xff\x80\x80\x80\x80\x80 + \xc3\x8f + \xe0\xaf\x80 + \xe1\x80\x80 + \xf0\x9f\x80\x80 + \xf1\x8f\x80\x80 + \xf8\x88\x80\x80\x80 + \xf9\x87\x80\x80\x80 + \xfc\x84\x80\x80\x80\x80 + \xfd\x83\x80\x80\x80\x80 + \?\xf8\x88\x80\x80\x80 + \?\xf9\x87\x80\x80\x80 + \?\xfc\x84\x80\x80\x80\x80 + \?\xfd\x83\x80\x80\x80\x80 + +/\x{100}/8DZ + +/\x{1000}/8DZ + +/\x{10000}/8DZ + +/\x{100000}/8DZ + +/\x{10ffff}/8DZ + +/[\x{ff}]/8DZ + +/[\x{100}]/8DZ + +/\x80/8DZ + +/\xff/8DZ + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 + \x{D55c}\x{ad6d}\x{C5B4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 + \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 + +/\x{084}/DZ8 + +/\x{104}/DZ8 + +/\x{861}/DZ8 + +/\x{212ab}/DZ8 + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + X\nabc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers + a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ + \x{f1} + \x{bf} + \x{100} + \x{1000} + *** Failers + \x{c0} + \x{f0} + +/Ä€{3,4}/8SDZ + \x{100}\x{100}\x{100}\x{100\x{100} + +/(\x{100}+|x)/8SDZ + +/(\x{100}*a|x)/8SDZ + +/(\x{100}{0,2}a|x)/8SDZ + +/(\x{100}{1,2}a|x)/8SDZ + +/\x{100}/8DZ + +/a\x{100}\x{101}*/8DZ + +/a\x{100}\x{101}+/8DZ + +/[^\x{c4}]/DZ + +/[\x{100}]/8DZ + \x{100} + Z\x{100} + \x{100}Z + *** Failers + +/[\xff]/DZ8 + >\x{ff}< + +/[^\xff]/8DZ + +/\x{100}abc(xyz(?1))/8DZ + +/a\x{1234}b/P8 + a\x{1234}b + +/\777/8I + \x{1ff} + \777 + +/\x{100}+\x{200}/8DZ + +/\x{100}+X/8DZ + +/^[\QÄ€\E-\QÅ\E/BZ8 + +/-- This tests the stricter UTF-8 check according to RFC 3629. --/ + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} + \x{d800} + \x{d800}\? + \x{da00} + \x{da00}\? + \x{dfff} + \x{dfff}\? + \x{110000} + \x{110000}\? + \x{2000000} + \x{2000000}\? + \x{7fffffff} + \x{7fffffff}\? + +/(*UTF8)\x{1234}/ + abcd\x{1234}pqr + +/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I + +/\h/SI8 + ABC\x{09} + ABC\x{20} + ABC\x{a0} + ABC\x{1680} + ABC\x{180e} + ABC\x{2000} + ABC\x{202f} + ABC\x{205f} + ABC\x{3000} + +/\v/SI8 + ABC\x{0a} + ABC\x{0b} + ABC\x{0c} + ABC\x{0d} + ABC\x{85} + ABC\x{2028} + +/\h*A/SI8 + CDBABC + +/\v+A/SI8 + +/\s?xxx\s/8SI + +/\sxxx\s/I8ST1 + AB\x{85}xxx\x{a0}XYZ + AB\x{a0}xxx\x{85}XYZ + +/\S \S/I8ST1 + \x{a2} \x{84} + A Z + +/a+/8 + a\x{123}aa\>1 + a\x{123}aa\>2 + a\x{123}aa\>3 + a\x{123}aa\>4 + a\x{123}aa\>5 + a\x{123}aa\>6 + +/\x{1234}+/iS8I + +/\x{1234}+?/iS8I + +/\x{1234}++/iS8I + +/\x{1234}{2}/iS8I + +/[^\x{c4}]/8DZ + +/X+\x{200}/8DZ + +/\R/SI8 + +/\777/8DZ + +/\w+\x{C4}/8BZ + a\x{C4}\x{C4} + +/\w+\x{C4}/8BZT1 + a\x{C4}\x{C4} + +/\W+\x{C4}/8BZ + !\x{C4} + +/\W+\x{C4}/8BZT1 + !\x{C4} + +/\W+\x{A1}/8BZ + !\x{A1} + +/\W+\x{A1}/8BZT1 + !\x{A1} + +/X\s+\x{A0}/8BZ + X\x20\x{A0}\x{A0} + +/X\s+\x{A0}/8BZT1 + X\x20\x{A0}\x{A0} + +/\S+\x{A0}/8BZ + X\x{A0}\x{A0} + +/\S+\x{A0}/8BZT1 + X\x{A0}\x{A0} + +/\x{a0}+\s!/8BZ + \x{a0}\x20! + +/\x{a0}+\s!/8BZT1 + \x{a0}\x20! + +/-- End of testinput15 --/ diff -Nru pcre3-8.12/testdata/testinput16 pcre3-8.31/testdata/testinput16 --- pcre3-8.12/testdata/testinput16 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput16 2011-12-28 16:57:55.000000000 +0000 @@ -0,0 +1,35 @@ +/-- This set of tests is run only with the 8-bit library when Unicode property + support is available. It starts with tests of the POSIX interface, because + that is supported only with the 8-bit library. --/ + +/\w/P + +++\x{c2} + +/\w/WP + +++\x{c2} + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZi + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ + +/[^â±¥]/8iBZ + +/\h/SI + +/\v/SI + +/\R/SI + +/[[:blank:]]/WBZ + +/-- End of testinput16 --/ diff -Nru pcre3-8.12/testdata/testinput17 pcre3-8.31/testdata/testinput17 --- pcre3-8.12/testdata/testinput17 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput17 2012-06-17 16:50:13.000000000 +0000 @@ -0,0 +1,295 @@ +/-- This set of tests is for the 16-bit library's basic (non-UTF-16) features + that are not compatible with the 8-bit library, or which give different + output in 16-bit mode. --/ + +/a\Cb/ + aXb + a\nb + +/-- Check maximum non-UTF character size --/ + +/\x{ffff}/ + A\x{ffff}B + +/\x{10000}/ + +/[^\x{c4}]/DZ + + +/\x{100}/I + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI + +/[\h]/BZ + >\x09< + +/[\h]+/BZ + >\x09\x20\xa0< + +/[\v]/BZ + +/[\H]/BZ + +/[^\h]/BZ + +/[\V]/BZ + +/[\x0a\V]/BZ + +/\h+/SI + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + +/[\h\x{dc00}]+/BZSI + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + +/\H+/SI + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + +/[\H\x{d800}]+/BZSI + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + +/\v+/SI + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + +/[\v\x{dc00}]+/BZSI + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + +/\V+/SI + \x{2028}\x{2029}\x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + +/[\V\x{d800}]+/BZSI + \x{2028}\x{2029}\x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + +/\R+/SI + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + +/\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I + \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K + XX + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K + XX + +/\u0100/BZ + +/[\u0100-\u0200]/BZ + +/\ud800/BZ + +/-- End of testinput17 --/ diff -Nru pcre3-8.12/testdata/testinput18 pcre3-8.31/testdata/testinput18 --- pcre3-8.12/testdata/testinput18 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput18 2012-07-06 08:52:35.000000000 +0000 @@ -0,0 +1,284 @@ +/-- This set of tests is for UTF-16 support, and is relevant only to the 16-bit + library. --/ + +/ÃÃÃxxx/8?DZSS + +/abc/8 + Ã] + +/X(\C{3})/8 + X\x{11234}Y + +/X(\C{4})/8 + X\x{11234}YZ + +/X\C*/8 + XYZabcdce + +/X\C*?/8 + XYZabcde + +/X\C{3,5}/8 + Xabcdefg + X\x{11234}Y + X\x{11234}YZ + X\x{11234}\x{512} + X\x{11234}\x{512}YZ + X\x{11234}\x{512}\x{11234}Z + +/X\C{3,5}?/8 + Xabcdefg + X\x{11234}Y + X\x{11234}YZ + X\x{11234}\x{512}YZ + *** Failers + X\x{11234} + +/a\Cb/8 + aXb + a\nb + +/a\C\Cb/8 + a\x{12257}b + ** Failers + a\x{100}b + +/ab\Cde/8 + abXde + +/-- Check maximum character size --/ + +/\x{ffff}/8DZ + +/\x{10000}/8DZ + +/\x{100}/8DZ + +/\x{1000}/8DZ + +/\x{10000}/8DZ + +/\x{100000}/8DZ + +/\x{10ffff}/8DZ + +/[\x{ff}]/8DZ + +/[\x{100}]/8DZ + +/\x80/8DZ + +/\xff/8DZ + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 + \x{D55c}\x{ad6d}\x{C5B4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 + \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 + +/\x{084}/DZ8 + +/\x{104}/DZ8 + +/\x{861}/DZ8 + +/\x{212ab}/DZ8 + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + X\nabc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers + a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ + \x{f1} + \x{bf} + \x{100} + \x{1000} + *** Failers + \x{c0} + \x{f0} + +/Ä€{3,4}/8SDZ + \x{100}\x{100}\x{100}\x{100\x{100} + +/(\x{100}+|x)/8SDZ + +/(\x{100}*a|x)/8SDZ + +/(\x{100}{0,2}a|x)/8SDZ + +/(\x{100}{1,2}a|x)/8SDZ + +/\x{100}/8DZ + +/a\x{100}\x{101}*/8DZ + +/a\x{100}\x{101}+/8DZ + +/[^\x{c4}]/DZ + +/[\x{100}]/8DZ + \x{100} + Z\x{100} + \x{100}Z + *** Failers + +/[\xff]/DZ8 + >\x{ff}< + +/[^\xff]/8DZ + +/\x{100}abc(xyz(?1))/8DZ + +/\777/8I + \x{1ff} + \777 + +/\x{100}+\x{200}/8DZ + +/\x{100}+X/8DZ + +/^[\QÄ€\E-\QÅ\E/BZ8 + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} + \x{d800} + \x{d800}\? + \x{da00} + \x{da00}\? + \x{dc00} + \x{dc00}\? + \x{de00} + \x{de00}\? + \x{dfff} + \x{dfff}\? + \x{110000} + \x{d800}\x{1234} + \x{fffe} + +/(*UTF16)\x{11234}/ + abcd\x{11234}pqr + +/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I + +/\h/SI8 + ABC\x{09} + ABC\x{20} + ABC\x{a0} + ABC\x{1680} + ABC\x{180e} + ABC\x{2000} + ABC\x{202f} + ABC\x{205f} + ABC\x{3000} + +/\v/SI8 + ABC\x{0a} + ABC\x{0b} + ABC\x{0c} + ABC\x{0d} + ABC\x{85} + ABC\x{2028} + +/\h*A/SI8 + CDBABC + \x{2000}ABC + +/\R*A/SI8 + CDBABC + \x{2028}A + +/\v+A/SI8 + +/\s?xxx\s/8SI + +/\sxxx\s/I8ST1 + AB\x{85}xxx\x{a0}XYZ + AB\x{a0}xxx\x{85}XYZ + +/\S \S/I8ST1 + \x{a2} \x{84} + A Z + +/a+/8 + a\x{123}aa\>1 + a\x{123}aa\>2 + a\x{123}aa\>3 + a\x{123}aa\>4 + a\x{123}aa\>5 + a\x{123}aa\>6 + +/\x{1234}+/iS8I + +/\x{1234}+?/iS8I + +/\x{1234}++/iS8I + +/\x{1234}{2}/iS8I + +/[^\x{c4}]/8DZ + +/X+\x{200}/8DZ + +/\R/SI8 + +/-- Check bad offset --/ + +/a/8 + \x{10000}\>1 + \x{10000}ab\>2 + \x{10000}ab\>3 + \x{10000}ab\>4 + \x{10000}ab\>5 + +/í¼€/8 + +/\w+\x{C4}/8BZ + a\x{C4}\x{C4} + +/\w+\x{C4}/8BZT1 + a\x{C4}\x{C4} + +/\W+\x{C4}/8BZ + !\x{C4} + +/\W+\x{C4}/8BZT1 + !\x{C4} + +/\W+\x{A1}/8BZ + !\x{A1} + +/\W+\x{A1}/8BZT1 + !\x{A1} + +/X\s+\x{A0}/8BZ + X\x20\x{A0}\x{A0} + +/X\s+\x{A0}/8BZT1 + X\x20\x{A0}\x{A0} + +/\S+\x{A0}/8BZ + X\x{A0}\x{A0} + +/\S+\x{A0}/8BZT1 + X\x{A0}\x{A0} + +/\x{a0}+\s!/8BZ + \x{a0}\x20! + +/\x{a0}+\s!/8BZT1 + \x{a0}\x20! + +/-- End of testinput18 --/ diff -Nru pcre3-8.12/testdata/testinput19 pcre3-8.31/testdata/testinput19 --- pcre3-8.12/testdata/testinput19 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput19 2011-12-28 16:57:55.000000000 +0000 @@ -0,0 +1,22 @@ +/-- This set of tests is for Unicode property support, relevant only to the + 16-bit library. --/ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZ + +/AB\x{1fb0}/8DZi + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ + +/[^â±¥]/8iBZ + +/[[:blank:]]/WBZ + +/-- End of testinput19 --/ diff -Nru pcre3-8.12/testdata/testinput2 pcre3-8.31/testdata/testinput2 --- pcre3-8.12/testdata/testinput2 2010-11-23 15:27:07.000000000 +0000 +++ pcre3-8.31/testdata/testinput2 2012-06-17 16:45:12.000000000 +0000 @@ -3,12 +3,11 @@ It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl - bug. --/ + bug. + + NOTE: This is a non-UTF set of tests. When UTF support is needed, use + test 5, and if Unicode Property Support is needed, use test 7. --/ -/-- Originally, the Perl >= 5.10 things were in here too, but now I have - separated many (most?) of them out into test 11. However, there may still - be some that were overlooked. --/ - /(a)b|/I /abc/I @@ -144,40 +143,6 @@ defabc \Zdefabc -/abc/P - abc - *** Failers - -/^abc|def/P - abcdef - abcdef\B - -/.*((abc)$|(def))/P - defabc - \Zdefabc - -/the quick brown fox/P - the quick brown fox - *** Failers - The Quick Brown Fox - -/the quick brown fox/Pi - the quick brown fox - The Quick Brown Fox - -/abc.def/P - *** Failers - abc\ndef - -/abc$/P - abc - abc\n - -/(abc)\2/P - -/(abc\1)/P - abc - /)/ /a[]b/ @@ -442,8 +407,6 @@ /abc/\ -/abc/\P - /abc/\i /(a)bc(d)/I @@ -491,9 +454,6 @@ /\Biss\B/I+ Mississippi -/\Biss\B/I+P - Mississippi - /iss/IG+ Mississippi @@ -629,15 +589,6 @@ *** Failers \Nabc -/a*(b+)(z)(z)/P - aaaabbbbzzzz - aaaabbbbzzzz\O0 - aaaabbbbzzzz\O1 - aaaabbbbzzzz\O2 - aaaabbbbzzzz\O3 - aaaabbbbzzzz\O4 - aaaabbbbzzzz\O5 - /^.?abcd/IS /\( # ( at start @@ -1061,7 +1012,12 @@ /abc(?C)de(?C1)f/I 123abcdef -/(?C1)\dabc(?C2)def/I +/(?C1)\dabc(?C2)def/IS + 1234abcdef + *** Failers + abcdef + +/(?C1)\dabc(?C2)def/ISS 1234abcdef *** Failers abcdef @@ -1310,7 +1266,12 @@ abcde abcdfe -/a*b/ICDZ +/a*b/ICDZS + ab + aaaab + aaaacb + +/a*b/ICDZSS ab aaaab aaaacb @@ -1320,9 +1281,16 @@ aaaab aaaacb -/(abc|def)x/ICDZ +/(abc|def)x/ICDZS abcx defx + ** Failers + abcdefzx + +/(abc|def)x/ICDZSS + abcx + defx + ** Failers abcdefzx /(ab|cd){3,4}/IC @@ -1330,7 +1298,10 @@ abcdabcd abcdcdcdcdcd -/([ab]{,4}c|xy)/ICDZ +/([ab]{,4}c|xy)/ICDZS + Note: that { does NOT introduce a quantifier + +/([ab]{,4}c|xy)/ICDZSS Note: that { does NOT introduce a quantifier /([ab]{1,4}c|xy){4,5}?123/ICDZ @@ -1404,13 +1375,25 @@ 1X 123456\P -/abc/I>testsavedregex +/abc/IS>testsavedregex +testsavedregex testsavedregex +/abc/IFS>testsavedregex +testsavedregex testsavedregex +testsavedregex testsavedregex +(.)*~smgI - \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n /^a/IF @@ -1447,17 +1442,6 @@ ** Failers line one\nthis is a line\nbreak in the second line -/ab.cd/P - ab-cd - ab=cd - ** Failers - ab\ncd - -/ab.cd/Ps - ab-cd - ab=cd - ab\ncd - /(?i)(?-i)AbCd/I AbCd ** Failers @@ -1508,14 +1492,6 @@ (this) ((this)) -/a(b)c/PN - abc - -/a(?Pb)c/PN - abc - -/\x{100}/I - /\x{0000ff}/I /^((?Pa1)|(?Pa2)b)/I @@ -1593,8 +1569,6 @@ /()()()()()()()()()(?:(?(A)(?P=A)a|b)(?PX|Y))+/I bXXaYYaY -/\777/I - /\s*,\s*/IS \x0b,\x0b \x0c,\x0d @@ -1976,8 +1950,6 @@ /(?(DEFINE) abc) xyz/xI -/(?(DEFINE) abc){3} xyz/x - /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 @@ -2199,22 +2171,6 @@ xabcpqrx xxyzx -/[\h]/BZ - >\x09< - -/[\h]+/BZ - >\x09\x20\xa0< - -/[\v]/BZ - -/[\H]/BZ - -/[^\h]/BZ - -/[\V]/BZ - -/[\x0a\V]/BZ - /\H++X/BZ ** Failers XXXX @@ -2255,7 +2211,7 @@ /\V+\v\V+\w/BZ /\( (?: [^()]* | (?R) )* \)/x -(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) +\J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ @@ -2295,7 +2251,7 @@ /\g6666666666/ -/[\g6666666666]/ +/[\g6666666666]/BZ /(?1)\c[/ @@ -2453,6 +2409,10 @@ /\k{}/ +/\k/ + +/\kabc/ + /(?P=)/ /(?P>)/ @@ -2570,11 +2530,6 @@ /(?(?=.*b).*b|^d)/I -/a?|b?/P - abc - ** Failers - ddd\N - /xyz/C xyz abcxyz @@ -2766,12 +2721,6 @@ abc\P abc\P\P -/\w+A/P - CDAAAAB - -/\w+A/PU - CDAAAAB - /abc\K123/ xyzabc123pqr xyzabc12\P @@ -2915,201 +2864,6 @@ /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI -/ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional leading comment -(?: (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # one word, optionally followed by.... -(?: -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... -\( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) | # comments, or... - -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -# quoted strings -)* -< (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # leading < -(?: @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* - -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* , (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -)* # further okay, if led by comma -: # closing colon -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* )? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address spec -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* > # trailing > -# name and address -) (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional trailing comment -/xSI - /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS "(?>.*/)foo"SI @@ -3276,104 +3030,19 @@ /A(*PRUNE)B|A(*PRUNE)C/K AC -/--- A whole lot of tests of verbs with arguments are here rather than in test - 11 because Perl doesn't seem to follow its specification entirely - correctly. ---/ - -/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is - not clear how Perl defines "involved in the failure of the match". ---/ - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - AB - CD - ** Failers - AC - CB - -/--- Check the use of names for success and failure. PCRE doesn't show these -names for success, though Perl does, contrary to its spec. ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - AB - CD - ** Failers - AC - CB - -/--- An empty name does not pass back an empty string. It is the same as if no -name were given. ---/ - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K - AB - CD - -/--- PRUNE goes to next bumpalong; COMMIT does not. ---/ - -/A(*PRUNE:A)B/K - ACAB - -/(*MARK:A)(*PRUNE:B)(C|X)/K - C - D - -/(*MARK:A)(*THEN:B)(C|X)/K - C - D - -/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/ - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK - AAAC - -/--- Same --/ - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK - AAAC - /--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. ---/ + PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC -/A(*:A)A+(*SKIP)(B|Z) | AC/xK - AAAC - -/--- This should fail, as a null name is the same as no name ---/ - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK - AAAC - -/--- This fails in PCRE, and I think that is in accordance with Perl's - documentation, though in Perl it succeeds. ---/ - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK - AAAC - -/--- Mark names can be duplicated ---/ +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ -/A(*:A)B|X(*:A)Y/K - AABC - XXYZ - /^A(*:A)B|^X(*:A)Y/K ** Failers XAQQ -/--- A check on what happens after hitting a mark and them bumping along to -something that does not even start. Perl reports tags after the failures here, -though it does not when the individual letters are made into something -more complicated. ---/ - -/A(*:A)B|XX(*:B)Y/K - AABC - XXYZ - ** Failers - XAQQ - XAQQXZZ - AXQQQ - AXXQQQ - /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ @@ -3383,78 +3052,6 @@ ** Failers DEFGABC\Y -/--- Repeat some tests with added studying. ---/ - -/A(*COMMIT)B/+KS - ACABX - -/A(*THEN)B|A(*THEN)C/KS - AC - -/A(*PRUNE)B|A(*PRUNE)C/KS - AC - -/^(A(*THEN:A)B|C(*THEN:B)D)/KS - AB - CD - ** Failers - AC - CB - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS - AB - CD - ** Failers - AC - CB - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS - AB - CD - -/A(*PRUNE:A)B/KS - ACAB - -/(*MARK:A)(*PRUNE:B)(C|X)/KS - C - D - -/(*MARK:A)(*THEN:B)(C|X)/KS - C - D - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS - AAAC - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS - AAAC - -/A(*:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS - AAAC - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS - AAAC - -/A(*:A)B|XX(*:B)Y/KS - AABC - XXYZ - ** Failers - XAQQ - XAQQXZZ - AXQQQ - AXXQQQ - -/(*COMMIT)ABC/ - ABCDEFG - ** Failers - DEFGABC\Y - /^(ab (c+(*THEN)cd) | xyz)/x abcccd @@ -3505,6 +3102,24 @@ /\d*\R/BZ /\s*\R/BZ + \x20\x0a + \x20\x0d + \x20\x0d\x0a + +/\S*\R/BZ + a\x0a + +/X\h*\R/BZ + X\x20\x0a + +/X\H*\R/BZ + X\x0d\x0a + +/X\H+\R/BZ + X\x0d\x0a + +/X\H++\R/BZ + X\x0d\x0a /-- Perl treats this one differently, not failing the second string. I believe that is a bug in Perl. --/ @@ -3570,4 +3185,588 @@ /(?P(?P=axn)xxx)(?yy)/BZ +/-- These tests are here because Perl gets the first one wrong. --/ + +/(\R*)(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/(\R)*(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/-- --/ + +/^abc$/BZ + +/^abc$/BZm + +/^(a)*+(\w)/S + aaaaX + ** Failers + aaaa + +/^(?:a)*+(\w)/S + aaaaX + ** Failers + aaaa + +/(a)++1234/SDZ + +/([abc])++1234/SI + +/(?<=(abc)+)X/ + +/(^ab)/I + +/(^ab)++/I + +/(^ab|^)+/I + +/(^ab|^)++/I + +/(?:^ab)/I + +/(?:^ab)++/I + +/(?:^ab|^)+/I + +/(?:^ab|^)++/I + +/(.*ab)/I + +/(.*ab)++/I + +/(.*ab|.*)+/I + +/(.*ab|.*)++/I + +/(?:.*ab)/I + +/(?:.*ab)++/I + +/(?:.*ab|.*)+/I + +/(?:.*ab|.*)++/I + +/(?=a)[bcd]/I + +/((?=a))[bcd]/I + +/((?=a))+[bcd]/I + +/((?=a))++[bcd]/I + +/(?=a+)[bcd]/iI + +/(?=a+?)[bcd]/iI + +/(?=a++)[bcd]/iI + +/(?=a{3})[bcd]/iI + +/(abc)\1+/S + +/-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ + +/(?1)(?:(b(*ACCEPT))){0}/ + b + +/(?1)(?:(b(*ACCEPT))){0}c/ + bc + ** Failers + b + +/(?1)(?:((*ACCEPT))){0}c/ + c + c\N + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba + +/^.*?(?(?=a)a|bc)/ + ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac + +/^.*?(?(?=a)a(*THEN)b)c/ + ac + +/^.*?(a(*THEN)b)c/ + aabc + +/^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x + aabc + +/^.*?(a(*THEN)b|z)c/ + aabc + +/^.*?(z|a(*THEN)b)c/ + aabc + +/-- --/ + +/-- These studied versions are here because they are not Perl-compatible; the + studying means the mark is not seen. --/ + +/(*MARK:A)(*SKIP:B)(C|X)/KS + C + D + +/(*:A)A+(*SKIP:A)(B|Z)/KS + AAAC + +/-- --/ + +"(?=a*(*ACCEPT)b)c" + c + c\N + +/(?1)c(?(DEFINE)((*ACCEPT)b))/ + c + c\N + +/(?>(*ACCEPT)b)c/ + c + c\N + +/(?:(?>(a)))+a%/++ + %aa% + +/(a)b|ac/++SS + ac\O3 + +/(a)(b)x|abc/++ + abc\O6 + +/(a)bc|(a)(b)\2/ + \O3abc + \O4abc + +/(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI + +/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI + +/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI + +/(abc)(?1)/SI + +/^(?>a)++/ + aa\M + aaaaaaaaa\M + +/(a)(?1)++/ + aa\M + aaaaaaaaa\M + +/(?:(foo)|(bar)|(baz))X/SS= + bazfooX + foobazbarX + barfooX + bazX + foobarbazX + bazfooX\O0 + bazfooX\O2 + bazfooX\O4 + bazfooX\O6 + bazfooX\O8 + bazfooX\O10 + +/(?=abc){3}abc/BZ + +/(?=abc)+abc/BZ + +/(?=abc)++abc/BZ + +/(?=abc){0}xyz/BZ + +/(?=(a))?./BZ + +/(?=(a))??./BZ + +/^(?=(a)){0}b(?1)/BZ + +/(?(DEFINE)(a))?b(?1)/BZ + +/^(?=(?1))?[az]([abc])d/BZ + +/^(?!a){0}\w+/BZ + +/(?<=(abc))?xyz/BZ + +/[:a[:abc]b:]/BZ + +/((?2))((?1))/SS + abc + +/((?(R2)a+|(?1)b))/SS + aaaabcde + +/(?(R)a*(?1)|((?R))b)/SS + aaaabcde + +/(a+|(?R)b)/ + +/^(a(*:A)(d|e(*:B))z|aeq)/C + adz + aez + aeqwerty + +/.(*F)/ + \P\Pabc + +/\btype\b\W*?\btext\b\W*?\bjavascript\b/IS + +/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ + aaaazzzzb + ** Failers + aazz + +/(.)(\1|a(?2))/ + bab + +/\1|(.)(?R)\1/ + cbbbc + +/(.)((?(1)c|a)|a(?2))/ + baa + +/(?P(?P=abn)xxx)/BZ + +/(a\1z)/BZ + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + \Maabbccddee + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + \Maabbccddee + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + \Maabbccddee + +/^a\x41z/ + aAz + *** Failers + ax41z + +/^a[m\x41]z/ + aAz + +/^a\x1z/ + ax1z + +/^a\u0041z/ + aAz + *** Failers + au0041z + +/^a[m\u0041]z/ + aAz + +/^a\u041z/ + au041z + *** Failers + aAz + +/^a\U0041z/ + aU0041z + *** Failers + aAz + +/(?(?=c)c|d)++Y/BZ + +/(?(?=c)c|d)*+Y/BZ + +/a[\NB]c/ + aNc + +/a[B-\Nc]/ + +/(a)(?2){0,1999}?(b)/ + +/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ + +/--- This test, with something more complicated than individual letters, causes +different behaviour in Perl. Perhaps it disables some optimization; no tag is +passed back for the failures, whereas in PCRE there is a tag. ---/ + +/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK + AABC + XXYZ + ** Failers + XAQQ + XAQQXZZ + AXQQQ + AXXQQQ + +/-- Perl doesn't give marks for these, though it does if the alternatives are +replaced by single letters. --/ + +/(b|q)(*:m)f|a(*:n)w/K + aw + ** Failers + abc + +/(q|b)(*:m)f|a(*:n)w/K + aw + ** Failers + abc + +/-- After a partial match, the behaviour is as for a failure. --/ + +/^a(*:X)bcde/K + abc\P + +/-- These are here because Perl doesn't return a mark, except for the first --/ + +/(?=(*:x))(q|)/K+ + abc + +/(?=(*:x))((*:y)q|)/K+ + abc + +/(?=(*:x))(?:(*:y)q|)/K+ + abc + +/(?=(*:x))(?>(*:y)q|)/K+ + abc + +/(?=a(*:x))(?!a(*:y)c)/K+ + ab + +/(?=a(*:x))(?=a(*:y)c|)/K+ + ab + +/(..)\1/ + ab\P + aba\P + abab\P + +/(..)\1/i + ab\P + abA\P + aBAb\P + +/(..)\1{2,}/ + ab\P + aba\P + abab\P + ababa\P + ababab\P + ababab\P\P + abababa\P + abababa\P\P + +/(..)\1{2,}/i + ab\P + aBa\P + aBAb\P + AbaBA\P + abABAb\P + aBAbaB\P\P + abABabA\P + abaBABa\P\P + +/(..)\1{2,}?x/i + ab\P + abA\P + aBAb\P + abaBA\P + abAbaB\P + abaBabA\P + abAbABaBx\P + +/^(..)\1/ + aba\P + +/^(..)\1{2,3}x/ + aba\P + ababa\P + ababa\P\P + abababx + ababababx + +/^(..)\1{2,3}?x/ + aba\P + ababa\P + ababa\P\P + abababx + ababababx + +/^(..)(\1{2,3})ab/ + abababab + +/^\R/ + \r\P + \r\P\P + +/^\R{2,3}x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R{2,3}?x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R?x/ + \r\P + \r\P\P + x + \rx + +/^\R+x/ + \r\P + \r\P\P + \r\n\P + \r\n\P\P + \rx + +/^a$/ + a\r\P + a\r\P\P + +/^a$/m + a\r\P + a\r\P\P + +/^(a$|a\r)/ + a\r\P + a\r\P\P + +/^(a$|a\r)/m + a\r\P + a\r\P\P + +/./ + \r\P + \r\P\P + +/.{2,3}/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/-- These two are here because Perl does not match: it seems to allow the +COMMIT to escape from the assertion. --/ + +/(?=a(*COMMIT)b|ac)ac|ac/ + ac + +/(?=a(*COMMIT)b|(ac)) ac | (a)c/x + ac + +"AB(C(D))(E(F))?(?(?=\2)(?=\4))" + ABCDGHI\O03 + +/-- This one is here because Perl does not confine the *COMMIT to the +assertion, and therefore fails the entire subroutine call. --/ + +/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ + ac + /-- End of testinput2 --/ diff -Nru pcre3-8.12/testdata/testinput20 pcre3-8.31/testdata/testinput20 --- pcre3-8.12/testdata/testinput20 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput20 2011-12-28 16:57:51.000000000 +0000 @@ -0,0 +1,19 @@ +/-- These tests are for the handling of characters greater than 255 in 16-bit, + non-UTF-16 mode. --/ + +/^\x{ffff}+/i + \x{ffff} + +/^\x{ffff}?/i + \x{ffff} + +/^\x{ffff}*/i + \x{ffff} + +/^\x{ffff}{3}/i + \x{ffff}\x{ffff}\x{ffff} + +/^\x{ffff}{0,3}/i + \x{ffff} + +/-- End of testinput20 --/ diff -Nru pcre3-8.12/testdata/testinput21 pcre3-8.31/testdata/testinput21 --- pcre3-8.12/testdata/testinput21 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testinput21 2012-01-20 14:11:12.000000000 +0000 @@ -0,0 +1,12 @@ +/-- Tests for reloading pre-compile patterns. The first one gives an error +right away. The others require the linke size to be 2. */ + +(?:[AaLl]+)[^xX-]*?)(?P[\x{150}-\x{250}\x{300}]|[^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$ --/ + +[aZ\x{400}-\x{10ffff}]{4,}[\x{f123}\x{10039}\x{20000}-\x{21234}]?|[A-Cx-z\x{100000}-\x{1000a7}\x{101234}])(?[^az]) --/8 + += 5.10 and both the 8-bit and 16-bit + PCRE libraries. --/ /a.b/8 acb @@ -126,31 +127,6 @@ *** Failers XYZ -/X(\C{3})/8 - X\x{1234} - -/X(\C{4})/8 - X\x{1234}YZ - -/X\C*/8 - XYZabcdce - -/X\C*?/8 - XYZabcde - -/X\C{3,5}/8 - Xabcdefg - X\x{1234} - X\x{1234}YZ - X\x{1234}\x{512} - X\x{1234}\x{512}YZ - -/X\C{3,5}?/8 - Xabcdefg - X\x{1234} - X\x{1234}YZ - X\x{1234}\x{512} - /[^a]+/8g bcd \x{100}aY\x{256}Z @@ -456,17 +432,6 @@ \x{150}X \x{200}X -/a\Cb/ - aXb - a\nb - -/a\Cb/8 - aXb - a\nb - -/a\C\Cb/8 - a\x{100}b - /[z-\x{100}]/8i z Z @@ -644,4 +609,16 @@ /A*/g8 AAB\x{123}BAA +/(abc)\1/8i + abc + +/(abc)\1/8 + abc + +/a(*:a\x{1234}b)/8K + abc + +/a(*:a£b)/8K + abc + /-- End of testinput4 --/ diff -Nru pcre3-8.12/testdata/testinput5 pcre3-8.31/testdata/testinput5 --- pcre3-8.12/testdata/testinput5 2010-11-20 17:25:04.000000000 +0000 +++ pcre3-8.31/testdata/testinput5 2012-06-17 16:43:11.000000000 +0000 @@ -1,79 +1,36 @@ -/-- This set of tests checks the API, internals, and non-Perl stuff for UTF-8 - support, excluding Unicode properties. --/ +/-- This set of tests checks the API, internals, and non-Perl stuff for UTF + support, excluding Unicode properties. However, tests that give different + results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ -/\x{100}/8DZ +/\x{110000}/8DZ -/\x{1000}/8DZ - -/\x{10000}/8DZ - -/\x{100000}/8DZ - -/\x{1000000}/8DZ +/\x{ffffffff}/8 -/\x{4000000}/8DZ +/\x{100000000}/8 -/\x{7fffFFFF}/8DZ +/\x{d800}/8 -/[\x{ff}]/8DZ +/\x{dfff}/8 -/[\x{100}]/8DZ +/\x{d7ff}/8 -/\x{ffffffff}/8 - -/\x{100000000}/8 +/\x{e000}/8 /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd -/\x80/8DZ - -/\xff/8DZ - /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 \x{0041}\x{2262}\x{0391}\x{002e} -/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 - \x{D55c}\x{ad6d}\x{C5B4} - -/\x{65e5}\x{672c}\x{8a9e}/DZ8 - \x{65e5}\x{672c}\x{8a9e} - -/\x{80}/DZ8 - -/\x{084}/DZ8 - -/\x{104}/DZ8 - -/\x{861}/DZ8 - -/\x{212ab}/DZ8 - /.{3,5}X/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861}X - /.{3,5}?/DZ8 \x{212ab}\x{212ab}\x{212ab}\x{861} /(?<=\C)X/8 Should produce an error diagnostic -/-- This one is here not because it's different to Perl, but because the way -the captured single-byte is displayed. (In Perl it becomes a character, and you -can't tell the difference.) --/ - -/X(\C)(.*)/8 - X\x{1234} - X\nabc - -/-- This one is here because Perl gives out a grumbly error message (quite -correctly, but that messes up comparisons). --/ - -/a\Cb/8 - *** Failers - a\x{100}b - /^[ab]/8DZ bar *** Failers @@ -88,26 +45,6 @@ *** Failers aaa -/[^ab\xC0-\xF0]/8SDZ - \x{f1} - \x{bf} - \x{100} - \x{1000} - *** Failers - \x{c0} - \x{f0} - -/Ä€{3,4}/8SDZ - \x{100}\x{100}\x{100}\x{100\x{100} - -/(\x{100}+|x)/8SDZ - -/(\x{100}*a|x)/8SDZ - -/(\x{100}{0,2}a|x)/8SDZ - -/(\x{100}{1,2}a|x)/8SDZ - /\x{100}*(\d+|"(?1)")/8 1234 "1234" @@ -118,33 +55,17 @@ *** Failers \x{100}\x{100}abcd -/\x{100}/8DZ - /\x{100}*/8DZ /a\x{100}*/8DZ /ab\x{100}*/8DZ -/a\x{100}\x{101}*/8DZ - -/a\x{100}\x{101}+/8DZ - /\x{100}*A/8DZ A /\x{100}*\d(?R)/8DZ -/[^\x{c4}]/DZ - -/[^\x{c4}]/8DZ - -/[\x{100}]/8DZ - \x{100} - Z\x{100} - \x{100}Z - *** Failers - /[Z\x{100}]/8DZ Z\x{100} \x{100} @@ -169,13 +90,8 @@ /[\xFF]/DZ >\xff< -/[\xff]/DZ8 - >\x{ff}< - /[^\xFF]/DZ -/[^\xff]/8DZ - /[Ä-Ãœ]/8 Ö # Matches without Study \x{d6} @@ -192,48 +108,6 @@ Ö <-- Same with Study \x{d6} -/[Ã]/8 - -/Ã/8 - -/ÃÃÃxxx/8 - -/ÃÃÃxxx/8?DZ - -/abc/8 - Ã] - à - ÃÃà - ÃÃÃ\? - \xe1\x88 - \P\xe1\x88 - \P\P\xe1\x88 - -/anything/8 - \xc0\x80 - \xc1\x8f - \xe0\x9f\x80 - \xf0\x8f\x80\x80 - \xf8\x87\x80\x80\x80 - \xfc\x83\x80\x80\x80\x80 - \xfe\x80\x80\x80\x80\x80 - \xff\x80\x80\x80\x80\x80 - \xc3\x8f - \xe0\xaf\x80 - \xe1\x80\x80 - \xf0\x9f\x80\x80 - \xf1\x8f\x80\x80 - \xf8\x88\x80\x80\x80 - \xf9\x87\x80\x80\x80 - \xfc\x84\x80\x80\x80\x80 - \xfd\x83\x80\x80\x80\x80 - \?\xf8\x88\x80\x80\x80 - \?\xf9\x87\x80\x80\x80 - \?\xfc\x84\x80\x80\x80\x80 - \?\xfd\x83\x80\x80\x80\x80 - -/\x{100}abc(xyz(?1))/8DZ - /[^\x{100}]abc(xyz(?1))/8DZ /[ab\x{100}]abc(xyz(?1))/8DZ @@ -253,17 +127,8 @@ /\w/8 \x{100}X -/a\x{1234}b/P8 - a\x{1234}b - /^\ሴ/8DZ -/\777/I - -/\777/8I - \x{1ff} - \777 - /\x{100}*\d/8DZ /\x{100}*\s/8DZ @@ -276,12 +141,6 @@ /\x{100}*\W/8DZ -/\x{100}+\x{200}/8DZ - -/\x{100}+X/8DZ - -/X+\x{200}/8DZ - /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() @@ -293,8 +152,6 @@ /^[\QÄ€\E-\QÅ\E]/BZ8 -/^[\QÄ€\E-\QÅ\E/BZ8 - /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK @@ -389,23 +246,6 @@ /.*$/8 \x{1ec5} -/-- This tests the stricter UTF-8 check according to RFC 3629. --/ - -/X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} - \x{d800} - \x{d800}\? - \x{da00} - \x{da00}\? - \x{dfff} - \x{dfff}\? - \x{110000} - \x{110000}\? - \x{2000000} - \x{2000000}\? - \x{7fffffff} - \x{7fffffff}\? - /a\Rb/I8 a\rb a\nb @@ -464,16 +304,10 @@ /(\x{de})\1/ \x{de}\x{de} - \x{123} /X/8f A\x{1ec5}ABCXYZ -/(*UTF8)\x{1234}/ - abcd\x{1234}pqr - -/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I - /Xa{2,4}b/8 X\P Xa\P @@ -755,55 +589,13 @@ /X\W{3}X/8 \PX -/\h/SI - -/\h/SI8 - ABC\x{09} - ABC\x{20} - ABC\x{a0} - ABC\x{1680} - ABC\x{180e} - ABC\x{2000} - ABC\x{202f} - ABC\x{205f} - ABC\x{3000} - -/\v/SI - -/\v/SI8 - ABC\x{0a} - ABC\x{0b} - ABC\x{0c} - ABC\x{0d} - ABC\x{85} - ABC\x{2028} - -/\R/SI - -/\R/SI8 - -/\h*A/SI8 - CDBABC - -/\v+A/SI8 - -/\s?xxx\s/8SI - /\sxxx\s/8T1 AB\x{85}xxx\x{a0}XYZ AB\x{a0}xxx\x{85}XYZ -/\sxxx\s/I8ST1 - AB\x{85}xxx\x{a0}XYZ - AB\x{a0}xxx\x{85}XYZ - /\S \S/8T1 \x{a2} \x{84} -/\S \S/I8ST1 - \x{a2} \x{84} - A Z - 'A#хц'8xBZ 'A#хц @@ -819,14 +611,162 @@ /\g{A}xxx#bÑ…(?'A'123) (?'A'456)/8xBZ -/a+/8 - a\x{123}aa\>1 - a\x{123}aa\>2 - a\x{123}aa\>3 - a\x{123}aa\>4 - a\x{123}aa\>5 - a\x{123}aa\>6 - /^\cÄ£/8 +/(\R*)(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/(\R)*(.)/s8 + \r\n + \r\r\n\n\r + \r\r\n\n\r\n + +/[^\x{1234}]+/iS8I + +/[^\x{1234}]+?/iS8I + +/[^\x{1234}]++/iS8I + +/[^\x{1234}]{2}/iS8I + +// + +/f.*/ + \P\Pfor + +/f.*/s + \P\Pfor + +/f.*/8 + \P\Pfor + +/f.*/8s + \P\Pfor + +/\x{d7ff}\x{e000}/8 + +/\x{d800}/8 + +/\x{dfff}/8 + +/\h+/8 + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/[\h\x{e000}]+/8BZ + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + +/\H+/8 + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/[\H\x{d7ff}]+/8BZ + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + +/\v+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/[\v\x{e000}]+/8BZ + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/\V+/8 + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/[\V\x{d7ff}]+/8BZ + \x{2028}\x{2029}\x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + +/(..)\1/8 + ab\P + aba\P + abab\P + +/(..)\1/8i + ab\P + abA\P + aBAb\P + +/(..)\1{2,}/8 + ab\P + aba\P + abab\P + ababa\P + ababab\P + ababab\P\P + abababa\P + abababa\P\P + +/(..)\1{2,}/8i + ab\P + aBa\P + aBAb\P + AbaBA\P + abABAb\P + aBAbaB\P\P + abABabA\P + abaBABa\P\P + +/(..)\1{2,}?x/8i + ab\P + abA\P + aBAb\P + abaBA\P + abAbaB\P + abaBabA\P + abAbABaBx\P + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi + +/(?<=\x{1234}\x{1234})\bxy/I8 + +/(?8BZ + +/[\u0100-\u0200]/8BZ + +/\ud800/8 + /-- End of testinput5 --/ diff -Nru pcre3-8.12/testdata/testinput6 pcre3-8.31/testdata/testinput6 --- pcre3-8.12/testdata/testinput6 2010-10-27 09:25:58.000000000 +0000 +++ pcre3-8.31/testdata/testinput6 2012-02-28 14:28:09.000000000 +0000 @@ -655,6 +655,7 @@ A\x80 /^[\p{Arabic}]/8 + \x{604} \x{60e} \x{656} \x{657} @@ -670,7 +671,6 @@ \x{6ef} \x{6fa} ** Failers - \x{600} \x{650} \x{651} \x{652} @@ -688,7 +688,6 @@ \x{61f} \x{964} \x{965} - \x{970} /^\p{Inherited}/8 \x{64b} @@ -802,4 +801,18 @@ ** Failers a\xFCb +/â±¥/8i + â±¥ + Ⱥx + Ⱥ + +/[â±¥]/8i + â±¥ + Ⱥx + Ⱥ + +/Ⱥ/8i + Ⱥ + â±¥ + /-- End of testinput6 --/ diff -Nru pcre3-8.12/testdata/testinput7 pcre3-8.31/testdata/testinput7 --- pcre3-8.12/testdata/testinput7 2010-11-21 17:39:20.000000000 +0000 +++ pcre3-8.31/testdata/testinput7 2012-06-01 18:22:15.000000000 +0000 @@ -1,4610 +1,625 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ - -/abc/ - abc - -/ab*c/ - abc - abbbbc - ac - -/ab+c/ - abc - abbbbbbc - *** Failers - ac - ab - -/a*/ - a - aaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F - -/(a|abcd|african)/ - a - abcd - african - -/^abc/ - abcdef - *** Failers - xyzabc - xyz\nabc - -/^abc/m - abcdef - xyz\nabc - *** Failers - xyzabc - -/\Aabc/ - abcdef - *** Failers - xyzabc - xyz\nabc - -/\Aabc/m - abcdef - *** Failers - xyzabc - xyz\nabc - -/\Gabc/ - abcdef - xyzabc\>3 - *** Failers - xyzabc - xyzabc\>2 - -/x\dy\Dz/ - x9yzz - x0y+z - *** Failers - xyz - xxy0z - -/x\sy\Sz/ - x yzz - x y+z - *** Failers - xyz - xxyyz - -/x\wy\Wz/ - xxy+z - *** Failers - xxy0z - x+y+z - -/x.y/ - x+y - x-y - *** Failers - x\ny - -/x.y/s - x+y - x-y - x\ny - -/(a.b(?s)c.d|x.y)p.q/ - a+bc+dp+q - a+bc\ndp+q - x\nyp+q - *** Failers - a\nbc\ndp+q - a+bc\ndp\nq - x\nyp\nq - -/a\d\z/ - ba0 - *** Failers - ba0\n - ba0\ncd - -/a\d\z/m - ba0 - *** Failers - ba0\n - ba0\ncd - -/a\d\Z/ - ba0 - ba0\n - *** Failers - ba0\ncd - -/a\d\Z/m - ba0 - ba0\n - *** Failers - ba0\ncd - -/a\d$/ - ba0 - ba0\n - *** Failers - ba0\ncd - -/a\d$/m - ba0 - ba0\n - ba0\ncd - *** Failers - -/abc/i - abc - aBc - ABC - -/[^a]/ - abcd - -/ab?\w/ - abz - abbz - azz - -/x{0,3}yz/ - ayzq - axyzq - axxyz - axxxyzq - axxxxyzq - *** Failers - ax - axx - -/x{3}yz/ - axxxyzq - axxxxyzq - *** Failers - ax - axx - ayzq - axyzq - axxyz - -/x{2,3}yz/ - axxyz - axxxyzq - axxxxyzq - *** Failers - ax - axx - ayzq - axyzq - -/[^a]+/ - bac - bcdefax - *** Failers - aaaaa - -/[^a]*/ - bac - bcdefax - *** Failers - aaaaa - -/[^a]{3,5}/ - xyz - awxyza - abcdefa - abcdefghijk - *** Failers - axya - axa - aaaaa - -/\d*/ - 1234b567 - xyz - -/\D*/ - a1234b567 - xyz - -/\d+/ - ab1234c56 - *** Failers - xyz - -/\D+/ - ab123c56 - *** Failers - 789 - -/\d?A/ - 045ABC - ABC - *** Failers - XYZ - -/\D?A/ - ABC - BAC - 9ABC - *** Failers - -/a+/ - aaaa - -/^.*xyz/ - xyz - ggggggggxyz - -/^.+xyz/ - abcdxyz - axyz - *** Failers - xyz - -/^.?xyz/ - xyz - cxyz - -/^\d{2,3}X/ - 12X - 123X - *** Failers - X - 1X - 1234X - -/^[abcd]\d/ - a45 - b93 - c99z - d04 - *** Failers - e45 - abcd - abcd1234 - 1234 - -/^[abcd]*\d/ - a45 - b93 - c99z - d04 - abcd1234 - 1234 - *** Failers - e45 - abcd - -/^[abcd]+\d/ - a45 - b93 - c99z - d04 - abcd1234 - *** Failers - 1234 - e45 - abcd - -/^a+X/ - aX - aaX - -/^[abcd]?\d/ - a45 - b93 - c99z - d04 - 1234 - *** Failers - abcd1234 - e45 - -/^[abcd]{2,3}\d/ - ab45 - bcd93 - *** Failers - 1234 - a36 - abcd1234 - ee45 - -/^(abc)*\d/ - abc45 - abcabcabc45 - 42xyz - *** Failers - -/^(abc)+\d/ - abc45 - abcabcabc45 - *** Failers - 42xyz - -/^(abc)?\d/ - abc45 - 42xyz - *** Failers - abcabcabc45 - -/^(abc){2,3}\d/ - abcabc45 - abcabcabc45 - *** Failers - abcabcabcabc45 - abc45 - 42xyz - -/1(abc|xyz)2(?1)3/ - 1abc2abc3456 - 1abc2xyz3456 - -/^(a*\w|ab)=(a*\w|ab)/ - ab=ab - -/^(a*\w|ab)=(?1)/ - ab=ab - -/^([^()]|\((?1)*\))*$/ - abc - a(b)c - a(b(c))d - *** Failers) - a(b(c)d - -/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)a*)\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 - *** Failers - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x - <> - - hij> - hij> - def> - - *** Failers - 3 - *** Failers - defabcxyz - -/^abcdef/ - ab\P - abcde\P - abcdef\P - *** Failers - abx\P - -/^a{2,4}\d+z/ - a\P - aa\P - aa2\P - aaa\P - aaa23\P - aaaa12345\P - aa0z\P - aaaa4444444444444z\P - *** Failers - az\P - aaaaa\P - a56\P - -/^abcdef/ - abc\P - def\R - -/(?<=foo)bar/ - xyzfo\P - foob\P\>2 - foobar...\R\P\>4 - xyzfo\P - foobar\>2 - *** Failers - xyzfo\P - obar\R - -/(ab*(cd|ef))+X/ - adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z - lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z - cdabbbbbbbb\P\R\B\Z - efabbbbbbbbbbbbbbbb\P\R\B\Z - bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z - -/(a|b)/SF>testsavedregex ->>aaabxyzpqrrrabbxyyyypqAzz - >aaaabxyzpqrrrabbxyyyypqAzz - >>>>abcxyzpqrrrabbxyyyypqAzz - *** Failers - abxyzpqrrabbxyyyypqAzz - abxyzpqrrrrabbxyyyypqAzz - abxyzpqrrrabxyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyypqAzz - aaabcxyzpqrrrabbxyyyypqqqqqqqAzz - -/^(abc){1,2}zz/ - abczz - abcabczz - *** Failers - zz - abcabcabczz - >>abczz - -/^(b+?|a){1,2}?c/ - bc - bbc - bbbc - bac - bbac - aac - abbbbbbbbbbbc - bbbbbbbbbbbac - *** Failers - aaac - abbbbbbbbbbbac - -/^(b+|a){1,2}c/ - bc - bbc - bbbc - bac - bbac - aac - abbbbbbbbbbbc - bbbbbbbbbbbac - *** Failers - aaac - abbbbbbbbbbbac - -/^(b+|a){1,2}?bc/ - bbc - -/^(b*|ba){1,2}?bc/ - babc - bbabc - bababc - *** Failers - bababbc - babababc - -/^(ba|b*){1,2}?bc/ - babc - bbabc - bababc - *** Failers - bababbc - babababc - -/^\ca\cA\c[\c{\c:/ - \x01\x01\e;z - -/^[ab\]cde]/ - athing - bthing - ]thing - cthing - dthing - ething - *** Failers - fthing - [thing - \\thing - -/^[]cde]/ - ]thing - cthing - dthing - ething - *** Failers - athing - fthing - -/^[^ab\]cde]/ - fthing - [thing - \\thing - *** Failers - athing - bthing - ]thing - cthing - dthing - ething - -/^[^]cde]/ - athing - fthing - *** Failers - ]thing - cthing - dthing - ething - -/^\/ - - -/^ÿ/ - ÿ - -/^[0-9]+$/ - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 100 - *** Failers - abc - -/^.*nter/ - enter - inter - uponter - -/^xxx[0-9]+$/ - xxx0 - xxx1234 - *** Failers - xxx - -/^.+[0-9][0-9][0-9]$/ - x123 - xx123 - 123456 - *** Failers - 123 - x1234 - -/^.+?[0-9][0-9][0-9]$/ - x123 - xx123 - 123456 - *** Failers - 123 - x1234 - -/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ - abc!pqr=apquxz.ixr.zzz.ac.uk - *** Failers - !pqr=apquxz.ixr.zzz.ac.uk - abc!=apquxz.ixr.zzz.ac.uk - abc!pqr=apquxz:ixr.zzz.ac.uk - abc!pqr=apquxz.ixr.zzz.ac.ukk - -/:/ - Well, we need a colon: somewhere - *** Fail if we don't - -/([\da-f:]+)$/i - 0abc - abc - fed - E - :: - 5f03:12C0::932e - fed def - Any old stuff - *** Failers - 0zzz - gzzz - fed\x20 - Any old rubbish - -/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ - .1.2.3 - A.12.123.0 - *** Failers - .1.2.3333 - 1.2.3 - 1234.2.3 - -/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ - 1 IN SOA non-sp1 non-sp2( - 1 IN SOA non-sp1 non-sp2 ( - *** Failers - 1IN SOA non-sp1 non-sp2( - -/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ - a. - Z. - 2. - ab-c.pq-r. - sxk.zzz.ac.uk. - x-.y-. - *** Failers - -abc.peq. - -/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ - *.a - *.b0-a - *.c3-b.c - *.c-a.b-c - *** Failers - *.0 - *.a- - *.a-b.c- - *.c-a.0-c - -/^(?=ab(de))(abd)(e)/ - abde - -/^(?!(ab)de|x)(abd)(f)/ - abdf - -/^(?=(ab(cd)))(ab)/ - abcd - -/^[\da-f](\.[\da-f])*$/i - a.b.c.d - A.B.C.D - a.b.c.1.2.3.C - -/^\".*\"\s*(;.*)?$/ - \"1234\" - \"abcd\" ; - \"\" ; rhubarb - *** Failers - \"1234\" : things - -/^$/ - \ - *** Failers - -/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x - ab c - *** Failers - abc - ab cde - -/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ - ab c - *** Failers - abc - ab cde - -/^ a\ b[c ]d $/x - a bcd - a b d - *** Failers - abcd - ab d - -/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ - abcdefhijklm - -/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ - abcdefhijklm - -/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ - a+ Z0+\x08\n\x1d\x12 - -/^[.^$|()*+?{,}]+/ - .^\$(*+)|{?,?} - -/^a*\w/ - z - az - aaaz - a - aa - aaaa - a+ - aa+ - -/^a*?\w/ - z - az - aaaz - a - aa - aaaa - a+ - aa+ - -/^a+\w/ - az - aaaz - aa - aaaa - aa+ - -/^a+?\w/ - az - aaaz - aa - aaaa - aa+ - -/^\d{8}\w{2,}/ - 1234567890 - 12345678ab - 12345678__ - *** Failers - 1234567 - -/^[aeiou\d]{4,5}$/ - uoie - 1234 - 12345 - aaaaa - *** Failers - 123456 - -/^[aeiou\d]{4,5}?/ - uoie - 1234 - 12345 - aaaaa - 123456 - -/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ - From abcd Mon Sep 01 12:33:02 1997 - -/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ - From abcd Mon Sep 01 12:33:02 1997 - From abcd Mon Sep 1 12:33:02 1997 - *** Failers - From abcd Sep 01 12:33:02 1997 - -/^12.34/s - 12\n34 - 12\r34 - -/\w+(?=\t)/ - the quick brown\t fox - -/foo(?!bar)(.*)/ - foobar is foolish see? - -/(?:(?!foo)...|^.{0,2})bar(.*)/ - foobar crowbar etc - barrel - 2barrel - A barrel - -/^(\D*)(?=\d)(?!123)/ - abc456 - *** Failers - abc123 - -/^1234(?# test newlines - inside)/ - 1234 - -/^1234 #comment in extended re - /x - 1234 - -/#rhubarb - abcd/x - abcd - -/^abcd#rhubarb/x - abcd - -/(?!^)abc/ - the abc - *** Failers - abc - -/(?=^)abc/ - abc - *** Failers - the abc - -/^[ab]{1,3}(ab*|b)/ - aabbbbb - -/^[ab]{1,3}?(ab*|b)/ - aabbbbb - -/^[ab]{1,3}?(ab*?|b)/ - aabbbbb - -/^[ab]{1,3}(ab*?|b)/ - aabbbbb - -/ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional leading comment -(?: (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # one word, optionally followed by.... -(?: -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... -\( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) | # comments, or... - -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -# quoted strings -)* -< (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # leading < -(?: @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* - -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* , (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -)* # further okay, if led by comma -: # closing colon -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* )? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address spec -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* > # trailing > -# name and address -) (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional trailing comment -/x - Alan Other - - user\@dom.ain - \"A. Other\" (a comment) - A. Other (a comment) - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -# leading word -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces -(?: -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -| -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -) # "special" comment or quoted string -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" -)* -< -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# < -(?: -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -(?: , -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -)* # additional domains -: -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address spec -> # > -# name and address -) -/x - Alan Other - - user\@dom.ain - \"A. Other\" (a comment) - A. Other (a comment) - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - A missing angle - a\rb - *** Failers - a\nb - -/abc$/ - abc - abc\n - *** Failers - abc\ndef - -/(abc)\123/ - abc\x53 - -/(abc)\223/ - abc\x93 - -/(abc)\323/ - abc\xd3 - -/(abc)\100/ - abc\x40 - abc\100 - -/(abc)\1000/ - abc\x400 - abc\x40\x30 - abc\1000 - abc\100\x30 - abc\100\060 - abc\100\60 - -/abc\81/ - abc\081 - abc\0\x38\x31 - -/abc\91/ - abc\091 - abc\0\x39\x31 - -/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ - abcdefghijk\12S - -/ab\idef/ - abidef - -/a{0}bc/ - bc - -/(a|(bc)){0,0}?xyz/ - xyz - -/abc[\10]de/ - abc\010de - -/abc[\1]de/ - abc\1de - -/(abc)[\1]de/ - abc\1de - -/(?s)a.b/ - a\nb - -/^([^a])([^\b])([^c]*)([^d]{3,4})/ - baNOTccccd - baNOTcccd - baNOTccd - bacccd - *** Failers - anything - b\bc - baccd - -/[^a]/ - Abc - -/[^a]/i - Abc - -/[^a]+/ - AAAaAbc - -/[^a]+/i - AAAaAbc - -/[^a]+/ - bbb\nccc - -/[^k]$/ - abc - *** Failers - abk - -/[^k]{2,3}$/ - abc - kbc - kabc - *** Failers - abk - akb - akk - -/^\d{8,}\@.+[^k]$/ - 12345678\@a.b.c.d - 123456789\@x.y.z - *** Failers - 12345678\@x.y.uk - 1234567\@a.b.c.d - -/[^a]/ - aaaabcd - aaAabcd - -/[^a]/i - aaaabcd - aaAabcd - -/[^az]/ - aaaabcd - aaAabcd - -/[^az]/i - aaaabcd - aaAabcd - -/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ - \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 - -/P[^*]TAIRE[^*]{1,6}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - -/P[^*]TAIRE[^*]{1,}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - -/(\.\d\d[1-9]?)\d+/ - 1.230003938 - 1.875000282 - 1.235 - -/(\.\d\d((?=0)|\d(?=\d)))/ - 1.230003938 - 1.875000282 - *** Failers - 1.235 - -/a(?)b/ - ab - -/\b(foo)\s+(\w+)/i - Food is on the foo table - -/foo(.*)bar/ - The food is under the bar in the barn. - -/foo(.*?)bar/ - The food is under the bar in the barn. - -/(.*)(\d*)/ - I have 2 numbers: 53147 - -/(.*)(\d+)/ - I have 2 numbers: 53147 - -/(.*?)(\d*)/ - I have 2 numbers: 53147 - -/(.*?)(\d+)/ - I have 2 numbers: 53147 - -/(.*)(\d+)$/ - I have 2 numbers: 53147 - -/(.*?)(\d+)$/ - I have 2 numbers: 53147 - -/(.*)\b(\d+)$/ - I have 2 numbers: 53147 - -/(.*\D)(\d+)$/ - I have 2 numbers: 53147 - -/^\D*(?!123)/ - ABC123 - -/^(\D*)(?=\d)(?!123)/ - ABC445 - *** Failers - ABC123 - -/^[W-]46]/ - W46]789 - -46]789 - *** Failers - Wall - Zebra - 42 - [abcd] - ]abcd[ - -/^[W-\]46]/ - W46]789 - Wall - Zebra - Xylophone - 42 - [abcd] - ]abcd[ - \\backslash - *** Failers - -46]789 - well - -/\d\d\/\d\d\/\d\d\d\d/ - 01/01/2000 - -/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark - -/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope - -/^(a){0,0}/ - bcd - abc - aab - -/^(a){0,1}/ - bcd - abc - aab - -/^(a){0,2}/ - bcd - abc - aab - -/^(a){0,3}/ - bcd - abc - aab - aaa - -/^(a){0,}/ - bcd - abc - aab - aaa - aaaaaaaa - -/^(a){1,1}/ - bcd - abc - aab - -/^(a){1,2}/ - bcd - abc - aab - -/^(a){1,3}/ - bcd - abc - aab - aaa - -/^(a){1,}/ - bcd - abc - aab - aaa - aaaaaaaa - -/.*\.gif/ - borfle\nbib.gif\nno - -/.{0,}\.gif/ - borfle\nbib.gif\nno - -/.*\.gif/m - borfle\nbib.gif\nno - -/.*\.gif/s - borfle\nbib.gif\nno - -/.*\.gif/ms - borfle\nbib.gif\nno - -/.*$/ - borfle\nbib.gif\nno - -/.*$/m - borfle\nbib.gif\nno - -/.*$/s - borfle\nbib.gif\nno - -/.*$/ms - borfle\nbib.gif\nno - -/.*$/ - borfle\nbib.gif\nno\n - -/.*$/m - borfle\nbib.gif\nno\n - -/.*$/s - borfle\nbib.gif\nno\n - -/.*$/ms - borfle\nbib.gif\nno\n - -/(.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(.*X|^B)/m - abcde\n1234Xyz - BarFoo - abcde\nBar - -/(.*X|^B)/s - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(.*X|^B)/ms - abcde\n1234Xyz - BarFoo - abcde\nBar - -/(?s)(.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/(?s:.*X|^B)/ - abcde\n1234Xyz - BarFoo - *** Failers - abcde\nBar - -/^.*B/ - **** Failers - abc\nB - -/(?s)^.*B/ - abc\nB - -/(?m)^.*B/ - abc\nB - -/(?ms)^.*B/ - abc\nB - -/(?ms)^B/ - abc\nB - -/(?s)B$/ - B\n - -/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ - 123456654321 - -/^\d\d\d\d\d\d\d\d\d\d\d\d/ - 123456654321 - -/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ - 123456654321 - -/^[abc]{12}/ - abcabcabcabc - -/^[a-c]{12}/ - abcabcabcabc - -/^(a|b|c){12}/ - abcabcabcabc - -/^[abcdefghijklmnopqrstuvwxy0123456789]/ - n - *** Failers - z - -/abcde{0,0}/ - abcd - *** Failers - abce - -/ab[cd]{0,0}e/ - abe - *** Failers - abcde - -/ab(c){0,0}d/ - abd - *** Failers - abcd - -/a(b*)/ - a - ab - abbbb - *** Failers - bbbbb - -/ab\d{0}e/ - abe - *** Failers - ab1e - -/"([^\\"]+|\\.)*"/ - the \"quick\" brown fox - \"the \\\"quick\\\" brown fox\" - -/.*?/g+ - abc - -/\b/g+ - abc - -/\b/+g - abc - -//g - abc - -/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is - 43.
    Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide - -/a[^a]b/ - acb - a\nb - -/a.b/ - acb - *** Failers - a\nb - -/a[^a]b/s - acb - a\nb - -/a.b/s - acb - a\nb - -/^(b+?|a){1,2}?c/ - bac - bbac - bbbac - bbbbac - bbbbbac - -/^(b+|a){1,2}?c/ - bac - bbac - bbbac - bbbbac - bbbbbac - -/(?!\A)x/m - x\nb\n - a\bx\n - -/\x0{ab}/ - \0{ab} - -/(A|B)*?CD/ - CD - -/(A|B)*CD/ - CD - -/(?.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ - -"(?>.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - -/(?>(\.\d\d[1-9]?))\d+/ - 1.230003938 - 1.875000282 - *** Failers - 1.235 - -/^((?>\w+)|(?>\s+))*$/ - now is the time for all good men to come to the aid of the party - *** Failers - this is not a line with only words and spaces! - -/(\d+)(\w)/ - 12345a - 12345+ - -/((?>\d+))(\w)/ - 12345a - *** Failers - 12345+ - -/(?>a+)b/ - aaab - -/((?>a+)b)/ - aaab - -/(?>(a+))b/ - aaab - -/(?>b)+/ - aaabbbccc - -/(?>a+|b+|c+)*c/ - aaabbbbccccd - -/(a+|b+|c+)*c/ - aaabbbbccccd - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - -/\(((?>[^()]+)|\([^()]+\))+\)/ - (abc) - (abc(def)xyz) - *** Failers - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/a(?-i)b/i - ab - Ab - *** Failers - aB - AB - -/(a (?x)b c)d e/ - a bcd e - *** Failers - a b cd e - abcd e - a bcde - -/(a b(?x)c d (?-x)e f)/ - a bcde f - *** Failers - abcdef - -/(a(?i)b)c/ - abc - aBc - *** Failers - abC - aBC - Abc - ABc - ABC - AbC - -/a(?i:b)c/ - abc - aBc - *** Failers - ABC - abC - aBC - -/a(?i:b)*c/ - aBc - aBBc - *** Failers - aBC - aBBC - -/a(?=b(?i)c)\w\wd/ - abcd - abCd - *** Failers - aBCd - abcD - -/(?s-i:more.*than).*million/i - more than million - more than MILLION - more \n than Million - *** Failers - MORE THAN MILLION - more \n than \n million - -/(?:(?s-i)more.*than).*million/i - more than million - more than MILLION - more \n than Million - *** Failers - MORE THAN MILLION - more \n than \n million - -/(?>a(?i)b+)+c/ - abc - aBbc - aBBc - *** Failers - Abc - abAb - abbC - -/(?=a(?i)b)\w\wc/ - abc - aBc - *** Failers - Ab - abC - aBC - -/(?<=a(?i)b)(\w\w)c/ - abxxc - aBxxc - *** Failers - Abxxc - ABxxc - abxxC - -/^(?(?=abc)\w{3}:|\d\d)$/ - abc: - 12 - *** Failers - 123 - xyz - -/^(?(?!abc)\d\d|\w{3}:)$/ - abc: - 12 - *** Failers - 123 - xyz - -/(?(?<=foo)bar|cat)/ - foobar - cat - fcat - focat - *** Failers - foocat - -/(?(?a*)*/ - a - aa - aaaa - -/(abc|)+/ - abc - abcabc - abcabcabc - xyz - -/([a]*)*/ - a - aaaaa - -/([ab]*)*/ - a - b - ababab - aaaabcde - bbbb - -/([^a]*)*/ - b - bbbb - aaa - -/([^ab]*)*/ - cccc - abab - -/([a]*?)*/ - a - aaaa - -/([ab]*?)*/ - a - b - abab - baba - -/([^a]*?)*/ - b - bbbb - aaa - -/([^ab]*?)*/ - c - cccc - baba - -/(?>a*)*/ - a - aaabcde - -/((?>a*))*/ - aaaaa - aabbaa - -/((?>a*?))*/ - aaaaa - aabbaa - -/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x - 12-sep-98 - 12-09-98 - *** Failers - sep-12-98 - -/(?i:saturday|sunday)/ - saturday - sunday - Saturday - Sunday - SATURDAY - SUNDAY - SunDay - -/(a(?i)bc|BB)x/ - abcx - aBCx - bbx - BBx - *** Failers - abcX - aBCX - bbX - BBX - -/^([ab](?i)[cd]|[ef])/ - ac - aC - bD - elephant - Europe - frog - France - *** Failers - Africa - -/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ - ab - aBd - xy - xY - zebra - Zambesi - *** Failers - aCD - XY - -/(?<=foo\n)^bar/m - foo\nbar - *** Failers - bar - baz\nbar - -/(?<=(?]&/ - <&OUT - -/(?:(f)(o)(o)|(b)(a)(r))*/ - foobar - -/(?<=a)b/ - ab - *** Failers - cb - b - -/(?\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} -/((?s)^a(.))((?m)^b$)/ - a\nb\nc\n +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/((?m)^b$)/ - a\nb\nc\n +/^>\p{Xsp}+?/8 + >\x{1680}\x{2028}\x{0b} -/(?m)^b/ - a\nb\n +/^>\p{Xsp}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xsp}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/(?m)^(b)/ - a\nb\n +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + >\x{a0} + ** Failers + \x{0b} -/((?m)^b)/ - a\nb\n +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/\n((?m)^b)/ - a\nb\n +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} -/((?s).)c(?!.)/ - a\nb\nc\n - a\nb\nc\n +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/((?s)b.)c(?!.)/ - a\nb\nc\n - a\nb\nc\n +/^\p{Xwd}/8 + ABCD + 1234 + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] -/^b/ +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/()^b/ - *** Failers - a\nb\nc\n - a\nb\nc\n +/^\p{Xwd}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ -/((?m)^b)/ - a\nb\nc\n +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_B12\x{6ca}\x{a6c}\x{10a7} + +/^\p{Xwd}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + +/^[\p{Xwd}]/8 + ABCD1234_ + 1234abcd_ + \x{6ca} + \x{a6c} + \x{10a7} + _ABC + ** Failers + [] + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/(?(?!a)a|b)/ +/-- A check not in UTF-8 mode --/ -/(?(?!a)b|a)/ - a +/^[\p{Xwd}]+/ + ABCD1234_ + +/-- Some negative checks --/ -/(?(?=a)b|a)/ - *** Failers - a - a +/^[\P{Xwd}]+/8 + !.+\x{019}\x{35a}AB -/(?(?=a)a|b)/ - a +/^[\p{^Xwd}]+/8 + !.+\x{019}\x{35a}AB -/(\w+:)+/ - one: +/[\D]/WBZ8 + 1\x{3c8}2 -/$(?<=^(a))/ - a +/[\d]/WBZ8 + >\x{6f4}< -/([\w:]+::)?(\w+)$/ - abcd - xy:z:::abcd - -/^[^bcd]*(c+)/ - aexycd - -/(a*)b+/ - caab - -/([\w:]+::)?(\w+)$/ - abcd - xy:z:::abcd - *** Failers - abcd: - abcd: +/[\S]/WBZ8 + \x{1680}\x{6f4}\x{1680} -/^[^bcd]*(c+)/ - aexycd +/[\s]/WBZ8 + >\x{1680}< -/(>a+)ab/ +/[\W]/WBZ8 + A\x{1712}B -/(?>a+)b/ - aaab +/[\w]/WBZ8 + >\x{1723}< -/([[:]+)/ - a:[b]: +/\D/WBZ8 + 1\x{3c8}2 -/([[=]+)/ - a=[b]= +/\d/WBZ8 + >\x{6f4}< -/([[.]+)/ - a.[b]. +/\S/WBZ8 + \x{1680}\x{6f4}\x{1680} -/((?>a+)b)/ - aaab +/\s/WBZ8 + >\x{1680}> -/(?>(a+))b/ - aaab +/\W/WBZ8 + A\x{1712}B -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x +/\w/WBZ8 + >\x{1723}< -/a\Z/ - *** Failers - aaab - a\nb\n +/[[:alpha:]]/WBZ -/b\Z/ - a\nb\n +/[[:lower:]]/WBZ -/b\z/ +/[[:upper:]]/WBZ -/b\Z/ - a\nb +/[[:alnum:]]/WBZ -/b\z/ - a\nb - *** Failers - -/(?>.*)(?<=(abcd|wxyz))/ - alphabetabcd - endingwxyz - *** Failers - a rather long string that doesn't end with one of them +/[[:ascii:]]/WBZ -/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark - -/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope +/[[:cntrl:]]/WBZ -/(?<=\d{3}(?!999))foo/ - 999foo - 123999foo - *** Failers - 123abcfoo - -/(?<=(?!...999)\d{3})foo/ - 999foo - 123999foo - *** Failers - 123abcfoo +/[[:digit:]]/WBZ -/(?<=\d{3}(?!999)...)foo/ - 123abcfoo - 123456foo - *** Failers - 123999foo - -/(?<=\d{3}...)(?Z)+|A)*/ - ZABCDEFG +/[[:word:]]/WBZ -/((?>)+|A)*/ - ZABCDEFG +/[[:xdigit:]]/WBZ -/a*/g - abbab +/-- Unicode properties for \b abd \B --/ -/^[a-\d]/ - abcde - -things - 0digit - *** Failers - bcdef +/\b...\B/8W + abc_ + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ -/^[\d-a]/ - abcde - -things - 0digit - *** Failers - bcdef - -/[[:space:]]+/ - > \x09\x0a\x0c\x0d\x0b< - -/[[:blank:]]+/ - > \x09\x0a\x0c\x0d\x0b< - -/[\s]+/ - > \x09\x0a\x0c\x0d\x0b< - -/\s+/ - > \x09\x0a\x0c\x0d\x0b< - -/a b/x - ab +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ -/(?!\A)x/m - a\nxb\n +/\b...\B/8 + abc_ + ** Failers + \x{37e}abc\x{376} + \x{37e}\x{376}\x{371}\x{393}\x{394} + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ -/(?!^)x/m - a\nxb\n +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ -/abc\Qabc\Eabc/ - abcabcabc - -/abc\Q(*+|\Eabc/ - abc(*+|abc +/\b...\B/W + abc_ + !\x{c0}++\x{c1}\x{c2} + !\x{c0}+++++ -/ abc\Q abc\Eabc/x - abc abcabc - *** Failers - abcabcabc - -/abc#comment - \Q#not comment - literal\E/x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal/x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal\E #more comment - /x - abc#not comment\n literal - -/abc#comment - \Q#not comment - literal\E #more comment/x - abc#not comment\n literal +/-- Some of these are silly, but they check various combinations --/ -/\Qabc\$xyz\E/ - abc\\\$xyz +/[[:^alpha:][:^cntrl:]]+/8WBZ + 123 + abc -/\Qabc\E\$\Qxyz\E/ - abc\$xyz +/[[:^cntrl:][:^alpha:]]+/8WBZ + 123 + abc -/\Gabc/ +/[[:alpha:]]+/8WBZ abc - *** Failers - xyzabc -/\Gabc./g - abc1abc2xyzabc3 - -/abc./g - abc1abc2xyzabc3 - -/a(?x: b c )d/ - XabcdY - *** Failers - Xa b c d Y - -/((?x)x y z | a b c)/ - XabcY - AxyzB +/[[:^alpha:]\S]+/8WBZ + 123 + abc -/(?i)AB(?-i)C/ - XabCY - *** Failers - XabcY +/[^\d]+/8WBZ + abc123 + abc\x{123} + \x{660}abc -/((?i)AB(?-i)C|D)E/ - abCE - DE - *** Failers - abcE - abCe - dE - De +/\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ -/[z\Qa-d]\E]/ - z - a - - - d - ] - *** Failers - b +/\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ -/[\z\C]/ - z - C - -/\M/ - M - -/(a+)*b/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ - REGular - regulaer - Regex - regulär - -/Åæåä[à-ÿÀ-ß]+/ - Åæåäà - Åæåäÿ - ÅæåäÀ - Åæåäß - -/(?<=Z)X./ - \x84XAZXB - -/^(?(2)a|(1)(2))+$/ - 123a - -/(?<=a|bbbb)c/ - ac - bbbbc +/\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ -/abc/>testsavedregex -testsavedregex -testsavedregex -testsavedregex - - xyz\r\nabc\ - xyz\rabc\ - xyz\r\nabc\ - ** Failers - xyz\nabc\ - xyz\r\nabc\ - xyz\nabc\ - xyz\rabc\ - xyz\rabc\ - -/abc$/m - xyzabc - xyzabc\n - xyzabc\npqr - xyzabc\r\ - xyzabc\rpqr\ - xyzabc\r\n\ - xyzabc\r\npqr\ - ** Failers - xyzabc\r - xyzabc\rpqr - xyzabc\r\n - xyzabc\r\npqr - -/^abc/m - xyz\rabcdef - xyz\nabcdef\ - ** Failers - xyz\nabcdef - -/^abc/m - xyz\nabcdef - xyz\rabcdef\ - ** Failers - xyz\rabcdef - -/^abc/m - xyz\r\nabcdef - xyz\rabcdef\ - ** Failers - xyz\rabcdef - -/.*/ - abc\ndef - abc\rdef - abc\r\ndef - \abc\ndef - \abc\rdef - \abc\r\ndef - \abc\ndef - \abc\rdef - \abc\r\ndef - -/\w+(.)(.)?def/s - abc\ndef - abc\rdef - abc\r\ndef - -/^\w+=.*(\\\n.*)*/ - abc=xyz\\\npqr - -/^(a()*)*/ - aaaa - -/^(?:a(?:(?:))*)*/ - aaaa - -/^(a()+)+/ - aaaa - -/^(?:a(?:(?:))+)+/ - aaaa - -/(a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?>a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?:a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/^a.b/ - a\rb - a\nb\ - ** Failers - a\nb - a\nb\ - a\rb\ - a\rb\ - -/^abc./mgx - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK - -/abc.$/mgx - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 - -/^a\Rb/ - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - ** Failers - a\n\rb +/A+\p{N}A+\dB+\p{N}*B+\d*/WBZ -/^a\R*b/ - ab - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - a\n\rb - a\n\r\x85\x0cb - -/^a\R+b/ - a\nb - a\rb - a\r\nb - a\x0bb - a\x0cb - a\x85b - a\n\rb - a\n\r\x85\x0cb - ** Failers - ab - -/^a\R{1,3}b/ - a\nb - a\n\rb - a\n\r\x85b - a\r\n\r\nb - a\r\n\r\n\r\nb - a\n\r\n\rb - a\n\n\r\nb - ** Failers - a\n\n\n\rb - a\r +/-- These behaved oddly in Perl, so they are kept in this test --/ -/^a[\R]b/ - aRb - ** Failers - a\nb +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} -/.+foo/ - afoo - ** Failers - \r\nfoo - \nfoo +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥ -/.+foo/ - afoo - \nfoo - ** Failers - \r\nfoo +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} -/.+foo/ - afoo - ** Failers - \nfoo - \r\nfoo +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥⱥ -/.+foo/s - afoo - \r\nfoo - \nfoo - -/^$/mg - abc\r\rxyz - abc\n\rxyz - ** Failers - abc\r\nxyz +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} -/^X/m - XABC - ** Failers - XABC\B +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥ -/(?m)^$/g+ - abc\r\n\r\n +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} -/(?m)^$|^\r\n/g+ - abc\r\n\r\n - -/(?m)$/g+ - abc\r\n\r\n +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥⱥ -/(?|(abc)|(xyz))/ - >abc< - >xyz< - -/(x)(?|(abc)|(xyz))(x)/ - xabcx - xxyzx - -/(x)(?|(abc)(pqr)|(xyz))(x)/ - xabcpqrx - xxyzx - -/(?|(abc)|(xyz))(?1)/ - abcabc - xyzabc - ** Failers - xyzxyz - -/\H\h\V\v/ - X X\x0a - X\x09X\x0b - ** Failers - \xa0 X\x0a - -/\H*\h+\V?\v{3,4}/ - \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a - \x09\x20\xa0\x0a\x0b\x0c - ** Failers - \x09\x20\xa0\x0a\x0b - -/\H{3,4}/ - XY ABCDE - XY PQR ST +/(\x{2c65}\x{2c65})\1/8i + \x{2c65}\x{2c65}\x{23a}\x{23a} -/.\h{3,4}./ - XY AB PQRS - -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - > X NYQZ - ** Failers - >XYZ - > X NY Z - -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - -/.+A/ - \r\nA +/(ⱥⱥ)\1/8i + ⱥⱥȺȺ -/\nA/ - \r\nA +/(\x{23a}\x{23a}\x{23a})\1Y/8i + X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ -/[\r\n]A/ - \r\nA +/(\x{2c65}\x{2c65})\1Y/8i + X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ -/(\r|\n)A/ - \r\nA +/-- --/ -/a\Rb/I - a\rb - a\nb - a\r\nb - ** Failers - a\x85b - a\x0bb +/-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ -/a\Rb/I - a\rb - a\nb - a\r\nb - a\x85b - a\x0bb - ** Failers - a\x85b\ - a\x0bb\ - -/a\R?b/I - a\rb - a\nb - a\r\nb +/^[\p{Batak}]/8 + \x{1bc0} + \x{1bff} ** Failers - a\x85b - a\x0bb - -/a\R?b/I - a\rb - a\nb - a\r\nb - a\x85b - a\x0bb - ** Failers - a\x85b\ - a\x0bb\ + \x{1bf4} -/a\R{2,4}b/I - a\r\n\nb - a\n\r\rb - a\r\n\r\n\r\n\r\nb +/^[\p{Brahmi}]/8 + \x{11000} + \x{1106f} ** Failers - a\x85\85b - a\x0b\0bb - -/a\R{2,4}b/I - a\r\rb - a\n\n\nb - a\r\n\n\r\rb - a\x85\85b - a\x0b\0bb - ** Failers - a\r\r\r\r\rb - a\x85\85b\ - a\x0b\0bb\ + \x{1104e} -/a(?!)|\wbc/ - abc - -/a[]b/ +/^[\p{Mandaic}]/8 + \x{840} + \x{85e} ** Failers - ab + \x{85c} + \x{85d} -/a[]+b/ - ** Failers - ab +/-- --/ -/a[]*+b/ - ** Failers - ab +/(\X*)(.)/s8 + A\x{300} -/a[^]b/ - aXb - a\nb - ** Failers - ab +/^S(\X*)e(\X*)$/8 + SteÌreÌo -/a[^]+b/ - aXb - a\nX\nXb - ** Failers - ab - -/X$/E - X - ** Failers - X\n - -/X$/ - X - X\n - -/xyz/C - xyz - abcxyz - abcxyz\Y - ** Failers - abc - abc\Y - abcxypqr - abcxypqr\Y +/^\X/8 + ÌreÌo -/(*NO_START_OPT)xyz/C - abcxyz - -/(?C)ab/ - ab - \C-ab - -/ab/C - ab - \C-ab - -/^"((?(?=[a])[^"])|b)*"$/C - "ab" - \C-"ab" - -/\d+X|9+Y/ - ++++123999\P - ++++123999Y\P - -/Z(*F)/ - Z\P - ZA\P - -/Z(?!)/ - Z\P - ZA\P - -/dog(sbody)?/ - dogs\P - dogs\P\P - -/dog(sbody)??/ - dogs\P - dogs\P\P - -/dog|dogsbody/ - dogs\P - dogs\P\P - -/dogsbody|dog/ - dogs\P - dogs\P\P - -/Z(*F)Q|ZXY/ - Z\P - ZA\P - X\P - -/\bthe cat\b/ - the cat\P - the cat\P\P - -/dog(sbody)?/ - dogs\D\P - body\D\R - -/dog(sbody)?/ - dogs\D\P\P - body\D\R - -/abc/ - abc\P - abc\P\P +/^a\X41z/ + aX41z + *** Failers + aAz -/abc\K123/ - xyzabc123pqr - -/(?<=abc)123/ - xyzabc123pqr - xyzabc12\P - xyzabc12\P\P - -/\babc\b/ - +++abc+++ - +++ab\P - +++ab\P\P - -/(?=C)/g+ - ABCDECBA - -/(abc|def|xyz)/I - terhjk;abcdaadsfe - the quick xyz brown fox - \Yterhjk;abcdaadsfe - \Ythe quick xyz brown fox - ** Failers - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +/(?<=ab\Cde)X/8 -/(abc|def|xyz)/SI - terhjk;abcdaadsfe - the quick xyz brown fox - \Yterhjk;abcdaadsfe - \Ythe quick xyz brown fox - ** Failers - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +/\X/ + a\P + a\P\P -/abcd*/+ - xxxxabcd\P - xxxxabcd\P\P - dddxxx\R - xxxxabcd\P\P - xxx\R - -/abcd*/i - xxxxabcd\P - xxxxabcd\P\P - XXXXABCD\P - XXXXABCD\P\P - -/abc\d*/ - xxxxabc1\P - xxxxabc1\P\P - -/abc[de]*/ - xxxxabcde\P - xxxxabcde\P\P +/\Xa/ + aa\P + aa\P\P -/(?:(?1)|B)(A(*F)|C)/ - ABCD - CCD - ** Failers - CAD +/\X{2}/ + aa\P + aa\P\P -/^(?:(?1)|B)(A(*F)|C)/ - CCD - BCD - ** Failers - ABCD - CAD - BAD +/\X+a/ + a\P + aa\P + aa\P\P -/^(?!a(*SKIP)b)/ - ac - -/^(?=a(*SKIP)b|ac)/ - ** Failers - ac - -/^(?=a(*THEN)b|ac)/ - ac +/\X+?a/ + a\P + ab\P + aa\P + aa\P\P + aba\P -/^(?=a(*PRUNE)b)/ - ab - ** Failers - ac - -/^(?(?!a(*SKIP)b))/ - ac - -/(?<=abc)def/ - abc\P\P - -/abc$/ - abc - abc\P - abc\P\P - -/abc$/m - abc - abc\n - abc\P\P - abc\n\P\P - abc\P - abc\n\P - -/abc\z/ - abc - abc\P - abc\P\P - -/abc\Z/ - abc - abc\P - abc\P\P - -/abc\b/ - abc - abc\P - abc\P\P +/-- These Unicode 6.1.0 scripts are not known to Perl. --/ -/abc\B/ - abc - abc\P - abc\P\P +/\p{Chakma}\d/8W + \x{11100}\x{1113c} -/.+/ - abc\>0 - abc\>1 - abc\>2 - abc\>3 - abc\>4 - abc\>-4 +/\p{Takri}\d/8W + \x{11680}\x{116c0} + +/^\X/8 + A\P + A\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{301}\P + A\x{301}\P\P + +/^\X{2,3}/8 + A\P + A\P\P + AA\P + AA\P\P + A\x{300}\x{301}\P + A\x{300}\x{301}\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X{2}/8 + AA\P + AA\P\P + A\x{300}\x{301}A\x{300}\x{301}\P + A\x{300}\x{301}A\x{300}\x{301}\P\P + +/^\X+/8 + AA\P + AA\P\P + +/^\X+?Z/8 + AA\P + AA\P\P /-- End of testinput7 --/ diff -Nru pcre3-8.12/testdata/testinput8 pcre3-8.31/testdata/testinput8 --- pcre3-8.12/testdata/testinput8 2010-11-07 15:53:06.000000000 +0000 +++ pcre3-8.31/testdata/testinput8 2012-06-17 19:06:55.000000000 +0000 @@ -1,590 +1,4199 @@ -/-- This set of tests checks UTF-8 support with the DFA matching functionality - of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running - it. --/ +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). + The -dfa flag must be used with pcretest when running it. --/ + +/abc/ + abc + +/ab*c/ + abc + abbbbc + ac + +/ab+c/ + abc + abbbbbbc + *** Failers + ac + ab + +/a*/ + a + aaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F + +/(a|abcd|african)/ + a + abcd + african + +/^abc/ + abcdef + *** Failers + xyzabc + xyz\nabc + +/^abc/m + abcdef + xyz\nabc + *** Failers + xyzabc + +/\Aabc/ + abcdef + *** Failers + xyzabc + xyz\nabc + +/\Aabc/m + abcdef + *** Failers + xyzabc + xyz\nabc + +/\Gabc/ + abcdef + xyzabc\>3 + *** Failers + xyzabc + xyzabc\>2 + +/x\dy\Dz/ + x9yzz + x0y+z + *** Failers + xyz + xxy0z + +/x\sy\Sz/ + x yzz + x y+z + *** Failers + xyz + xxyyz + +/x\wy\Wz/ + xxy+z + *** Failers + xxy0z + x+y+z + +/x.y/ + x+y + x-y + *** Failers + x\ny + +/x.y/s + x+y + x-y + x\ny + +/(a.b(?s)c.d|x.y)p.q/ + a+bc+dp+q + a+bc\ndp+q + x\nyp+q + *** Failers + a\nbc\ndp+q + a+bc\ndp\nq + x\nyp\nq + +/a\d\z/ + ba0 + *** Failers + ba0\n + ba0\ncd + +/a\d\z/m + ba0 + *** Failers + ba0\n + ba0\ncd + +/a\d\Z/ + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d\Z/m + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d$/ + ba0 + ba0\n + *** Failers + ba0\ncd + +/a\d$/m + ba0 + ba0\n + ba0\ncd + *** Failers + +/abc/i + abc + aBc + ABC + +/[^a]/ + abcd + +/ab?\w/ + abz + abbz + azz + +/x{0,3}yz/ + ayzq + axyzq + axxyz + axxxyzq + axxxxyzq + *** Failers + ax + axx + +/x{3}yz/ + axxxyzq + axxxxyzq + *** Failers + ax + axx + ayzq + axyzq + axxyz + +/x{2,3}yz/ + axxyz + axxxyzq + axxxxyzq + *** Failers + ax + axx + ayzq + axyzq + +/[^a]+/ + bac + bcdefax + *** Failers + aaaaa + +/[^a]*/ + bac + bcdefax + *** Failers + aaaaa + +/[^a]{3,5}/ + xyz + awxyza + abcdefa + abcdefghijk + *** Failers + axya + axa + aaaaa + +/\d*/ + 1234b567 + xyz + +/\D*/ + a1234b567 + xyz + +/\d+/ + ab1234c56 + *** Failers + xyz + +/\D+/ + ab123c56 + *** Failers + 789 + +/\d?A/ + 045ABC + ABC + *** Failers + XYZ + +/\D?A/ + ABC + BAC + 9ABC + *** Failers + +/a+/ + aaaa + +/^.*xyz/ + xyz + ggggggggxyz + +/^.+xyz/ + abcdxyz + axyz + *** Failers + xyz + +/^.?xyz/ + xyz + cxyz + +/^\d{2,3}X/ + 12X + 123X + *** Failers + X + 1X + 1234X + +/^[abcd]\d/ + a45 + b93 + c99z + d04 + *** Failers + e45 + abcd + abcd1234 + 1234 + +/^[abcd]*\d/ + a45 + b93 + c99z + d04 + abcd1234 + 1234 + *** Failers + e45 + abcd + +/^[abcd]+\d/ + a45 + b93 + c99z + d04 + abcd1234 + *** Failers + 1234 + e45 + abcd + +/^a+X/ + aX + aaX + +/^[abcd]?\d/ + a45 + b93 + c99z + d04 + 1234 + *** Failers + abcd1234 + e45 + +/^[abcd]{2,3}\d/ + ab45 + bcd93 + *** Failers + 1234 + a36 + abcd1234 + ee45 + +/^(abc)*\d/ + abc45 + abcabcabc45 + 42xyz + *** Failers + +/^(abc)+\d/ + abc45 + abcabcabc45 + *** Failers + 42xyz + +/^(abc)?\d/ + abc45 + 42xyz + *** Failers + abcabcabc45 + +/^(abc){2,3}\d/ + abcabc45 + abcabcabc45 + *** Failers + abcabcabcabc45 + abc45 + 42xyz + +/1(abc|xyz)2(?1)3/ + 1abc2abc3456 + 1abc2xyz3456 + +/^(a*\w|ab)=(a*\w|ab)/ + ab=ab + +/^(a*\w|ab)=(?1)/ + ab=ab + +/^([^()]|\((?1)*\))*$/ + abc + a(b)c + a(b(c))d + *** Failers) + a(b(c)d + +/^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)a*)\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 + *** Failers + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x + <> + + hij> + hij> + def> + + *** Failers + 3 + *** Failers + defabcxyz + +/^abcdef/ + ab\P + abcde\P + abcdef\P + *** Failers + abx\P + +/^a{2,4}\d+z/ + a\P + aa\P + aa2\P + aaa\P + aaa23\P + aaaa12345\P + aa0z\P + aaaa4444444444444z\P + *** Failers + az\P + aaaaa\P + a56\P + +/^abcdef/ + abc\P + def\R + +/(?<=foo)bar/ + xyzfo\P + foob\P\>2 + foobar...\R\P\>4 + xyzfo\P + foobar\>2 + *** Failers + xyzfo\P + obar\R + +/(ab*(cd|ef))+X/ + adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z + lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z + cdabbbbbbbb\P\R\B\Z + efabbbbbbbbbbbbbbbb\P\R\B\Z + bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z + +/(a|b)/SF>testsavedregex +>>aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + *** Failers + abxyzpqrrabbxyyyypqAzz + abxyzpqrrrrabbxyyyypqAzz + abxyzpqrrrabxyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz + aaaabcxyzzzzpqrrrabbbxyyypqAzz + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz + +/^(abc){1,2}zz/ + abczz + abcabczz + *** Failers + zz + abcabcabczz + >>abczz + +/^(b+?|a){1,2}?c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac + *** Failers + aaac + abbbbbbbbbbbac + +/^(b+|a){1,2}c/ + bc + bbc + bbbc + bac + bbac + aac + abbbbbbbbbbbc + bbbbbbbbbbbac + *** Failers + aaac + abbbbbbbbbbbac + +/^(b+|a){1,2}?bc/ + bbc + +/^(b*|ba){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^(ba|b*){1,2}?bc/ + babc + bbabc + bababc + *** Failers + bababbc + babababc + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + +/^[ab\]cde]/ + athing + bthing + ]thing + cthing + dthing + ething + *** Failers + fthing + [thing + \\thing + +/^[]cde]/ + ]thing + cthing + dthing + ething + *** Failers + athing + fthing + +/^[^ab\]cde]/ + fthing + [thing + \\thing + *** Failers + athing + bthing + ]thing + cthing + dthing + ething + +/^[^]cde]/ + athing + fthing + *** Failers + ]thing + cthing + dthing + ething + +/^\/ + + +/^ÿ/ + ÿ + +/^[0-9]+$/ + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + *** Failers + abc + +/^.*nter/ + enter + inter + uponter + +/^xxx[0-9]+$/ + xxx0 + xxx1234 + *** Failers + xxx + +/^.+[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + xx123 + 123456 + *** Failers + 123 + x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + *** Failers + !pqr=apquxz.ixr.zzz.ac.uk + abc!=apquxz.ixr.zzz.ac.uk + abc!pqr=apquxz:ixr.zzz.ac.uk + abc!pqr=apquxz.ixr.zzz.ac.ukk + +/:/ + Well, we need a colon: somewhere + *** Fail if we don't + +/([\da-f:]+)$/i + 0abc + abc + fed + E + :: + 5f03:12C0::932e + fed def + Any old stuff + *** Failers + 0zzz + gzzz + fed\x20 + Any old rubbish + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + A.12.123.0 + *** Failers + .1.2.3333 + 1.2.3 + 1234.2.3 + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 1 IN SOA non-sp1 non-sp2 ( + *** Failers + 1IN SOA non-sp1 non-sp2( + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + Z. + 2. + ab-c.pq-r. + sxk.zzz.ac.uk. + x-.y-. + *** Failers + -abc.peq. + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + *.b0-a + *.c3-b.c + *.c-a.b-c + *** Failers + *.0 + *.a- + *.a-b.c- + *.c-a.0-c + +/^(?=ab(de))(abd)(e)/ + abde + +/^(?!(ab)de|x)(abd)(f)/ + abdf + +/^(?=(ab(cd)))(ab)/ + abcd + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + A.B.C.D + a.b.c.1.2.3.C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + \"abcd\" ; + \"\" ; rhubarb + *** Failers + \"1234\" : things + +/^$/ + \ + *** Failers + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + *** Failers + abc + ab cde + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + *** Failers + abc + ab cde + +/^ a\ b[c ]d $/x + a bcd + a b d + *** Failers + abcd + ab d + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + +/^a*\w/ + z + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a*?\w/ + z + az + aaaz + a + aa + aaaa + a+ + aa+ + +/^a+\w/ + az + aaaz + aa + aaaa + aa+ + +/^a+?\w/ + az + aaaz + aa + aaaa + aa+ + +/^\d{8}\w{2,}/ + 1234567890 + 12345678ab + 12345678__ + *** Failers + 1234567 + +/^[aeiou\d]{4,5}$/ + uoie + 1234 + 12345 + aaaaa + *** Failers + 123456 + +/^[aeiou\d]{4,5}?/ + uoie + 1234 + 12345 + aaaaa + 123456 + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + From abcd Mon Sep 1 12:33:02 1997 + *** Failers + From abcd Sep 01 12:33:02 1997 + +/^12.34/s + 12\n34 + 12\r34 + +/\w+(?=\t)/ + the quick brown\t fox + +/foo(?!bar)(.*)/ + foobar is foolish see? + +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + barrel + 2barrel + A barrel + +/^(\D*)(?=\d)(?!123)/ + abc456 + *** Failers + abc123 + +/^1234(?# test newlines + inside)/ + 1234 + +/^1234 #comment in extended re + /x + 1234 + +/#rhubarb + abcd/x + abcd + +/^abcd#rhubarb/x + abcd + +/(?!^)abc/ + the abc + *** Failers + abc + +/(?=^)abc/ + abc + *** Failers + the abc + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + + user\@dom.ain + \"A. Other\" (a comment) + A. Other (a comment) + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + A missing angle + a\rb + *** Failers + a\nb + +/abc$/ + abc + abc\n + *** Failers + abc\ndef + +/(abc)\123/ + abc\x53 + +/(abc)\223/ + abc\x93 + +/(abc)\323/ + abc\xd3 + +/(abc)\100/ + abc\x40 + abc\100 + +/(abc)\1000/ + abc\x400 + abc\x40\x30 + abc\1000 + abc\100\x30 + abc\100\060 + abc\100\60 + +/abc\81/ + abc\081 + abc\0\x38\x31 + +/abc\91/ + abc\091 + abc\0\x39\x31 + +/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ + abcdefghijk\12S + +/ab\idef/ + abidef + +/a{0}bc/ + bc + +/(a|(bc)){0,0}?xyz/ + xyz + +/abc[\10]de/ + abc\010de + +/abc[\1]de/ + abc\1de + +/(abc)[\1]de/ + abc\1de + +/(?s)a.b/ + a\nb + +/^([^a])([^\b])([^c]*)([^d]{3,4})/ + baNOTccccd + baNOTcccd + baNOTccd + bacccd + *** Failers + anything + b\bc + baccd + +/[^a]/ + Abc + +/[^a]/i + Abc + +/[^a]+/ + AAAaAbc + +/[^a]+/i + AAAaAbc + +/[^a]+/ + bbb\nccc + +/[^k]$/ + abc + *** Failers + abk + +/[^k]{2,3}$/ + abc + kbc + kabc + *** Failers + abk + akb + akk + +/^\d{8,}\@.+[^k]$/ + 12345678\@a.b.c.d + 123456789\@x.y.z + *** Failers + 12345678\@x.y.uk + 1234567\@a.b.c.d + +/[^a]/ + aaaabcd + aaAabcd + +/[^a]/i + aaaabcd + aaAabcd + +/[^az]/ + aaaabcd + aaAabcd + +/[^az]/i + aaaabcd + aaAabcd + +/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ + \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 + +/P[^*]TAIRE[^*]{1,6}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + +/P[^*]TAIRE[^*]{1,}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + +/(\.\d\d[1-9]?)\d+/ + 1.230003938 + 1.875000282 + 1.235 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 1.875000282 + *** Failers + 1.235 + +/a(?)b/ + ab + +/\b(foo)\s+(\w+)/i + Food is on the foo table + +/foo(.*)bar/ + The food is under the bar in the barn. + +/foo(.*?)bar/ + The food is under the bar in the barn. + +/(.*)(\d*)/ + I have 2 numbers: 53147 + +/(.*)(\d+)/ + I have 2 numbers: 53147 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 + +/(.*?)(\d+)/ + I have 2 numbers: 53147 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + +/^\D*(?!123)/ + ABC123 + +/^(\D*)(?=\d)(?!123)/ + ABC445 + *** Failers + ABC123 + +/^[W-]46]/ + W46]789 + -46]789 + *** Failers + Wall + Zebra + 42 + [abcd] + ]abcd[ + +/^[W-\]46]/ + W46]789 + Wall + Zebra + Xylophone + 42 + [abcd] + ]abcd[ + \\backslash + *** Failers + -46]789 + well + +/\d\d\/\d\d\/\d\d\d\d/ + 01/01/2000 + +/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/^(a){0,0}/ + bcd + abc + aab + +/^(a){0,1}/ + bcd + abc + aab + +/^(a){0,2}/ + bcd + abc + aab + +/^(a){0,3}/ + bcd + abc + aab + aaa + +/^(a){0,}/ + bcd + abc + aab + aaa + aaaaaaaa + +/^(a){1,1}/ + bcd + abc + aab + +/^(a){1,2}/ + bcd + abc + aab + +/^(a){1,3}/ + bcd + abc + aab + aaa + +/^(a){1,}/ + bcd + abc + aab + aaa + aaaaaaaa + +/.*\.gif/ + borfle\nbib.gif\nno + +/.{0,}\.gif/ + borfle\nbib.gif\nno + +/.*\.gif/m + borfle\nbib.gif\nno + +/.*\.gif/s + borfle\nbib.gif\nno + +/.*\.gif/ms + borfle\nbib.gif\nno + +/.*$/ + borfle\nbib.gif\nno + +/.*$/m + borfle\nbib.gif\nno + +/.*$/s + borfle\nbib.gif\nno + +/.*$/ms + borfle\nbib.gif\nno + +/.*$/ + borfle\nbib.gif\nno\n + +/.*$/m + borfle\nbib.gif\nno\n + +/.*$/s + borfle\nbib.gif\nno\n + +/.*$/ms + borfle\nbib.gif\nno\n + +/(.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(.*X|^B)/m + abcde\n1234Xyz + BarFoo + abcde\nBar + +/(.*X|^B)/s + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(.*X|^B)/ms + abcde\n1234Xyz + BarFoo + abcde\nBar + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/(?s:.*X|^B)/ + abcde\n1234Xyz + BarFoo + *** Failers + abcde\nBar + +/^.*B/ + **** Failers + abc\nB + +/(?s)^.*B/ + abc\nB + +/(?m)^.*B/ + abc\nB + +/(?ms)^.*B/ + abc\nB + +/(?ms)^B/ + abc\nB + +/(?s)B$/ + B\n + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + +/^\d\d\d\d\d\d\d\d\d\d\d\d/ + 123456654321 + +/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ + 123456654321 + +/^[abc]{12}/ + abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + *** Failers + z + +/abcde{0,0}/ + abcd + *** Failers + abce + +/ab[cd]{0,0}e/ + abe + *** Failers + abcde + +/ab(c){0,0}d/ + abd + *** Failers + abcd + +/a(b*)/ + a + ab + abbbb + *** Failers + bbbbb + +/ab\d{0}e/ + abe + *** Failers + ab1e + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + \"the \\\"quick\\\" brown fox\" + +/.*?/g+ + abc + +/\b/g+ + abc + +/\b/+g + abc + +//g + abc + +/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + +/a[^a]b/ + acb + a\nb + +/a.b/ + acb + *** Failers + a\nb + +/a[^a]b/s + acb + a\nb + +/a.b/s + acb + a\nb + +/^(b+?|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/^(b+|a){1,2}?c/ + bac + bbac + bbbac + bbbbac + bbbbbac + +/(?!\A)x/m + x\nb\n + a\bx\n + +/\x0{ab}/ + \0{ab} + +/(A|B)*?CD/ + CD + +/(A|B)*CD/ + CD + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\d\d[1-9]?))\d+/ + 1.230003938 + 1.875000282 + *** Failers + 1.235 + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + *** Failers + this is not a line with only words and spaces! + +/(\d+)(\w)/ + 12345a + 12345+ + +/((?>\d+))(\w)/ + 12345a + *** Failers + 12345+ + +/(?>a+)b/ + aaab + +/((?>a+)b)/ + aaab + +/(?>(a+))b/ + aaab + +/(?>b)+/ + aaabbbccc + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + +/(a+|b+|c+)*c/ + aaabbbbccccd + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + (abc(def)xyz) + *** Failers + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/a(?-i)b/i + ab + Ab + *** Failers + aB + AB + +/(a (?x)b c)d e/ + a bcd e + *** Failers + a b cd e + abcd e + a bcde + +/(a b(?x)c d (?-x)e f)/ + a bcde f + *** Failers + abcdef + +/(a(?i)b)c/ + abc + aBc + *** Failers + abC + aBC + Abc + ABc + ABC + AbC + +/a(?i:b)c/ + abc + aBc + *** Failers + ABC + abC + aBC + +/a(?i:b)*c/ + aBc + aBBc + *** Failers + aBC + aBBC + +/a(?=b(?i)c)\w\wd/ + abcd + abCd + *** Failers + aBCd + abcD + +/(?s-i:more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?:(?s-i)more.*than).*million/i + more than million + more than MILLION + more \n than Million + *** Failers + MORE THAN MILLION + more \n than \n million + +/(?>a(?i)b+)+c/ + abc + aBbc + aBBc + *** Failers + Abc + abAb + abbC + +/(?=a(?i)b)\w\wc/ + abc + aBc + *** Failers + Ab + abC + aBC + +/(?<=a(?i)b)(\w\w)c/ + abxxc + aBxxc + *** Failers + Abxxc + ABxxc + abxxC + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 12 + *** Failers + 123 + xyz + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 12 + *** Failers + 123 + xyz + +/(?(?<=foo)bar|cat)/ + foobar + cat + fcat + focat + *** Failers + foocat + +/(?(?a*)*/ + a + aa + aaaa + +/(abc|)+/ + abc + abcabc + abcabcabc + xyz + +/([a]*)*/ + a + aaaaa + +/([ab]*)*/ + a + b + ababab + aaaabcde + bbbb + +/([^a]*)*/ + b + bbbb + aaa + +/([^ab]*)*/ + cccc + abab + +/([a]*?)*/ + a + aaaa + +/([ab]*?)*/ + a + b + abab + baba + +/([^a]*?)*/ + b + bbbb + aaa + +/([^ab]*?)*/ + c + cccc + baba + +/(?>a*)*/ + a + aaabcde + +/((?>a*))*/ + aaaaa + aabbaa + +/((?>a*?))*/ + aaaaa + aabbaa + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 12-09-98 + *** Failers + sep-12-98 + +/(?i:saturday|sunday)/ + saturday + sunday + Saturday + Sunday + SATURDAY + SUNDAY + SunDay + +/(a(?i)bc|BB)x/ + abcx + aBCx + bbx + BBx + *** Failers + abcX + aBCX + bbX + BBX + +/^([ab](?i)[cd]|[ef])/ + ac + aC + bD + elephant + Europe + frog + France + *** Failers + Africa + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + aBd + xy + xY + zebra + Zambesi + *** Failers + aCD + XY + +/(?<=foo\n)^bar/m + foo\nbar + *** Failers + bar + baz\nbar + +/(?<=(?]&/ + <&OUT + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + +/(?<=a)b/ ab - a\x{100}b - a\x{100}\x{100}b - -/a\x{100}+b/8 - a\x{100}b - a\x{100}\x{100}b - *** Failers + *** Failers + cb + b + +/(?\S/8 - > >X Y - > >\x{100} Y - -/\d/8 - \x{100}3 - -/\s/8 - \x{100} X - -/\D+/8 - 12abcd34 +/((?-i:a.))b/i *** Failers - 1234 + AB + a\nB -/\D{2,3}/8 - 12abcd34 - 12ab34 - *** Failers - 1234 - 12a34 +/((?s-i:a.))b/i + a\nB -/\D{2,3}?/8 - 12abcd34 - 12ab34 - *** Failers - 1234 - 12a34 +/(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))/ + cabbbb -/\d+/8 - 12abcd34 - *** Failers +/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/ + caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -/\d{2,3}/8 - 12abcd34 - 1234abcd - *** Failers - 1.4 +/foo\w*\d{4}baz/ + foobar1234baz -/\d{2,3}?/8 - 12abcd34 - 1234abcd - *** Failers - 1.4 +/x(~~)*(?:(?:F)?)?/ + x~~ -/\S+/8 - 12abcd34 - *** Failers - \ \ +/^a(?#xxx){3}c/ + aaac -/\S{2,3}/8 - 12abcd34 - 1234abcd - *** Failers - \ \ +/^a (?#xxx) (?#yyy) {3}c/x + aaac -/\S{2,3}?/8 - 12abcd34 - 1234abcd +/(?\s+ <34 - *** Failers +/(?\s{2,3} \s{2,3}? a+)ab/ -/[\x{100}\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - *** Failers +/(?>a+)b/ + aaab -/[\x{100}-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - *** Failers +/([[:]+)/ + a:[b]: -/[z-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - abzcd - ab|cd - *** Failers +/([[=]+)/ + a=[b]= -/[Q\x{100}\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - Q? - *** Failers +/([[.]+)/ + a.[b]. -/[Q\x{100}-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - Q? - *** Failers +/((?>a+)b)/ + aaab -/[Qz-\x{200}]/8 - ab\x{100}cd - ab\x{200}cd - ab\x{111}cd - abzcd - ab|cd - Q? - *** Failers +/(?>(a+))b/ + aaab -/[\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + +/a\Z/ + *** Failers + aaab + a\nb\n -/[\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers +/b\Z/ + a\nb\n -/[Q\x{100}\x{200}]{1,3}/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers +/b\z/ -/[Q\x{100}\x{200}]{1,3}?/8 - ab\x{100}cd - ab\x{200}cd - ab\x{200}\x{100}\x{200}\x{100}cd - *** Failers +/b\Z/ + a\nb -/(?<=[\x{100}\x{200}])X/8 - abc\x{200}X - abc\x{100}X +/b\z/ + a\nb + *** Failers + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + endingwxyz *** Failers - X + a rather long string that doesn't end with one of them -/(?<=[Q\x{100}\x{200}])X/8 - abc\x{200}X - abc\x{100}X - abQX +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope + +/(?<=\d{3}(?!999))foo/ + 999foo + 123999foo + *** Failers + 123abcfoo + +/(?<=(?!...999)\d{3})foo/ + 999foo + 123999foo *** Failers - X + 123abcfoo -/(?<=[\x{100}\x{200}]{3})X/8 - abc\x{100}\x{200}\x{100}X +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 123456foo *** Failers - abc\x{200}X - X + 123999foo + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + +/((?>)+|A)*/ + ZABCDEFG + +/a*/g + abbab + +/^[a-\d]/ + abcde + -things + 0digit *** Failers - \x{100}X - \x{200}X + bcdef -/[^Q\x{100}\x{200}]X/8 - AX - \x{150}X - \x{500}X +/^[\d-a]/ + abcde + -things + 0digit *** Failers - \x{100}X - \x{200}X - QX + bcdef + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + +/a b/x + ab + +/(?!\A)x/m + a\nxb\n + +/(?!^)x/m + a\nxb\n -/[^\x{100}-\x{200}]X/8 - AX - \x{500}X +/abc\Qabc\Eabc/ + abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc *** Failers - \x{100}X - \x{150}X - \x{200}X + abcabcabc + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal -/[z-\x{100}]/8i - z - Z - \x{100} +/\Qabc\$xyz\E/ + abc\\\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + +/\Gabc/ + abc *** Failers - \x{102} - y + xyzabc -/[\xFF]/ - >\xff< +/\Gabc./g + abc1abc2xyzabc3 -/[\xff]/8 - >\x{ff}< +/abc./g + abc1abc2xyzabc3 -/[^\xFF]/ - XYZ +/a(?x: b c )d/ + XabcdY + *** Failers + Xa b c d Y -/[^\xff]/8 - XYZ - \x{123} +/((?x)x y z | a b c)/ + XabcY + AxyzB -/^[ac]*b/8 - xb +/(?i)AB(?-i)C/ + XabCY + *** Failers + XabcY -/^[ac\x{100}]*b/8 - xb +/((?i)AB(?-i)C|D)E/ + abCE + DE + *** Failers + abcE + abCe + dE + De -/^[^x]*b/8i - xb +/[z\Qa-d]\E]/ + z + a + - + d + ] + *** Failers + b -/^[^x]*b/8 - xb - -/^\d*b/8 - xb +/[\z\C]/ + z + C + +/\M/ + M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + regulaer + Regex + regulär + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + Åæåäÿ + ÅæåäÀ + Åæåäß + +/(?<=Z)X./ + \x84XAZXB + +/^(?(2)a|(1)(2))+$/ + 123a + +/(?<=a|bbbb)c/ + ac + bbbbc + +/abc/SS>testsavedregex +testsavedregex +testsavedregex +testsavedregex + + xyz\r\nabc\ + xyz\rabc\ + xyz\r\nabc\ + ** Failers + xyz\nabc\ + xyz\r\nabc\ + xyz\nabc\ + xyz\rabc\ + xyz\rabc\ + +/abc$/m + xyzabc + xyzabc\n + xyzabc\npqr + xyzabc\r\ + xyzabc\rpqr\ + xyzabc\r\n\ + xyzabc\r\npqr\ + ** Failers + xyzabc\r + xyzabc\rpqr + xyzabc\r\n + xyzabc\r\npqr + +/^abc/m + xyz\rabcdef + xyz\nabcdef\ + ** Failers + xyz\nabcdef + +/^abc/m + xyz\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/^abc/m + xyz\r\nabcdef + xyz\rabcdef\ + ** Failers + xyz\rabcdef + +/.*/ + abc\ndef + abc\rdef + abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + \abc\ndef + \abc\rdef + \abc\r\ndef + +/\w+(.)(.)?def/s + abc\ndef + abc\rdef + abc\r\ndef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + +/^(a()*)*/ + aaaa + +/^(?:a(?:(?:))*)*/ + aaaa + +/^(a()+)+/ + aaaa + +/^(?:a(?:(?:))+)+/ + aaaa + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -/^\x{85}$/8i - \x{85} +/^a.b/ + a\rb + a\nb\ + ** Failers + a\nb + a\nb\ + a\rb\ + a\rb\ -/^abc./mgx8 - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK -/abc.$/mgx8 - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 -/^a\Rb/8 +/^a\Rb/ a\nb a\rb a\r\nb a\x0bb a\x0cb - a\x{85}b - a\x{2028}b - a\x{2029}b + a\x85b ** Failers a\n\rb -/^a\R*b/8 +/^a\R*b/ ab a\nb a\rb a\r\nb a\x0bb - a\x0c\x{2028}\x{2029}b - a\x{85}b + a\x0cb + a\x85b a\n\rb - a\n\r\x{85}\x0cb + a\n\r\x85\x0cb -/^a\R+b/8 +/^a\R+b/ a\nb a\rb a\r\nb a\x0bb - a\x0c\x{2028}\x{2029}b - a\x{85}b + a\x0cb + a\x85b a\n\rb - a\n\r\x{85}\x0cb + a\n\r\x85\x0cb ** Failers ab - -/^a\R{1,3}b/8 + +/^a\R{1,3}b/ a\nb a\n\rb - a\n\r\x{85}b + a\n\r\x85b a\r\n\r\nb a\r\n\r\n\r\nb a\n\r\n\rb @@ -593,111 +4202,600 @@ a\n\n\n\rb a\r -/\h+\V?\v{3,4}/8 - \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a +/^a[\R]b/ + aRb + ** Failers + a\nb + +/.+foo/ + afoo + ** Failers + \r\nfoo + \nfoo + +/.+foo/ + afoo + \nfoo + ** Failers + \r\nfoo + +/.+foo/ + afoo + ** Failers + \nfoo + \r\nfoo + +/.+foo/s + afoo + \r\nfoo + \nfoo + +/^$/mg + abc\r\rxyz + abc\n\rxyz + ** Failers + abc\r\nxyz -/\V?\v{3,4}/8 - \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a +/^X/m + XABC + ** Failers + XABC\B -/\h+\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< +/(?m)^$/g+ + abc\r\n\r\n -/\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + +/(?m)$/g+ + abc\r\n\r\n -/\H\h\V\v/8 +/(?|(abc)|(xyz))/ + >abc< + >xyz< + +/(x)(?|(abc)|(xyz))(x)/ + xabcx + xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + xyzabc + ** Failers + xyzxyz + +/\H\h\V\v/ X X\x0a X\x09X\x0b ** Failers - \x{a0} X\x0a + \xa0 X\x0a -/\H*\h+\V?\v{3,4}/8 - \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a - \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a - \x09\x20\x{a0}\x0a\x0b\x0c - ** Failers - \x09\x20\x{a0}\x0a\x0b - -/\H\h\V\v/8 - \x{3001}\x{3000}\x{2030}\x{2028} - X\x{180e}X\x{85} - ** Failers - \x{2009} X\x0a - -/\H*\h+\V?\v{3,4}/8 - \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a - \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a - \x09\x20\x{202f}\x0a\x0b\x0c +/\H*\h+\V?\v{3,4}/ + \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a + \x09\x20\xa0\x0a\x0b\x0c ** Failers - \x09\x{200a}\x{a0}\x{2028}\x0b + \x09\x20\xa0\x0a\x0b -/a\Rb/I8 +/\H{3,4}/ + XY ABCDE + XY PQR ST + +/.\h{3,4}./ + XY AB PQRS + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + > X NYQZ + ** Failers + >XYZ + > X NY Z + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA + +/\nA/ + \r\nA + +/[\r\n]A/ + \r\nA + +/(\r|\n)A/ + \r\nA + +/a\Rb/I a\rb a\nb a\r\nb ** Failers - a\x{85}b + a\x85b a\x0bb -/a\Rb/I8 +/a\Rb/I a\rb a\nb a\r\nb - a\x{85}b + a\x85b a\x0bb ** Failers - a\x{85}b\ + a\x85b\ a\x0bb\ -/a\R?b/I8 +/a\R?b/I a\rb a\nb a\r\nb ** Failers - a\x{85}b + a\x85b a\x0bb -/a\R?b/I8 +/a\R?b/I a\rb a\nb a\r\nb - a\x{85}b + a\x85b a\x0bb ** Failers - a\x{85}b\ + a\x85b\ a\x0bb\ + +/a\R{2,4}b/I + a\r\n\nb + a\n\r\rb + a\r\n\r\n\r\n\r\nb + ** Failers + a\x85\85b + a\x0b\0bb + +/a\R{2,4}b/I + a\r\rb + a\n\n\nb + a\r\n\n\r\rb + a\x85\85b + a\x0b\0bb + ** Failers + a\r\r\r\r\rb + a\x85\85b\ + a\x0b\0bb\ + +/a(?!)|\wbc/ + abc + +/a[]b/ + ** Failers + ab + +/a[]+b/ + ** Failers + ab + +/a[]*+b/ + ** Failers + ab + +/a[^]b/ + aXb + a\nb + ** Failers + ab + +/a[^]+b/ + aXb + a\nX\nXb + ** Failers + ab + +/X$/E + X + ** Failers + X\n + +/X$/ + X + X\n + +/xyz/C + xyz + abcxyz + abcxyz\Y + ** Failers + abc + abc\Y + abcxypqr + abcxypqr\Y + +/(*NO_START_OPT)xyz/C + abcxyz + +/(?C)ab/ + ab + \C-ab + +/ab/C + ab + \C-ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" + \C-"ab" + +/\d+X|9+Y/ + ++++123999\P + ++++123999Y\P + +/Z(*F)/ + Z\P + ZA\P + +/Z(?!)/ + Z\P + ZA\P + +/dog(sbody)?/ + dogs\P + dogs\P\P + +/dog(sbody)??/ + dogs\P + dogs\P\P + +/dog|dogsbody/ + dogs\P + dogs\P\P -/X/8f - A\x{1ec5}ABCXYZ +/dogsbody|dog/ + dogs\P + dogs\P\P + +/Z(*F)Q|ZXY/ + Z\P + ZA\P + X\P + +/\bthe cat\b/ + the cat\P + the cat\P\P + +/dog(sbody)?/ + dogs\D\P + body\D\R + +/dog(sbody)?/ + dogs\D\P\P + body\D\R + +/abc/ + abc\P + abc\P\P + +/abc\K123/ + xyzabc123pqr + +/(?<=abc)123/ + xyzabc123pqr + xyzabc12\P + xyzabc12\P\P + +/\babc\b/ + +++abc+++ + +++ab\P + +++ab\P\P + +/(?=C)/g+ + ABCDECBA + +/(abc|def|xyz)/I + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + +/(abc|def|xyz)/SI + terhjk;abcdaadsfe + the quick xyz brown fox + \Yterhjk;abcdaadsfe + \Ythe quick xyz brown fox + ** Failers + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -/abcd*/8 +/abcd*/+ xxxxabcd\P xxxxabcd\P\P + dddxxx\R + xxxxabcd\P\P + xxx\R -/abcd*/i8 +/abcd*/i xxxxabcd\P xxxxabcd\P\P XXXXABCD\P XXXXABCD\P\P -/abc\d*/8 +/abc\d*/ xxxxabc1\P xxxxabc1\P\P -/abc[de]*/8 +/abc[de]*/ xxxxabcde\P xxxxabcde\P\P -/\bthe cat\b/8 - the cat\P - the cat\P\P +/(?:(?1)|B)(A(*F)|C)/ + ABCD + CCD + ** Failers + CAD + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + BCD + ** Failers + ABCD + CAD + BAD + +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?(?!a(*SKIP)b))/ + ac + +/(?<=abc)def/ + abc\P\P + +/abc$/ + abc + abc\P + abc\P\P + +/abc$/m + abc + abc\n + abc\P\P + abc\n\P\P + abc\P + abc\n\P + +/abc\z/ + abc + abc\P + abc\P\P + +/abc\Z/ + abc + abc\P + abc\P\P + +/abc\b/ + abc + abc\P + abc\P\P + +/abc\B/ + abc + abc\P + abc\P\P + +/.+/ + abc\>0 + abc\>1 + abc\>2 + abc\>3 + abc\>4 + abc\>-4 + +/^(?:a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(?:aa|(?:a)++\w)/ + aaaab + aaaa + ** Failers + bbb + +/^(?:a)*+\w/ + aaaab + bbb + ** Failers + aaaa + +/^(a)++\w/ + aaaab + ** Failers + aaaa + bbb + +/^(a|)++\w/ + aaaab + ** Failers + aaaa + bbb + +/(?=abc){3}abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)+abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc)++abc/+ + abcabcabc + ** Failers + xyz + +/(?=abc){0}xyz/ + xyz + +/(?=abc){1}xyz/ + ** Failers + xyz + +/(?=(a))?./ + ab + bc + +/(?=(a))??./ + ab + bc -/a+/8 - a\x{123}aa\>1 - a\x{123}aa\>2 - a\x{123}aa\>3 - a\x{123}aa\>4 - a\x{123}aa\>5 - a\x{123}aa\>6 +/^(?=(a)){0}b(?1)/ + backgammon + +/^(?=(?1))?[az]([abc])d/ + abd + zcdxx + +/^(?!a){0}\w+/ + aaaaa + +/(?<=(abc))?xyz/ + abcxyz + pqrxyz + +/((?2))((?1))/ + abc + +/(?(R)a+|(?R)b)/ + aaaabcde + +/(?(R)a+|((?R))b)/ + aaaabcde + +/((?(R)a+|(?1)b))/ + aaaabcde + +/((?(R2)a+|(?1)b))/ + aaaabcde + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde + +/(a+)/ + \O6aaaa + \O8aaaa + +/ab\Cde/ + abXde + +/(?<=ab\Cde)X/ + abZdeX + +/^\R/ + \r\P + \r\P\P + +/^\R{2,3}x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R{2,3}?x/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + \r\rx + \r\r\rx + +/^\R?x/ + \r\P + \r\P\P + x + \rx + +/^\R+x/ + \r\P + \r\P\P + \r\n\P + \r\n\P\P + \rx + +/^a$/ + a\r\P + a\r\P\P + +/^a$/m + a\r\P + a\r\P\P + +/^(a$|a\r)/ + a\r\P + a\r\P\P + +/^(a$|a\r)/m + a\r\P + a\r\P\P + +/./ + \r\P + \r\P\P + +/.{2,3}/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/ + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + xx\xa0xabcd + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + xx\xa0xxxxxabcd -/-- End of testinput8 --/ +/-- End of testinput8 --/ diff -Nru pcre3-8.12/testdata/testinput9 pcre3-8.31/testdata/testinput9 --- pcre3-8.12/testdata/testinput9 2010-05-08 11:36:46.000000000 +0000 +++ pcre3-8.31/testdata/testinput9 2012-06-01 18:31:44.000000000 +0000 @@ -1,989 +1,717 @@ -/-- This set of tests check Unicode property support with the DFA matching - functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest - when running it. --/ - -/\pL\P{Nd}/8 - AB +/-- This set of tests checks UTF-8 support with the DFA matching functionality + of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running + it. --/ + +/\x{100}ab/8 + \x{100}ab + +/a\x{100}*b/8 + ab + a\x{100}b + a\x{100}\x{100}b + +/a\x{100}+b/8 + a\x{100}b + a\x{100}\x{100}b + *** Failers + ab + +/\bX/8 + Xoanon + +Xoanon + \x{300}Xoanon + *** Failers + YXoanon + +/\BX/8 + YXoanon *** Failers - A0 - 00 + Xoanon + +Xoanon + \x{300}Xoanon + +/X\b/8 + X+oanon + ZX\x{300}oanon + FAX + *** Failers + Xoanon + +/X\B/8 + Xoanon + *** Failers + X+oanon + ZX\x{300}oanon + FAX + +/[^a]/8 + abcd + a\x{100} -/\X./8 - AB - A\x{300}BC - A\x{300}\x{301}\x{302}BC +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + \x{123}\x{123}45 + \x{400}\x{401}\x{402}6 + *** Failers + d99 + \x{123}\x{122}4 + \x{400}\x{403}6 + \x{400}\x{401}\x{402}\x{402}6 + +/a.b/8 + acb + a\x7fb + a\x{100}b + *** Failers + a\nb + +/a(.{3})b/8 + a\x{4000}xyb + a\x{4000}\x7fyb + a\x{4000}\x{100}yb + *** Failers + a\x{4000}b + ac\ncb + +/a(.*?)(.)/ + a\xc0\x88b + +/a(.*?)(.)/8 + a\x{100}b + +/a(.*)(.)/ + a\xc0\x88b + +/a(.*)(.)/8 + a\x{100}b + +/a(.)(.)/ + a\xc0\x92bcd + +/a(.)(.)/8 + a\x{240}bcd + +/a(.?)(.)/ + a\xc0\x92bcd + +/a(.?)(.)/8 + a\x{240}bcd + +/a(.??)(.)/ + a\xc0\x92bcd + +/a(.??)(.)/8 + a\x{240}bcd + +/a(.{3})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + *** Failers + a\x{1234}b + ac\ncb + +/a(.{3,})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + *** Failers + a\x{1234}b + +/a(.{3,5})b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb + *** Failers + a\x{1234}b + axxxxxxbcdefghijb + +/a(.{3,5}?)b/8 + a\x{1234}xyb + a\x{1234}\x{4321}yb + a\x{1234}\x{4321}\x{3412}b + axxxxbcdefghijb + a\x{1234}\x{4321}\x{3412}\x{3421}b + axbxxbcdefghijb + axxxxxbcdefghijb *** Failers - \x{300} + a\x{1234}b + axxxxxxbcdefghijb -/\X\X/8 - ABC - A\x{300}B\x{300}\x{301}C - A\x{300}\x{301}\x{302}BC +/^[a\x{c0}]/8 *** Failers - \x{300} + \x{100} -/^\pL+/8 - abcd - a - *** Failers +/(?<=aXb)cd/8 + aXbcd -/^\PL+/8 - 1234 - = - *** Failers - abcd +/(?<=a\x{100}b)cd/8 + a\x{100}bcd -/^\X+/8 - abcdA\x{300}\x{301}\x{302} - A\x{300}\x{301}\x{302} - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} - a +/(?<=a\x{100000}b)cd/8 + a\x{100000}bcd + +/(?:\x{100}){3}b/8 + \x{100}\x{100}\x{100}b *** Failers - \x{300}\x{301}\x{302} + \x{100}\x{100}b -/\X?abc/8 - abc - A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - \x{300}abc - *** Failers +/\x{ab}/8 + \x{ab} + \xc2\xab + *** Failers + \x00{ab} -/^\X?abc/8 - abc - A\x{300}abc +/(?<=(.))X/8 + WXYZ + \x{256}XYZ *** Failers - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - \x{300}abc + XYZ -/\X*abc/8 - abc - A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - \x{300}abc - *** Failers +/[^a]+/8g + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8 + \x{100}bc + +/^[^a]{2,}/8 + \x{100}bcAa -/^\X*abc/8 - abc - A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - *** Failers - \x{300}abc +/^[^a]{2,}?/8 + \x{100}bca -/^\pL?=./8 - A=b - =c - *** Failers - 1=2 - AAAA=b +/[^a]+/8ig + bcd + \x{100}aY\x{256}Z + +/^[^a]{2}/8i + \x{100}bc + +/^[^a]{2,}/8i + \x{100}bcAa -/^\pL*=./8 - AAAA=b - =c - *** Failers - 1=2 +/^[^a]{2,}?/8i + \x{100}bca -/^\X{2,3}X/8 - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - *** Failers - X - A\x{300}\x{301}\x{302}X - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X +/\x{100}{0,0}/8 + abcd + +/\x{100}?/8 + abcd + \x{100}\x{100} -/^\pC\pL\pM\pN\pP\pS\pZ\S/8 + > >X Y + > >\x{100} Y + +/\d/8 + \x{100}3 + +/\s/8 + \x{100} X + /\D+/8 - 11111111111111111111111111111111111111111111111111111111111111111111111 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/\P{Nd}+/8 - 11111111111111111111111111111111111111111111111111111111111111111111111 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/[\D]+/8 - 11111111111111111111111111111111111111111111111111111111111111111111111 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/[\P{Nd}]+/8 - 11111111111111111111111111111111111111111111111111111111111111111111111 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/[\D\P{Nd}]+/8 - 11111111111111111111111111111111111111111111111111111111111111111111111 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/\pL/8 - a - A - -/\pL/8i - a - A - -/\p{Lu}/8 - A - aZ - ** Failers - abc + 12abcd34 + *** Failers + 1234 -/\p{Lu}/8i - A - aZ - ** Failers - abc +/\D{2,3}/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 -/\p{Ll}/8 - a - Az - ** Failers - ABC +/\D{2,3}?/8 + 12abcd34 + 12ab34 + *** Failers + 1234 + 12a34 -/\p{Ll}/8i - a - Az - ** Failers - ABC +/\d+/8 + 12abcd34 + *** Failers -/^\x{c0}$/8i - \x{c0} - \x{e0} - -/^\x{e0}$/8i - \x{c0} - \x{e0} +/\d{2,3}/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8 - A\x{391}\x{10427}\x{ff3a}\x{1fb0} - ** Failers - a\x{391}\x{10427}\x{ff3a}\x{1fb0} - A\x{3b1}\x{10427}\x{ff3a}\x{1fb0} - A\x{391}\x{1044F}\x{ff3a}\x{1fb0} - A\x{391}\x{10427}\x{ff5a}\x{1fb0} - A\x{391}\x{10427}\x{ff3a}\x{1fb8} - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8i - A\x{391}\x{10427}\x{ff3a}\x{1fb0} - a\x{391}\x{10427}\x{ff3a}\x{1fb0} - A\x{3b1}\x{10427}\x{ff3a}\x{1fb0} - A\x{391}\x{1044F}\x{ff3a}\x{1fb0} - A\x{391}\x{10427}\x{ff5a}\x{1fb0} - A\x{391}\x{10427}\x{ff3a}\x{1fb8} - -/\x{391}+/8i - \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391} - -/\x{391}{3,5}(.)/8i - \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}X - -/\x{391}{3,5}?(.)/8i - \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}X - -/[\x{391}\x{ff3a}]/8i - \x{391} - \x{ff3a} - \x{3b1} - \x{ff5a} - -/[\x{c0}\x{391}]/8i - \x{c0} - \x{e0} - -/[\x{105}-\x{109}]/8i - \x{104} - \x{105} - \x{109} - ** Failers - \x{100} - \x{10a} - -/[z-\x{100}]/8i - Z - z - \x{39c} - \x{178} - | - \x{80} - \x{ff} - \x{100} - \x{101} - ** Failers - \x{102} - Y - y +/\d{2,3}?/8 + 12abcd34 + 1234abcd + *** Failers + 1.4 -/[z-\x{100}]/8i +/\S+/8 + 12abcd34 + *** Failers + \ \ -/^\X/8 - A - A\x{300}BC - A\x{300}\x{301}\x{302}BC +/\S{2,3}/8 + 12abcd34 + 1234abcd *** Failers - \x{300} + \ \ -/^[\X]/8 - X123 +/\S{2,3}?/8 + 12abcd34 + 1234abcd *** Failers - AXYZ + \ \ -/^(\X*)C/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C +/>\s+ <34 + *** Failers -/^(\X*?)C/8 - A\x{300}\x{301}\x{302}BCA\x{300}\x{301} - A\x{300}\x{301}\x{302}BCA\x{300}\x{301}C +/>\s{2,3} \s{2,3}? \xff< -/^[\p{Any}]*X/8 +/[\xff]/8 + >\x{ff}< + +/[^\xFF]/ XYZ - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - ** Failers -/^[\P{Any}]*X/8 +/[^\xff]/8 XYZ - ** Failers - AXYZ - \x{1234}XYZ - A\x{1234}XYZ - -/^\p{Any}{3,5}?/8 - abcdefgh - \x{1234}\n\r\x{3456}xyz - -/^\p{Any}{3,5}/8 - abcdefgh - \x{1234}\n\r\x{3456}xyz + \x{123} -/^\P{Any}{3,5}?/8 - ** Failers - abcdefgh - \x{1234}\n\r\x{3456}xyz +/^[ac]*b/8 + xb -/^\p{L&}X/8 - AXY - aXY - \x{1c5}XY - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]X/8 - AXY - aXY - \x{1c5}XY - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\p{L&}+X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]+X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\p{L&}+?X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^[\p{L&}]+?X/8 - AXY - aXY - AbcdeXyz - \x{1c5}AbXY - abcDEXypqreXlmn - ** Failers - \x{1bb}XY - \x{2b0}XY - !XY - -/^\P{L&}X/8 - !XY - \x{1bb}XY - \x{2b0}XY - ** Failers - \x{1c5}XY - AXY - -/^[\P{L&}]X/8 - !XY - \x{1bb}XY - \x{2b0}XY - ** Failers - \x{1c5}XY - AXY +/^[ac\x{100}]*b/8 + xb -/^\x{023a}+?(\x{0130}+)/8i - \x{023a}\x{2c65}\x{0130} +/^[^x]*b/8i + xb + +/^[^x]*b/8 + xb -/^\x{023a}+([^X])/8i - \x{023a}\x{2c65}X - -/\x{c0}+\x{116}+/8i - \x{c0}\x{e0}\x{116}\x{117} +/^\d*b/8 + xb -/[\x{c0}\x{116}]+/8i - \x{c0}\x{e0}\x{116}\x{117} +/(|a)/g8 + catac + a\x{256}a -/Check property support in non-UTF-8 mode/ - -/\p{L}{4}/ - 123abcdefg - 123abc\xc4\xc5zz - -/\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}/8 - \x{102A4}\x{AA52}\x{A91D}\x{1C46}\x{10283}\x{1092E}\x{1C6B}\x{A93B}\x{A8BF}\x{1BA0}\x{A50A}==== - -/\x{a77d}\x{1d79}/8i - \x{a77d}\x{1d79} - \x{1d79}\x{a77d} +/^\x{85}$/8i + \x{85} -/\x{a77d}\x{1d79}/8 - \x{a77d}\x{1d79} - ** Failers - \x{1d79}\x{a77d} +/^abc./mgx8 + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK -/^\p{Xan}/8 - ABCD - 1234 - \x{6ca} - \x{a6c} - \x{10a7} - ** Failers - _ABC +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 -/^\p{Xan}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ +/^a\Rb/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0cb + a\x{85}b + a\x{2028}b + a\x{2029}b ** Failers - _ABC + a\n\rb -/^\p{Xan}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xan}{2,9}/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^[\p{Xan}]/8 - ABCD1234_ - 1234abcd_ - \x{6ca} - \x{a6c} - \x{10a7} - ** Failers - _ABC - -/^[\p{Xan}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - ** Failers - _ABC +/^a\R*b/8 + ab + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb -/^>\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} +/^a\R+b/8 + a\nb + a\rb + a\r\nb + a\x0bb + a\x0c\x{2028}\x{2029}b + a\x{85}b + a\n\rb + a\n\r\x{85}\x0cb ** Failers - \x{0b} - -/^>\p{Xsp}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xsp}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xsp}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + ab -/^>\p{Xps}/8 - >\x{1680}\x{2028}\x{0b} - >\x{a0} +/^a\R{1,3}b/8 + a\nb + a\n\rb + a\n\r\x{85}b + a\r\n\r\nb + a\r\n\r\n\r\nb + a\n\r\n\rb + a\n\n\r\nb ** Failers - \x{0b} + a\n\n\n\rb + a\r -/^>\p{Xps}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} +/\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a -/^>\p{Xps}+?/8 - >\x{1680}\x{2028}\x{0b} +/\V?\v{3,4}/8 + \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a -/^>\p{Xps}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>[\p{Xps}]/8 - >\x{2028}\x{0b} - -/^>[\p{Xps}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} +/\h+\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< -/^\p{Xwd}/8 - ABCD - 1234 - \x{6ca} - \x{a6c} - \x{10a7} - _ABC - ** Failers - [] +/\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< -/^\p{Xwd}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}{2,9}/8 - A_12\x{6ca}\x{a6c}\x{10a7} - -/^[\p{Xwd}]/8 - ABCD1234_ - 1234abcd_ - \x{6ca} - \x{a6c} - \x{10a7} - _ABC +/\H\h\V\v/8 + X X\x0a + X\x09X\x0b ** Failers - [] + \x{a0} X\x0a + +/\H*\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + \x09\x20\x{a0}\x0a\x0b\x0c + ** Failers + \x09\x20\x{a0}\x0a\x0b + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} + ** Failers + \x{2009} X\x0a + +/\H*\h+\V?\v{3,4}/8 + \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a + \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a + \x09\x20\x{202f}\x0a\x0b\x0c + ** Failers + \x09\x{200a}\x{a0}\x{2028}\x0b + +/a\Rb/I8 + a\rb + a\nb + a\r\nb + ** Failers + a\x{85}b + a\x0bb + +/a\Rb/I8 + a\rb + a\nb + a\r\nb + a\x{85}b + a\x0bb + ** Failers + a\x{85}b\ + a\x0bb\ + +/a\R?b/I8 + a\rb + a\nb + a\r\nb + ** Failers + a\x{85}b + a\x0bb + +/a\R?b/I8 + a\rb + a\nb + a\r\nb + a\x{85}b + a\x0bb + ** Failers + a\x{85}b\ + a\x0bb\ -/^[\p{Xwd}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ +/X/8f + A\x{1ec5}ABCXYZ -/-- Unicode properties for \b abd \B --/ +/abcd*/8 + xxxxabcd\P + xxxxabcd\P\P + +/abcd*/i8 + xxxxabcd\P + xxxxabcd\P\P + XXXXABCD\P + XXXXABCD\P\P + +/abc\d*/8 + xxxxabc1\P + xxxxabc1\P\P + +/abc[de]*/8 + xxxxabcde\P + xxxxabcde\P\P + +/\bthe cat\b/8 + the cat\P + the cat\P\P + +/ab\Cde/8 + abXde + +/(?<=ab\Cde)X/8 + +/./8 + \r\P + \r\P\P + +/.{2,3}/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P + +/.{2,3}?/8 + \r\P + \r\P\P + \r\r\P + \r\r\P\P + \r\r\r\P + \r\r\r\P\P -/\b...\B/8W - abc_ - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ +/[^\x{100}]/8 + \x{100}\x{101}X -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ - -/\b...\B/8 - abc_ - ** Failers - \x{37e}abc\x{376} - \x{37e}\x{376}\x{371}\x{393}\x{394} - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ - -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ - -/\b...\B/W - abc_ - !\x{c0}++\x{c1}\x{c2} - !\x{c0}+++++ +/[^\x{100}]+/8 + \x{100}\x{101}X /-- End of testinput9 --/ diff -Nru pcre3-8.12/testdata/testoutput1 pcre3-8.31/testdata/testoutput1 --- pcre3-8.12/testdata/testoutput1 2010-11-20 17:29:24.000000000 +0000 +++ pcre3-8.31/testdata/testoutput1 2012-06-16 17:52:11.000000000 +0000 @@ -1,5 +1,6 @@ /-- This set of tests is for features that are compatible with all versions of - Perl 5, in non-UTF-8 mode. --/ + Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and + 16-bit PCRE libraries. --/ /the quick brown fox/ the quick brown fox @@ -6666,4 +6667,2070 @@ ? 0: ? +/(abc)\1/i + abc +No match + +/(abc)\1/ + abc +No match + +/[^a]*/i + 12abc + 0: 12 + 12ABC + 0: 12 + +/[^a]*+/i + 12abc + 0: 12 + 12ABC + 0: 12 + +/[^a]*?X/i + ** Failers +No match + 12abc +No match + 12ABC +No match + +/[^a]+?X/i + ** Failers +No match + 12abc +No match + 12ABC +No match + +/[^a]?X/i + 12aXbcX + 0: X + 12AXBCX + 0: X + BCX + 0: CX + +/[^a]??X/i + 12aXbcX + 0: X + 12AXBCX + 0: X + BCX + 0: CX + +/[^a]?+X/i + 12aXbcX + 0: cX + 12AXBCX + 0: CX + BCX + 0: CX + +/[^a]{2,3}/i + abcdef + 0: bcd + ABCDEF + 0: BCD + +/[^a]{2,3}?/i + abcdef + 0: bc + ABCDEF + 0: BC + +/[^a]{2,3}+/i + abcdef + 0: bcd + ABCDEF + 0: BCD + +/((a|)+)+Z/ + Z + 0: Z + 1: + 2: + +/(a)b|(a)c/ + ac + 0: ac + 1: + 2: a + +/(?>(a))b|(a)c/ + ac + 0: ac + 1: + 2: a + +/(?=(a))ab|(a)c/ + ac + 0: ac + 1: + 2: a + +/((?>(a))b|(a)c)/ + ac + 0: ac + 1: ac + 2: + 3: a + +/((?>(a))b|(a)c)++/ + ac + 0: ac + 1: ac + 2: + 3: a + +/(?:(?>(a))b|(a)c)++/ + ac + 0: ac + 1: + 2: a + +/(?=(?>(a))b|(a)c)(..)/ + ac + 0: ac + 1: + 2: a + 3: ac + +/(?>(?>(a))b|(a)c)/ + ac + 0: ac + 1: + 2: a + +/(?:(?>([ab])))+a=/+ + =ba= + 0: ba= + 0+ + 1: b + +/(?>([ab]))+a=/+ + =ba= + 0: ba= + 0+ + 1: b + +/((?>(a+)b)+(aabab))/ + aaaabaaabaabab + 0: aaaabaaabaabab + 1: aaaabaaabaabab + 2: aaa + 3: aabab + +/(?>a+|ab)+?c/ + aabc +No match + +/(?>a+|ab)+c/ + aabc +No match + +/(?:a+|ab)+c/ + aabc + 0: aabc + +/(?(?=(a))a)/ + a + 0: a + 1: a + +/(?(?=(a))a)(b)/ + ab + 0: ab + 1: a + 2: b + +/^(?:a|ab)++c/ + aaaabc +No match + +/^(?>a|ab)++c/ + aaaabc +No match + +/^(?:a|ab)+c/ + aaaabc + 0: aaaabc + +/(?=abc){3}abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)+abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)++abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc){0}xyz/ + xyz + 0: xyz + +/(?=abc){1}xyz/ + ** Failers +No match + xyz +No match + +/(?=(a))?./ + ab + 0: a + 1: a + bc + 0: b + +/(?=(a))??./ + ab + 0: a + bc + 0: b + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/^(?=(?1))?[az]([abc])d/ + abd + 0: abd + 1: b + zcdxx + 0: zcd + 1: c + +/^(?!a){0}\w+/ + aaaaa + 0: aaaaa + +/(?<=(abc))?xyz/ + abcxyz + 0: xyz + 1: abc + pqrxyz + 0: xyz + +/^[\g]+/ + ggg<<>> + 0: ggg<<>> + ** Failers +No match + \\ga +No match + +/^[\ga]+/ + gggagagaxyz + 0: gggagaga + +/^[:a[:digit:]]+/ + aaaa444:::Z + 0: aaaa444::: + +/^[:a[:digit:]:b]+/ + aaaa444:::bbbZ + 0: aaaa444:::bbb + +/[:a]xxx[b:]/ + :xxx: + 0: :xxx: + +/(?<=a{2})b/i + xaabc + 0: b + ** Failers +No match + xabc +No match + +/(?XNNNYZ + 0: XNNNYZ + > X NYQZ + 0: X NYQZ + ** Failers +No match + >XYZ +No match + > X NY Z +No match + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + 0: XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/(foo)\Kbar/ + foobar + 0: bar + 1: foo + +/(foo)(\Kbar|baz)/ + foobar + 0: bar + 1: foo + 2: bar + foobaz + 0: foobaz + 1: foo + 2: baz + +/(foo\Kbar)baz/ + foobarbaz + 0: barbaz + 1: foobar + +/abc\K|def\K/g+ + Xabcdefghi + 0: + 0+ defghi + 0: + 0+ ghi + +/ab\Kc|de\Kf/g+ + Xabcdefghi + 0: c + 0+ defghi + 0: f + 0+ ghi + +/(?=C)/g+ + ABCDECBA + 0: + 0+ CDECBA + 0: + 0+ CBA + +/^abc\K/+ + abcdef + 0: + 0+ def + ** Failers +No match + defabcxyz +No match + +/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ + ababababbbabZXXXX + 0: ababababbbabZ + 1: ab + 2: b + +/(?tom|bon)-\g{A}/ + tom-tom + 0: tom-tom + 1: tom + bon-bon + 0: bon-bon + 1: bon + +/(^(a|b\g{-1}))/ + bacxxx +No match + +/(?|(abc)|(xyz))\1/ + abcabc + 0: abcabc + 1: abc + xyzxyz + 0: xyzxyz + 1: xyz + ** Failers +No match + abcxyz +No match + xyzabc +No match + +/(?|(abc)|(xyz))(?1)/ + abcabc + 0: abcabc + 1: abc + xyzabc + 0: xyzabc + 1: xyz + ** Failers +No match + xyzxyz +No match + +/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: c + 4: d + 5: Y + +/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: + 4: + 5: c + 6: d + 7: Y + +/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ + XYabcdY + 0: XYabcdY + 1: a + 2: b + 3: + 4: + 5: c + 6: d + 7: Y + +/(?'abc'\w+):\k{2}/ + a:aaxyz + 0: a:aa + 1: a + ab:ababxyz + 0: ab:abab + 1: ab + ** Failers +No match + a:axyz +No match + ab:abxyz +No match + +/(?'abc'\w+):\g{abc}{2}/ + a:aaxyz + 0: a:aa + 1: a + ab:ababxyz + 0: ab:abab + 1: ab + ** Failers +No match + a:axyz +No match + ab:abxyz +No match + +/^(?a)? (?()b|c) (?('ab')d|e)/x + abd + 0: abd + 1: a + ce + 0: ce + +/^(a.)\g-1Z/ + aXaXZ + 0: aXaXZ + 1: aX + +/^(a.)\g{-1}Z/ + aXaXZ + 0: aXaXZ + 1: aX + +/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x + abcd + 0: ab + +/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) + (?(DEFINE) + (?[a-z]+) + (?\d+) + )/x + metcalfe 33 + 0: metcalfe 33 + 1: metcalfe + 2: 33 + +/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ + 1.2.3.4 + 0: 1.2.3.4 + 1: + 2: .4 + 131.111.10.206 + 0: 131.111.10.206 + 1: + 2: .206 + 10.0.0.0 + 0: 10.0.0.0 + 1: + 2: .0 + ** Failers +No match + 10.6 +No match + 455.3.4.5 +No match + +/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ + 1.2.3.4 + 0: 1.2.3.4 + 1: .4 + 131.111.10.206 + 0: 131.111.10.206 + 1: .206 + 10.0.0.0 + 0: 10.0.0.0 + 1: .0 + ** Failers +No match + 10.6 +No match + 455.3.4.5 +No match + +/^(\w++|\s++)*$/ + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + 1: party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d++)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: a + *** Failers +No match + 12345+ +No match + +/a++b/ + aaab + 0: aaab + +/(a++b)/ + aaab + 0: aaab + 1: aaab + +/(a++)b/ + aaab + 0: aaab + 1: aaa + +/([^()]++|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: x + +/\(([^()]++|\([^()]+\))+\)/ + (abc) + 0: (abc) + 1: abc + (abc(def)xyz) + 0: (abc(def)xyz) + 1: xyz + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/^([^()]|\((?1)*\))*$/ + abc + 0: abc + 1: c + a(b)c + 0: a(b)c + 1: c + a(b(c))d + 0: a(b(c))d + 1: d + *** Failers) +No match + a(b(c)d +No match + +/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) + 2: + 3: Satanoscillatemymetallicsonatas + 4: S + AmanaplanacanalPanama + 0: AmanaplanacanalPanama + 1: + 2: + 3: AmanaplanacanalPanama + 4: A + AblewasIereIsawElba + 0: AblewasIereIsawElba + 1: + 2: + 3: AblewasIereIsawElba + 4: A + *** Failers +No match + Thequickbrownfox +No match + +/^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ + 12 + 0: 12 + 1: 12 + (((2+2)*-3)-7) + 0: (((2+2)*-3)-7) + 1: (((2+2)*-3)-7) + 2: - + -12 + 0: -12 + 1: -12 + *** Failers +No match + ((2+2)*-3)-7) +No match + +/^(x(y|(?1){2})z)/ + xyz + 0: xyz + 1: xyz + 2: y + xxyzxyzz + 0: xxyzxyzz + 1: xxyzxyzz + 2: xyzxyz + *** Failers +No match + xxyzz +No match + xxyzxyzxyzz +No match + +/((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x + <> + 0: <> + 1: <> + 2: <> + + 0: + 1: + 2: + hij> + 0: hij> + 1: hij> + 2: hij> + hij> + 0: + 1: + 2: + def> + 0: def> + 1: def> + 2: def> + + 0: <> + 1: <> + 2: <> + *** Failers +No match + + 2: + 3: Satan, oscillate my metallic sonatas + 4: S + A man, a plan, a canal: Panama! + 0: A man, a plan, a canal: Panama! + 1: + 2: + 3: A man, a plan, a canal: Panama + 4: A + Able was I ere I saw Elba. + 0: Able was I ere I saw Elba. + 1: + 2: + 3: Able was I ere I saw Elba + 4: A + *** Failers +No match + The quick brown fox +No match + +/^((.)(?1)\2|.)$/ + a + 0: a + 1: a + aba + 0: aba + 1: aba + 2: a + aabaa + 0: aabaa + 1: aabaa + 2: a + abcdcba + 0: abcdcba + 1: abcdcba + 2: a + pqaabaaqp + 0: pqaabaaqp + 1: pqaabaaqp + 2: p + ablewasiereisawelba + 0: ablewasiereisawelba + 1: ablewasiereisawelba + 2: a + rhubarb +No match + the quick brown fox +No match + +/(a)(?<=b(?1))/ + baz + 0: a + 1: a + ** Failers +No match + caz +No match + +/(?<=b(?1))(a)/ + zbaaz + 0: a + 1: a + ** Failers +No match + aaa +No match + +/(?a)(?<=b(?&X))/ + baz + 0: a + 1: a + +/^(?|(abc)|(def))\1/ + abcabc + 0: abcabc + 1: abc + defdef + 0: defdef + 1: def + ** Failers +No match + abcdef +No match + defabc +No match + +/^(?|(abc)|(def))(?1)/ + abcabc + 0: abcabc + 1: abc + defabc + 0: defabc + 1: def + ** Failers +No match + defdef +No match + abcdef +No match + +/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ + a\"aaaaa + 0: a"aaaaa + 1: " + 2: + 3: " + b\"aaaaa + 0: b"aaaaa + 1: + 2: + 3: + 4: " + 5: + 6: " + ** Failers +No match + b\"11111 +No match + +/(?:(?1)|B)(A(*F)|C)/ + ABCD + 0: BC + 1: C + CCD + 0: CC + 1: C + ** Failers +No match + CAD +No match + +/^(?:(?1)|B)(A(*F)|C)/ + CCD + 0: CC + 1: C + BCD + 0: BC + 1: C + ** Failers +No match + ABCD +No match + CAD +No match + BAD +No match + +/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ + AAD + 0: AA + 1: A + ACD + 0: ACD + 1: C + BAD + 0: BA + 1: A + BCD + 0: BCD + 1: C + BAX + 0: BA + 1: A + ** Failers +No match + ACX +No match + ABC +No match + +/(?(DEFINE)(A))B(?1)C/ + BAC + 0: BAC + +/(?(DEFINE)((A)\2))B(?1)C/ + BAAC + 0: BAAC + +/(? \( ( [^()]++ | (?&pn) )* \) )/x + (ab(cd)ef) + 0: (ab(cd)ef) + 1: (ab(cd)ef) + 2: ef + +/^(?!a(*SKIP)b)/ + ac + 0: + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +No match + +/^(?=a(*THEN)b|ac)/ + ac + 0: + +/^(?=a(*PRUNE)b)/ + ab + 0: + ** Failers +No match + ac +No match + +/^(?=a(*ACCEPT)b)/ + ac + 0: + +/^(?(?!a(*SKIP)b))/ + ac + 0: + +/(?>a\Kb)/ + ab + 0: b + +/((?>a\Kb))/ + ab + 0: b + 1: ab + +/(a\Kb)/ + ab + 0: b + 1: ab + +/^a\Kcz|ac/ + ac + 0: ac + +/(?>a\Kbz|ab)/ + ab + 0: ab + +/^(?&t)(?(DEFINE)(?a\Kb))$/ + ab + 0: b + +/^([^()]|\((?1)*\))*$/ + a(b)c + 0: a(b)c + 1: c + a(b(c)d)e + 0: a(b(c)d)e + 1: e + +/(?P(?P0)(?P>L1)|(?P>L2))/ + 0 + 0: 0 + 1: 0 + 00 + 0: 00 + 1: 00 + 2: 0 + 0000 + 0: 0000 + 1: 0000 + 2: 0 + +/(?P(?P0)|(?P>L2)(?P>L1))/ + 0 + 0: 0 + 1: 0 + 2: 0 + 00 + 0: 0 + 1: 0 + 2: 0 + 0000 + 0: 0 + 1: 0 + 2: 0 + +/--- This one does fail, as expected, in Perl. It needs the complex item at the + end of the pattern. A single letter instead of (B|D) makes it not fail, + which I think is a Perl bug. --- / + +/A(*COMMIT)(B|D)/ + ACABX +No match + +/--- Check the use of names for failure ---/ + +/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K + ** Failers +No match + AC +No match, mark = A + CB +No match, mark = B + +/--- Force no study, otherwise mark is not seen. The studied version is in + test 2 because it isn't Perl-compatible. ---/ + +/(*MARK:A)(*SKIP:B)(C|X)/KSS + C + 0: C + 1: C +MK: A + D +No match, mark = A + +/^(A(*THEN:A)B|C(*THEN:B)D)/K + ** Failers +No match + CB +No match, mark = B + +/^(?:A(*THEN:A)B|C(*THEN:B)D)/K + CB +No match, mark = B + +/^(?>A(*THEN:A)B|C(*THEN:B)D)/K + CB +No match, mark = B + +/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note +that we have to have something complicated such as (B|Z) at the end because, +for Perl, a simple character somehow causes an unwanted optimization to mess +with the handling of backtracking verbs. ---/ + +/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Test skipping over a non-matching mark. ---/ + +/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Check shorthand for MARK ---/ + +/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK + AAAC + 0: AC + +/--- Don't loop! Force no study, otherwise mark is not seen. ---/ + +/(*:A)A+(*SKIP:A)(B|Z)/KSS + AAAC +No match, mark = A + +/--- This should succeed, as a non-existent skip name disables the skip ---/ + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK + AAAC + 0: AC + +/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK + AAAC + 0: AC +MK: B + +/--- COMMIT at the start of a pattern should act like an anchor. Again, +however, we need the complication for Perl. ---/ + +/(*COMMIT)(A|P)(B|P)(C|P)/ + ABCDEFG + 0: ABC + 1: A + 2: B + 3: C + ** Failers +No match + DEFGABC +No match + +/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ + +/(\w+)(?>b(*COMMIT))\w{2}/ + abbb + 0: abbb + 1: a + +/(\w+)b(*COMMIT)\w{2}/ + abbb +No match + +/--- Check opening parens in comment when seeking forward reference. ---/ + +/(?&t)(?#()(?(DEFINE)(?a))/ + bac + 0: a + +/--- COMMIT should override THEN ---/ + +/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ + yes +No match + +/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ + yes +No match + +/b?(*SKIP)c/ + bc + 0: bc + abc + 0: bc + +/(*SKIP)bc/ + a +No match + +/(*SKIP)b/ + a +No match + +/(?P(?P=abn)xxx|)+/ + xxx + 0: + 1: + +/(?i:([^b]))(?1)/ + aa + 0: aa + 1: a + aA + 0: aA + 1: a + ** Failers + 0: ** + 1: * + ab +No match + aB +No match + Ba +No match + ba +No match + +/^(?&t)*+(?(DEFINE)(?a))\w$/ + aaaaaaX + 0: aaaaaaX + ** Failers +No match + aaaaaa +No match + +/^(?&t)*(?(DEFINE)(?a))\w$/ + aaaaaaX + 0: aaaaaaX + aaaaaa + 0: aaaaaa + +/^(a)*+(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + YZ + 0: Y + 1: + 2: Y + ** Failers +No match + aaaa +No match + +/^(?:a)*+(\w)/ + aaaaX + 0: aaaaX + 1: X + YZ + 0: Y + 1: Y + ** Failers +No match + aaaa +No match + +/^(a)++(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaaa +No match + YZ +No match + +/^(?:a)++(\w)/ + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaaa +No match + YZ +No match + +/^(a)?+(\w)/ + aaaaX + 0: aa + 1: a + 2: a + YZ + 0: Y + 1: + 2: Y + +/^(?:a)?+(\w)/ + aaaaX + 0: aa + 1: a + YZ + 0: Y + 1: Y + +/^(a){2,}+(\w)/ + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaa +No match + YZ +No match + +/^(?:a){2,}+(\w)/ + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaa +No match + YZ +No match + +/(a|)*(?1)b/ + b + 0: b + 1: + ab + 0: ab + 1: + aab + 0: aab + 1: + +/(a)++(?1)b/ + ** Failers +No match + ab +No match + aab +No match + +/(a)*+(?1)b/ + ** Failers +No match + ab +No match + aab +No match + +/(?1)(?:(b)){0}/ + b + 0: b + +/(foo ( \( ((?:(?> [^()]+ )|(?2))*) \) ) )/x + foo(bar(baz)+baz(bop)) + 0: foo(bar(baz)+baz(bop)) + 1: foo(bar(baz)+baz(bop)) + 2: (bar(baz)+baz(bop)) + 3: bar(baz)+baz(bop) + +/(A (A|B(*ACCEPT)|C) D)(E)/x + AB + 0: AB + 1: AB + 2: B + +/\A.*?(?:a|b(*THEN)c)/ + ba + 0: ba + +/\A.*?(?:a|bc)/ + ba + 0: ba + +/\A.*?(a|b(*THEN)c)/ + ba + 0: ba + 1: a + +/\A.*?(a|bc)/ + ba + 0: ba + 1: a + +/\A.*?(?:a|b(*THEN)c)++/ + ba + 0: ba + +/\A.*?(?:a|bc)++/ + ba + 0: ba + +/\A.*?(a|b(*THEN)c)++/ + ba + 0: ba + 1: a + +/\A.*?(a|bc)++/ + ba + 0: ba + 1: a + +/\A.*?(?:a|b(*THEN)c|d)/ + ba + 0: ba + +/\A.*?(?:a|bc|d)/ + ba + 0: ba + +/(?:(b))++/ + beetle + 0: b + 1: b + +/(?(?=(a(*ACCEPT)z))a)/ + a + 0: a + 1: a + +/^(a)(?1)+ab/ + aaaab + 0: aaaab + 1: a + +/^(a)(?1)++ab/ + aaaab +No match + +/^(?=a(*:M))aZ/K + aZbc + 0: aZ +MK: M + +/^(?!(*:M)b)aZ/K + aZbc + 0: aZ + +/(?(DEFINE)(a))?b(?1)/ + backgammon + 0: ba + +/^\N+/ + abc\ndef + 0: abc + +/^\N{1,}/ + abc\ndef + 0: abc + +/(?(R)a+|(?R)b)/ + aaaabcde + 0: aaaab + +/(?(R)a+|((?R))b)/ + aaaabcde + 0: aaaab + 1: aaaa + +/((?(R)a+|(?1)b))/ + aaaabcde + 0: aaaab + 1: aaaab + +/((?(R1)a+|(?1)b))/ + aaaabcde + 0: aaaab + 1: aaaab + +/a(*:any +name)/K + abc + 0: a +MK: any \x0aname + +/(?>(?&t)c|(?&t))(?(DEFINE)(?a|b(*PRUNE)c))/ + a + 0: a + ba + 0: a + bba + 0: a + +/--- Checking revised (*THEN) handling ---/ + +/--- Capture ---/ + +/^.*? (a(*THEN)b) c/x + aabc +No match + +/^.*? (a(*THEN)b|(*F)) c/x + aabc + 0: aabc + 1: ab + +/^.*? ( (a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + 1: ab + 2: ab + +/^.*? ( (a(*THEN)b) ) c/x + aabc +No match + +/--- Non-capture ---/ + +/^.*? (?:a(*THEN)b) c/x + aabc +No match + +/^.*? (?:a(*THEN)b|(*F)) c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b) ) c/x + aabc +No match + +/--- Atomic ---/ + +/^.*? (?>a(*THEN)b) c/x + aabc +No match + +/^.*? (?>a(*THEN)b|(*F)) c/x + aabc + 0: aabc + +/^.*? (?> (?>a(*THEN)b) | (*F) ) c/x + aabc + 0: aabc + +/^.*? (?> (?>a(*THEN)b) ) c/x + aabc +No match + +/--- Possessive capture ---/ + +/^.*? (a(*THEN)b)++ c/x + aabc +No match + +/^.*? (a(*THEN)b|(*F))++ c/x + aabc + 0: aabc + 1: ab + +/^.*? ( (a(*THEN)b)++ | (*F) )++ c/x + aabc + 0: aabc + 1: ab + 2: ab + +/^.*? ( (a(*THEN)b)++ )++ c/x + aabc +No match + +/--- Possessive non-capture ---/ + +/^.*? (?:a(*THEN)b)++ c/x + aabc +No match + +/^.*? (?:a(*THEN)b|(*F))++ c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b)++ | (*F) )++ c/x + aabc + 0: aabc + +/^.*? (?: (?:a(*THEN)b)++ )++ c/x + aabc +No match + +/--- Condition assertion ---/ + +/^(?(?=a(*THEN)b)ab|ac)/ + ac + 0: ac + +/--- Condition ---/ + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba +No match + +/^.*?(?:(?(?=a)a|b(*THEN)c)|d)/ + ba + 0: ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac +No match + +/--- Assertion ---/ + +/^.*(?=a(*THEN)b)/ + aabc + 0: a + +/------------------------------/ + +/(?>a(*:m))/imsxSK + a + 0: a +MK: m + +/(?>(a)(*:m))/imsxSK + a + 0: a + 1: a +MK: m + +/(?<=a(*ACCEPT)b)c/ + xacd + 0: c + +/(?<=(a(*ACCEPT)b))c/ + xacd + 0: c + 1: a + +/(?<=(a(*COMMIT)b))c/ + xabcd + 0: c + 1: ab + ** Failers +No match + xacd +No match + +/(? + 2: + +/(another)?(\1+)test/ + hello world test +No match + +/(a(*COMMIT)b){0}a(?1)|aac/ + aac + 0: aac + +/(?!a(*COMMIT)b)ac|cd/ + ac + 0: ac + +/((?:a?)*)*c/ + aac + 0: aac + 1: + +/((?>a?)*)*c/ + aac + 0: aac + 1: + /-- End of testinput1 --/ diff -Nru pcre3-8.12/testdata/testoutput10 pcre3-8.31/testdata/testoutput10 --- pcre3-8.12/testdata/testoutput10 2010-10-10 15:37:09.000000000 +0000 +++ pcre3-8.31/testdata/testoutput10 2012-06-01 18:32:41.000000000 +0000 @@ -1,739 +1,2103 @@ -/-- These are a few representative patterns whose lengths and offsets are to be -shown when the link size is 2. This is just a doublecheck test to ensure the -sizes don't go horribly wrong when something is changed. The pattern contents -are all themselves checked in other tests. Unicode, including property support, -is required for these tests. --/ - -/((?i)b)/BM -Memory allocation (code space): 21 ------------------------------------------------------------------- - 0 17 Bra - 3 9 CBra 1 - 8 01 Opt - 10 NC b - 12 9 Ket - 15 00 Opt - 17 17 Ket - 20 End ------------------------------------------------------------------- - -/(?s)(.*X|^B)/BM -Memory allocation (code space): 25 ------------------------------------------------------------------- - 0 21 Bra - 3 9 CBra 1 - 8 AllAny* - 10 X - 12 6 Alt - 15 ^ - 16 B - 18 15 Ket - 21 21 Ket - 24 End ------------------------------------------------------------------- - -/(?s:.*X|^B)/BM -Memory allocation (code space): 29 ------------------------------------------------------------------- - 0 25 Bra - 3 9 Bra - 6 04 Opt - 8 AllAny* - 10 X - 12 8 Alt - 15 04 Opt - 17 ^ - 18 B - 20 17 Ket - 23 00 Opt - 25 25 Ket - 28 End ------------------------------------------------------------------- - -/^[[:alnum:]]/BM -Memory allocation (code space): 41 ------------------------------------------------------------------- - 0 37 Bra - 3 ^ - 4 [0-9A-Za-z] - 37 37 Ket - 40 End ------------------------------------------------------------------- - -/#/IxMD -Memory allocation (code space): 7 ------------------------------------------------------------------- - 0 3 Bra - 3 3 Ket - 6 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: extended -No first char -No need char - -/a#/IxMD -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 a - 5 5 Ket - 8 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: extended -First char = 'a' -No need char - -/x?+/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 x?+ - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/x++/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 x++ - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/x{1,3}+/BM -Memory allocation (code space): 19 ------------------------------------------------------------------- - 0 15 Bra - 3 9 Once - 6 x - 8 x{0,2} - 12 9 Ket - 15 15 Ket - 18 End ------------------------------------------------------------------- - -/(x)*+/BM -Memory allocation (code space): 24 ------------------------------------------------------------------- - 0 20 Bra - 3 14 Once - 6 Brazero - 7 7 CBra 1 - 12 x - 14 7 KetRmax - 17 14 Ket - 20 20 Ket - 23 End ------------------------------------------------------------------- - -/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM -Memory allocation (code space): 120 ------------------------------------------------------------------- - 0 116 Bra - 3 ^ - 4 109 CBra 1 - 9 7 CBra 2 - 14 a+ - 16 7 Ket - 19 39 CBra 3 - 24 [ab]+? - 58 39 Ket - 61 39 CBra 4 - 66 [bc]+ -100 39 Ket -103 7 CBra 5 -108 \w* -110 7 Ket -113 109 Ket -116 116 Ket -119 End ------------------------------------------------------------------- - -|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM -Memory allocation (code space): 826 ------------------------------------------------------------------- - 0 822 Bra - 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X -821 \b -822 822 Ket -825 End ------------------------------------------------------------------- - -|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM -Memory allocation (code space): 816 ------------------------------------------------------------------- - 0 812 Bra - 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X -811 \b -812 812 Ket -815 End ------------------------------------------------------------------- - -/(a(?1)b)/BM -Memory allocation (code space): 28 ------------------------------------------------------------------- - 0 24 Bra - 3 18 CBra 1 - 8 a - 10 6 Once - 13 3 Recurse - 16 6 Ket - 19 b - 21 18 Ket - 24 24 Ket - 27 End ------------------------------------------------------------------- - -/(a(?1)+b)/BM -Memory allocation (code space): 28 ------------------------------------------------------------------- - 0 24 Bra - 3 18 CBra 1 - 8 a - 10 6 Once - 13 3 Recurse - 16 6 KetRmax - 19 b - 21 18 Ket - 24 24 Ket - 27 End ------------------------------------------------------------------- - -/a(?Pb|c)d(?Pe)/BM -Memory allocation (code space): 42 ------------------------------------------------------------------- - 0 32 Bra - 3 a - 5 7 CBra 1 - 10 b - 12 5 Alt - 15 c - 17 12 Ket - 20 d - 22 7 CBra 2 - 27 e - 29 7 Ket - 32 32 Ket - 35 End ------------------------------------------------------------------- - -/(?:a(?Pc(?Pd)))(?Pa)/BM -Memory allocation (code space): 54 ------------------------------------------------------------------- - 0 41 Bra - 3 25 Bra - 6 a - 8 17 CBra 1 - 13 c - 15 7 CBra 2 - 20 d - 22 7 Ket - 25 17 Ket - 28 25 Ket - 31 7 CBra 3 - 36 a - 38 7 Ket - 41 41 Ket - 44 End ------------------------------------------------------------------- - -/(?Pa)...(?P=a)bbb(?P>a)d/BM -Memory allocation (code space): 43 ------------------------------------------------------------------- - 0 36 Bra - 3 7 CBra 1 - 8 a - 10 7 Ket - 13 Any - 14 Any - 15 Any - 16 \1 - 19 bbb - 25 6 Once - 28 3 Recurse - 31 6 Ket - 34 d - 36 36 Ket - 39 End ------------------------------------------------------------------- - -/abc(?C255)de(?C)f/BM -Memory allocation (code space): 31 ------------------------------------------------------------------- - 0 27 Bra - 3 abc - 9 Callout 255 10 1 - 15 de - 19 Callout 0 16 1 - 25 f - 27 27 Ket - 30 End ------------------------------------------------------------------- - -/abcde/CBM -Memory allocation (code space): 53 ------------------------------------------------------------------- - 0 49 Bra - 3 Callout 255 0 1 - 9 a - 11 Callout 255 1 1 - 17 b - 19 Callout 255 2 1 - 25 c - 27 Callout 255 3 1 - 33 d - 35 Callout 255 4 1 - 41 e - 43 Callout 255 5 0 - 49 49 Ket - 52 End ------------------------------------------------------------------- - -/\x{100}/8BM -Memory allocation (code space): 10 ------------------------------------------------------------------- - 0 6 Bra - 3 \x{100} - 6 6 Ket - 9 End ------------------------------------------------------------------- - -/\x{1000}/8BM -Memory allocation (code space): 11 ------------------------------------------------------------------- - 0 7 Bra - 3 \x{1000} - 7 7 Ket - 10 End ------------------------------------------------------------------- - -/\x{10000}/8BM -Memory allocation (code space): 12 ------------------------------------------------------------------- - 0 8 Bra - 3 \x{10000} - 8 8 Ket - 11 End ------------------------------------------------------------------- - -/\x{100000}/8BM -Memory allocation (code space): 12 ------------------------------------------------------------------- - 0 8 Bra - 3 \x{100000} - 8 8 Ket - 11 End ------------------------------------------------------------------- - -/\x{1000000}/8BM -Memory allocation (code space): 13 ------------------------------------------------------------------- - 0 9 Bra - 3 \x{1000000} - 9 9 Ket - 12 End ------------------------------------------------------------------- - -/\x{4000000}/8BM -Memory allocation (code space): 14 ------------------------------------------------------------------- - 0 10 Bra - 3 \x{4000000} - 10 10 Ket - 13 End ------------------------------------------------------------------- - -/\x{7fffFFFF}/8BM -Memory allocation (code space): 14 ------------------------------------------------------------------- - 0 10 Bra - 3 \x{7fffffff} - 10 10 Ket - 13 End ------------------------------------------------------------------- - -/[\x{ff}]/8BM -Memory allocation (code space): 10 ------------------------------------------------------------------- - 0 6 Bra - 3 \x{ff} - 6 6 Ket - 9 End ------------------------------------------------------------------- - -/[\x{100}]/8BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\x{100}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/\x80/8BM -Memory allocation (code space): 10 ------------------------------------------------------------------- - 0 6 Bra - 3 \x{80} - 6 6 Ket - 9 End ------------------------------------------------------------------- - -/\xff/8BM -Memory allocation (code space): 10 ------------------------------------------------------------------- - 0 6 Bra - 3 \x{ff} - 6 6 Ket - 9 End ------------------------------------------------------------------- - -/\x{0041}\x{2262}\x{0391}\x{002e}/D8M -Memory allocation (code space): 18 ------------------------------------------------------------------- - 0 14 Bra - 3 A\x{2262}\x{391}. - 14 14 Ket - 17 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'A' -Need char = '.' - -/\x{D55c}\x{ad6d}\x{C5B4}/D8M -Memory allocation (code space): 19 ------------------------------------------------------------------- - 0 15 Bra - 3 \x{d55c}\x{ad6d}\x{c5b4} - 15 15 Ket - 18 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 237 -Need char = 180 - -/\x{65e5}\x{672c}\x{8a9e}/D8M -Memory allocation (code space): 19 ------------------------------------------------------------------- - 0 15 Bra - 3 \x{65e5}\x{672c}\x{8a9e} - 15 15 Ket - 18 End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 230 -Need char = 158 - -/[\x{100}]/8BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\x{100}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[Z\x{100}]/8BM -Memory allocation (code space): 47 ------------------------------------------------------------------- - 0 43 Bra - 3 [Z\x{100}] - 43 43 Ket - 46 End ------------------------------------------------------------------- - -/^[\x{100}\E-\Q\E\x{150}]/B8M -Memory allocation (code space): 18 ------------------------------------------------------------------- - 0 14 Bra - 3 ^ - 4 [\x{100}-\x{150}] - 14 14 Ket - 17 End ------------------------------------------------------------------- - -/^[\QÄ€\E-\QÅ\E]/B8M -Memory allocation (code space): 18 ------------------------------------------------------------------- - 0 14 Bra - 3 ^ - 4 [\x{100}-\x{150}] - 14 14 Ket - 17 End ------------------------------------------------------------------- - -/^[\QÄ€\E-\QÅ\E/B8M -Failed: missing terminating ] for character class at offset 15 - -/[\p{L}]/BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\p{L}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[\p{^L}]/BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\P{L}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[\P{L}]/BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\P{L}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[\P{^L}]/BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\p{L}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[abc\p{L}\x{0660}]/8BM -Memory allocation (code space): 50 ------------------------------------------------------------------- - 0 46 Bra - 3 [a-c\p{L}\x{660}] - 46 46 Ket - 49 End ------------------------------------------------------------------- - -/[\p{Nd}]/8BM -Memory allocation (code space): 15 ------------------------------------------------------------------- - 0 11 Bra - 3 [\p{Nd}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[\p{Nd}+-]+/8BM -Memory allocation (code space): 48 ------------------------------------------------------------------- - 0 44 Bra - 3 [+\-\p{Nd}]+ - 44 44 Ket - 47 End ------------------------------------------------------------------- - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM -Memory allocation (code space): 25 ------------------------------------------------------------------- - 0 21 Bra - 3 NC A\x{391}\x{10427}\x{ff3a}\x{1fb0} - 21 21 Ket - 24 End ------------------------------------------------------------------- - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM -Memory allocation (code space): 25 ------------------------------------------------------------------- - 0 21 Bra - 3 A\x{391}\x{10427}\x{ff3a}\x{1fb0} - 21 21 Ket - 24 End ------------------------------------------------------------------- - -/[\x{105}-\x{109}]/8iBM -Memory allocation (code space): 17 ------------------------------------------------------------------- - 0 13 Bra - 3 [\x{104}-\x{109}] - 13 13 Ket - 16 End ------------------------------------------------------------------- - -/( ( (?(1)0|) )* )/xBM -Memory allocation (code space): 38 ------------------------------------------------------------------- - 0 34 Bra - 3 28 CBra 1 - 8 Brazero - 9 19 SCBra 2 - 14 8 Cond - 17 1 Cond ref - 20 0 - 22 3 Alt - 25 11 Ket - 28 19 KetRmax - 31 28 Ket - 34 34 Ket - 37 End ------------------------------------------------------------------- - -/( (?(1)0|)* )/xBM -Memory allocation (code space): 30 ------------------------------------------------------------------- - 0 26 Bra - 3 20 CBra 1 - 8 Brazero - 9 8 SCond - 12 1 Cond ref - 15 0 - 17 3 Alt - 20 11 KetRmax - 23 20 Ket - 26 26 Ket - 29 End ------------------------------------------------------------------- - -/[a]/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 a - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[a]/8BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 a - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[\xaa]/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 \xaa - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[\xaa]/8BM -Memory allocation (code space): 10 ------------------------------------------------------------------- - 0 6 Bra - 3 \x{aa} - 6 6 Ket - 9 End ------------------------------------------------------------------- - -/[^a]/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 [^a] - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[^a]/8BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 [^a] - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[^\xaa]/BM -Memory allocation (code space): 9 ------------------------------------------------------------------- - 0 5 Bra - 3 [^\xaa] - 5 5 Ket - 8 End ------------------------------------------------------------------- - -/[^\xaa]/8BM -Memory allocation (code space): 40 ------------------------------------------------------------------- - 0 36 Bra - 3 [\x00-\xa9\xab-\xff] (neg) - 36 36 Ket - 39 End ------------------------------------------------------------------- - -/[^\d]/8WB ------------------------------------------------------------------- - 0 11 Bra - 3 [^\p{Nd}] - 11 11 Ket - 14 End ------------------------------------------------------------------- - -/[[:^alpha:][:^cntrl:]]+/8WB ------------------------------------------------------------------- - 0 44 Bra - 3 [ -~\x80-\xff\P{L}]+ - 44 44 Ket - 47 End ------------------------------------------------------------------- - -/[[:^cntrl:][:^alpha:]]+/8WB ------------------------------------------------------------------- - 0 44 Bra - 3 [ -~\x80-\xff\P{L}]+ - 44 44 Ket - 47 End ------------------------------------------------------------------- - -/[[:alpha:]]+/8WB ------------------------------------------------------------------- - 0 12 Bra - 3 [\p{L}]+ - 12 12 Ket - 15 End ------------------------------------------------------------------- - -/[[:^alpha:]\S]+/8WB ------------------------------------------------------------------- - 0 15 Bra - 3 [\P{L}\P{Xsp}]+ - 15 15 Ket - 18 End ------------------------------------------------------------------- - -/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B ------------------------------------------------------------------- - 0 79 Bra - 3 abc - 9 7 CBra 1 - 14 d - 16 5 Alt - 19 e - 21 12 Ket - 24 *THEN 24 - 27 x - 29 16 CBra 2 - 34 123 - 40 *THEN 11 - 43 4 - 45 31 Alt - 48 567 - 54 7 CBra 3 - 59 b - 61 5 Alt - 64 q - 66 12 Ket - 69 *THEN 24 - 72 xx - 76 47 Ket - 79 79 Ket - 82 End ------------------------------------------------------------------- +/-- This set of tests check Unicode property support with the DFA matching + functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest + when running it. --/ + +/\pL\P{Nd}/8 + AB + 0: AB + *** Failers + 0: Fa + A0 +No match + 00 +No match + +/\X./8 + AB + 0: AB + A\x{300}BC + 0: A\x{300}B + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302}B + *** Failers + 0: ** + \x{300} +No match + +/\X\X/8 + ABC + 0: AB + A\x{300}B\x{300}\x{301}C + 0: A\x{300}B\x{300}\x{301} + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302}B + *** Failers + 0: ** + \x{300} +No match + +/^\pL+/8 + abcd + 0: abcd + 1: abc + 2: ab + 3: a + a + 0: a + *** Failers +No match + +/^\PL+/8 + 1234 + 0: 1234 + 1: 123 + 2: 12 + 3: 1 + = + 0: = + *** Failers + 0: *** + 1: *** + 2: ** + 3: * + abcd +No match + +/^\X+/8 + abcdA\x{300}\x{301}\x{302} + 0: abcdA\x{300}\x{301}\x{302} + 1: abcd + 2: abc + 3: ab + 4: a + A\x{300}\x{301}\x{302} + 0: A\x{300}\x{301}\x{302} + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} + 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} + 1: A\x{300}\x{301}\x{302} + a + 0: a + *** Failers + 0: *** Failers + 1: *** Failer + 2: *** Faile + 3: *** Fail + 4: *** Fai + 5: *** Fa + 6: *** F + 7: *** + 8: *** + 9: ** +10: * + \x{300}\x{301}\x{302} +No match + +/\X?abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}abc + \x{300}abc + 0: abc + *** Failers +No match + +/^\X?abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + *** Failers +No match + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz +No match + \x{300}abc +No match + +/\X*abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc + \x{300}abc + 0: abc + *** Failers +No match + +/^\X*abc/8 + abc + 0: abc + A\x{300}abc + 0: A\x{300}abc + A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc + *** Failers +No match + \x{300}abc +No match + +/^\pL?=./8 + A=b + 0: A=b + =c + 0: =c + *** Failers +No match + 1=2 +No match + AAAA=b +No match + +/^\pL*=./8 + AAAA=b + 0: AAAA=b + =c + 0: =c + *** Failers +No match + 1=2 +No match + +/^\X{2,3}X/8 + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + *** Failers +No match + X +No match + A\x{300}\x{301}\x{302}X +No match + A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X +No match + +/^\pC\pL\pM\pN\pP\pS\pZ\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + ** Failers +No match + \x{0b} +No match + +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 3: > \x{09}\x{0a}\x{0c}\x{0d} + 4: > \x{09}\x{0a}\x{0c} + 5: > \x{09}\x{0a} + 6: > \x{09} + 7: > + +/^>\p{Xsp}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 3: > \x{09}\x{0a}\x{0c}\x{0d} + 4: > \x{09}\x{0a}\x{0c} + 5: > \x{09}\x{0a} + 6: > \x{09} + 7: > + 8: > + +/^>\p{Xsp}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 3: > \x{09}\x{0a}\x{0c}\x{0d} + 4: > \x{09}\x{0a}\x{0c} + 5: > \x{09}\x{0a} + 6: > \x{09} + +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 3: > \x{09}\x{0a}\x{0c}\x{0d} + 4: > \x{09}\x{0a}\x{0c} + 5: > \x{09}\x{0a} + 6: > \x{09} + 7: > + +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} + ** Failers +No match + \x{0b} +No match + +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > + +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680}\x{2028}\x{0b} + 1: >\x{1680}\x{2028} + 2: >\x{1680} + +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > + 9: > + +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} + 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} + 4: > \x{09}\x{0a}\x{0c}\x{0d} + 5: > \x{09}\x{0a}\x{0c} + 6: > \x{09}\x{0a} + 7: > \x{09} + 8: > + +/^\p{Xwd}/8 + ABCD + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers +No match + [] +No match + +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} + 2: ABCD1234\x{6ca}\x{a6c} + 3: ABCD1234\x{6ca} + 4: ABCD1234 + 5: ABCD123 + 6: ABCD12 + 7: ABCD1 + 8: ABCD + 9: ABC +10: AB +11: A + +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} + 2: ABCD1234\x{6ca}\x{a6c} + 3: ABCD1234\x{6ca} + 4: ABCD1234 + 5: ABCD123 + 6: ABCD12 + 7: ABCD1 + 8: ABCD + 9: ABC +10: AB +11: A +12: + +/^\p{Xwd}{2,9}/8 + A_12\x{6ca}\x{a6c}\x{10a7} + 0: A_12\x{6ca}\x{a6c}\x{10a7} + 1: A_12\x{6ca}\x{a6c} + 2: A_12\x{6ca} + 3: A_12 + 4: A_1 + 5: A_ + +/^[\p{Xwd}]/8 + ABCD1234_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ + ** Failers +No match + [] +No match + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} + 2: ABCD1234\x{6ca}\x{a6c} + 3: ABCD1234\x{6ca} + 4: ABCD1234 + 5: ABCD123 + 6: ABCD12 + 7: ABCD1 + 8: ABCD + 9: ABC +10: AB +11: A + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + 0: abc + \x{37e}abc\x{376} + 0: abc + \x{37e}\x{376}\x{371}\x{393}\x{394} + 0: \x{376}\x{371}\x{393} + !\x{c0}++\x{c1}\x{c2} + 0: ++\x{c1} + !\x{c0}+++++ + 0: \x{c0}++ + +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ + +/\b...\B/8 + abc_ + 0: abc + ** Failers + 0: Fai + \x{37e}abc\x{376} +No match + \x{37e}\x{376}\x{371}\x{393}\x{394} +No match + !\x{c0}++\x{c1}\x{c2} +No match + !\x{c0}+++++ +No match + +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ + +/\b...\B/W + abc_ + 0: abc + !\x{c0}++\x{c1}\x{c2} + 0: ++\xc1 + !\x{c0}+++++ + 0: \xc0++ + +/-- Caseless single negated characters > 127 need UCP support --/ + +/[^\x{100}]/8i + \x{100}\x{101}X + 0: X + +/[^\x{100}]+/8i + \x{100}\x{101}XX + 0: XX + 1: X + +/^\X/8 + A\P + 0: A + A\P\P +Partial match: A + A\x{300}\x{301}\P + 0: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{301}\P + 0: A\x{301} + A\x{301}\P\P +Partial match: A\x{301} + +/^\X{2,3}/8 + A\P +Partial match: A + A\P\P +Partial match: A + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} + +/^\X{2}/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} + +/^\X+/8 + AA\P + 0: AA + 1: A + AA\P\P +Partial match: AA + +/^\X+?Z/8 + AA\P +Partial match: AA + AA\P\P +Partial match: AA -/-- End of testinput10 --/ +/-- End of testinput10 --/ diff -Nru pcre3-8.12/testdata/testoutput11 pcre3-8.31/testdata/testoutput11 --- pcre3-8.12/testdata/testoutput11 2010-11-23 15:30:50.000000000 +0000 +++ pcre3-8.31/testdata/testoutput11 1970-01-01 00:00:00.000000000 +0000 @@ -1,978 +0,0 @@ -/-- These tests are for the Perl >= 5.10 features that PCRE supports. --/ - -/\H\h\V\v/ - X X\x0a - 0: X X\x0a - X\x09X\x0b - 0: X\x09X\x0b - ** Failers -No match - \xa0 X\x0a -No match - -/\H*\h+\V?\v{3,4}/ - \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a - 0: \x09 \xa0X\x0a\x0b\x0c\x0d - \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a - 0: \x09 \xa0\x0a\x0b\x0c\x0d - \x09\x20\xa0\x0a\x0b\x0c - 0: \x09 \xa0\x0a\x0b\x0c - ** Failers -No match - \x09\x20\xa0\x0a\x0b -No match - -/\H{3,4}/ - XY ABCDE - 0: ABCD - XY PQR ST - 0: PQR - -/.\h{3,4}./ - XY AB PQRS - 0: B P - -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - 0: XNNNYZ - > X NYQZ - 0: X NYQZ - ** Failers -No match - >XYZ -No match - > X NY Z -No match - -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - 0: XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - -/(foo)\Kbar/ - foobar - 0: bar - 1: foo - -/(foo)(\Kbar|baz)/ - foobar - 0: bar - 1: foo - 2: bar - foobaz - 0: foobaz - 1: foo - 2: baz - -/(foo\Kbar)baz/ - foobarbaz - 0: barbaz - 1: foobar - -/abc\K|def\K/g+ - Xabcdefghi - 0: - 0+ defghi - 0: - 0+ ghi - -/ab\Kc|de\Kf/g+ - Xabcdefghi - 0: c - 0+ defghi - 0: f - 0+ ghi - -/(?=C)/g+ - ABCDECBA - 0: - 0+ CDECBA - 0: - 0+ CBA - -/^abc\K/+ - abcdef - 0: - 0+ def - ** Failers -No match - defabcxyz -No match - -/^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z/ - ababababbbabZXXXX - 0: ababababbbabZ - 1: ab - 2: b - -/(?tom|bon)-\g{A}/ - tom-tom - 0: tom-tom - 1: tom - bon-bon - 0: bon-bon - 1: bon - -/(^(a|b\g{-1}))/ - bacxxx -No match - -/(?|(abc)|(xyz))\1/ - abcabc - 0: abcabc - 1: abc - xyzxyz - 0: xyzxyz - 1: xyz - ** Failers -No match - abcxyz -No match - xyzabc -No match - -/(?|(abc)|(xyz))(?1)/ - abcabc - 0: abcabc - 1: abc - xyzabc - 0: xyzabc - 1: xyz - ** Failers -No match - xyzxyz -No match - -/^X(?5)(a)(?|(b)|(q))(c)(d)(Y)/ - XYabcdY - 0: XYabcdY - 1: a - 2: b - 3: c - 4: d - 5: Y - -/^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)/ - XYabcdY - 0: XYabcdY - 1: a - 2: b - 3: - 4: - 5: c - 6: d - 7: Y - -/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ - XYabcdY - 0: XYabcdY - 1: a - 2: b - 3: - 4: - 5: c - 6: d - 7: Y - -/(?'abc'\w+):\k{2}/ - a:aaxyz - 0: a:aa - 1: a - ab:ababxyz - 0: ab:abab - 1: ab - ** Failers -No match - a:axyz -No match - ab:abxyz -No match - -/(?'abc'\w+):\g{abc}{2}/ - a:aaxyz - 0: a:aa - 1: a - ab:ababxyz - 0: ab:abab - 1: ab - ** Failers -No match - a:axyz -No match - ab:abxyz -No match - -/^(?a)? (?()b|c) (?('ab')d|e)/x - abd - 0: abd - 1: a - ce - 0: ce - -/^(a.)\g-1Z/ - aXaXZ - 0: aXaXZ - 1: aX - -/^(a.)\g{-1}Z/ - aXaXZ - 0: aXaXZ - 1: aX - -/^(?(DEFINE) (? a) (? b) ) (?&A) (?&B) /x - abcd - 0: ab - -/(?(?&NAME_PAT))\s+(?(?&ADDRESS_PAT)) - (?(DEFINE) - (?[a-z]+) - (?\d+) - )/x - metcalfe 33 - 0: metcalfe 33 - 1: metcalfe - 2: 33 - -/(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))\b(?&byte)(\.(?&byte)){3}/ - 1.2.3.4 - 0: 1.2.3.4 - 1: - 2: .4 - 131.111.10.206 - 0: 131.111.10.206 - 1: - 2: .206 - 10.0.0.0 - 0: 10.0.0.0 - 1: - 2: .0 - ** Failers -No match - 10.6 -No match - 455.3.4.5 -No match - -/\b(?&byte)(\.(?&byte)){3}(?(DEFINE)(?2[0-4]\d|25[0-5]|1\d\d|[1-9]?\d))/ - 1.2.3.4 - 0: 1.2.3.4 - 1: .4 - 131.111.10.206 - 0: 131.111.10.206 - 1: .206 - 10.0.0.0 - 0: 10.0.0.0 - 1: .0 - ** Failers -No match - 10.6 -No match - 455.3.4.5 -No match - -/^(\w++|\s++)*$/ - now is the time for all good men to come to the aid of the party - 0: now is the time for all good men to come to the aid of the party - 1: party - *** Failers -No match - this is not a line with only words and spaces! -No match - -/(\d++)(\w)/ - 12345a - 0: 12345a - 1: 12345 - 2: a - *** Failers -No match - 12345+ -No match - -/a++b/ - aaab - 0: aaab - -/(a++b)/ - aaab - 0: aaab - 1: aaab - -/(a++)b/ - aaab - 0: aaab - 1: aaa - -/([^()]++|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: x - -/\(([^()]++|\([^()]+\))+\)/ - (abc) - 0: (abc) - 1: abc - (abc(def)xyz) - 0: (abc(def)xyz) - 1: xyz - *** Failers -No match - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/^([^()]|\((?1)*\))*$/ - abc - 0: abc - 1: c - a(b)c - 0: a(b)c - 1: c - a(b(c))d - 0: a(b(c))d - 1: d - *** Failers) -No match - a(b(c)d -No match - -/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) - 2: - 3: Satanoscillatemymetallicsonatas - 4: S - AmanaplanacanalPanama - 0: AmanaplanacanalPanama - 1: - 2: - 3: AmanaplanacanalPanama - 4: A - AblewasIereIsawElba - 0: AblewasIereIsawElba - 1: - 2: - 3: AblewasIereIsawElba - 4: A - *** Failers -No match - Thequickbrownfox -No match - -/^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ - 12 - 0: 12 - 1: 12 - (((2+2)*-3)-7) - 0: (((2+2)*-3)-7) - 1: (((2+2)*-3)-7) - 2: - - -12 - 0: -12 - 1: -12 - *** Failers -No match - ((2+2)*-3)-7) -No match - -/^(x(y|(?1){2})z)/ - xyz - 0: xyz - 1: xyz - 2: y - xxyzxyzz - 0: xxyzxyzz - 1: xxyzxyzz - 2: xyzxyz - *** Failers -No match - xxyzz -No match - xxyzxyzxyzz -No match - -/((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x - <> - 0: <> - 1: <> - 2: <> - - 0: - 1: - 2: - hij> - 0: hij> - 1: hij> - 2: hij> - hij> - 0: - 1: - 2: - def> - 0: def> - 1: def> - 2: def> - - 0: <> - 1: <> - 2: <> - *** Failers -No match - - 2: - 3: Satan, oscillate my metallic sonatas - 4: S - A man, a plan, a canal: Panama! - 0: A man, a plan, a canal: Panama! - 1: - 2: - 3: A man, a plan, a canal: Panama - 4: A - Able was I ere I saw Elba. - 0: Able was I ere I saw Elba. - 1: - 2: - 3: Able was I ere I saw Elba - 4: A - *** Failers -No match - The quick brown fox -No match - -/^((.)(?1)\2|.)$/ - a - 0: a - 1: a - aba - 0: aba - 1: aba - 2: a - aabaa - 0: aabaa - 1: aabaa - 2: a - abcdcba - 0: abcdcba - 1: abcdcba - 2: a - pqaabaaqp - 0: pqaabaaqp - 1: pqaabaaqp - 2: p - ablewasiereisawelba - 0: ablewasiereisawelba - 1: ablewasiereisawelba - 2: a - rhubarb -No match - the quick brown fox -No match - -/(a)(?<=b(?1))/ - baz - 0: a - 1: a - ** Failers -No match - caz -No match - -/(?<=b(?1))(a)/ - zbaaz - 0: a - 1: a - ** Failers -No match - aaa -No match - -/(?a)(?<=b(?&X))/ - baz - 0: a - 1: a - -/^(?|(abc)|(def))\1/ - abcabc - 0: abcabc - 1: abc - defdef - 0: defdef - 1: def - ** Failers -No match - abcdef -No match - defabc -No match - -/^(?|(abc)|(def))(?1)/ - abcabc - 0: abcabc - 1: abc - defabc - 0: defabc - 1: def - ** Failers -No match - defdef -No match - abcdef -No match - -/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?('quote')[a-z]+|[0-9]+)/xJ - a\"aaaaa - 0: a"aaaaa - 1: " - 2: - 3: " - b\"aaaaa - 0: b"aaaaa - 1: - 2: - 3: - 4: " - 5: - 6: " - ** Failers -No match - b\"11111 -No match - -/(?:(?1)|B)(A(*F)|C)/ - ABCD - 0: BC - 1: C - CCD - 0: CC - 1: C - ** Failers -No match - CAD -No match - -/^(?:(?1)|B)(A(*F)|C)/ - CCD - 0: CC - 1: C - BCD - 0: BC - 1: C - ** Failers -No match - ABCD -No match - CAD -No match - BAD -No match - -/(?:(?1)|B)(A(*ACCEPT)XX|C)D/ - AAD - 0: AA - 1: A - ACD - 0: ACD - 1: C - BAD - 0: BA - 1: A - BCD - 0: BCD - 1: C - BAX - 0: BA - 1: A - ** Failers -No match - ACX -No match - ABC -No match - -/(?(DEFINE)(A))B(?1)C/ - BAC - 0: BAC - -/(?(DEFINE)((A)\2))B(?1)C/ - BAAC - 0: BAAC - -/(? \( ( [^()]++ | (?&pn) )* \) )/x - (ab(cd)ef) - 0: (ab(cd)ef) - 1: (ab(cd)ef) - 2: ef - -/^(?!a(*SKIP)b)/ - ac - 0: - -/^(?=a(*SKIP)b|ac)/ - ** Failers -No match - ac -No match - -/^(?=a(*THEN)b|ac)/ - ac - 0: - -/^(?=a(*PRUNE)b)/ - ab - 0: - ** Failers -No match - ac -No match - -/^(?=a(*ACCEPT)b)/ - ac - 0: - -/^(?(?!a(*SKIP)b))/ - ac - 0: - -/(?>a\Kb)/ - ab - 0: b - -/((?>a\Kb))/ - ab - 0: b - 1: ab - -/(a\Kb)/ - ab - 0: b - 1: ab - -/^a\Kcz|ac/ - ac - 0: ac - -/(?>a\Kbz|ab)/ - ab - 0: ab - -/^(?&t)(?(DEFINE)(?a\Kb))$/ - ab - 0: b - -/^([^()]|\((?1)*\))*$/ - a(b)c - 0: a(b)c - 1: c - a(b(c)d)e - 0: a(b(c)d)e - 1: e - -/(?P(?P0)(?P>L1)|(?P>L2))/ - 0 - 0: 0 - 1: 0 - 00 - 0: 00 - 1: 00 - 2: 0 - 0000 - 0: 0000 - 1: 0000 - 2: 0 - -/(?P(?P0)|(?P>L2)(?P>L1))/ - 0 - 0: 0 - 1: 0 - 2: 0 - 00 - 0: 0 - 1: 0 - 2: 0 - 0000 - 0: 0 - 1: 0 - 2: 0 - -/--- This one does fail, as expected, in Perl. It needs the complex item at the - end of the pattern. A single letter instead of (B|D) makes it not fail, - which I think is a Perl bug. --- / - -/A(*COMMIT)(B|D)/ - ACABX -No match - -/--- Check the use of names for failure ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - ** Failers -No match - AC -No match, mark = A - CB -No match, mark = B - -/(*MARK:A)(*SKIP:B)(C|X)/K - C - 0: C - 1: C -MK: A - D -No match, mark = A - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - ** Failers -No match - CB -No match, mark = B - -/^(?:A(*THEN:A)B|C(*THEN:B)D)/K - CB -No match, mark = B - -/^(?>A(*THEN:A)B|C(*THEN:B)D)/K - CB -No match, mark = B - -/--- This should succeed, as the skip causes bump to offset 1 (the mark). Note -that we have to have something complicated such as (B|Z) at the end because, -for Perl, a simple character somehow causes an unwanted optimization to mess -with the handling of backtracking verbs. ---/ - -/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC - 0: AC - -/--- Test skipping over a non-matching mark. ---/ - -/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/xK - AAAC - 0: AC - -/--- Check shorthand for MARK ---/ - -/A(*:A)A+(*SKIP:A)(B|Z) | AC/xK - AAAC - 0: AC - -/--- Don't loop! ---/ - -/(*:A)A+(*SKIP:A)(B|Z)/K - AAAC -No match, mark = A - -/--- This should succeed, as a non-existent skip name disables the skip ---/ - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK - AAAC - 0: AC - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/xK - AAAC - 0: AC -MK: B - -/--- We use something more complicated than individual letters here, because -that causes different behaviour in Perl. Perhaps it disables some optimization; -anyway, the result now matches PCRE in that no tag is passed back for the -failures. ---/ - -/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK - AABC - 0: AB - 1: A - 2: B -MK: A - XXYZ - 0: XXY - 1: - 2: - 3: X - 4: X - 5: Y -MK: B - ** Failers -No match - XAQQ -No match - XAQQXZZ -No match - AXQQQ -No match - AXXQQQ -No match - -/--- COMMIT at the start of a pattern should act like an anchor. Again, -however, we need the complication for Perl. ---/ - -/(*COMMIT)(A|P)(B|P)(C|P)/ - ABCDEFG - 0: ABC - 1: A - 2: B - 3: C - ** Failers -No match - DEFGABC -No match - -/--- COMMIT inside an atomic group can't stop backtracking over the group. ---/ - -/(\w+)(?>b(*COMMIT))\w{2}/ - abbb - 0: abbb - 1: a - -/(\w+)b(*COMMIT)\w{2}/ - abbb -No match - -/--- Check opening parens in comment when seeking forward reference. ---/ - -/(?&t)(?#()(?(DEFINE)(?a))/ - bac - 0: a - -/--- COMMIT should override THEN ---/ - -/(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?/ - yes -No match - -/(?>(*COMMIT)(yes|no)(*THEN)(*F))?/ - yes -No match - -/^((yes|no)(*THEN)(*F))?/ - yes - 0: - -/b?(*SKIP)c/ - bc - 0: bc - abc - 0: bc - -/(*SKIP)bc/ - a -No match - -/(*SKIP)b/ - a -No match - -/(?P(?P=abn)xxx|)+/ - xxx - 0: - 1: - -/-- End of testinput11 --/ diff -Nru pcre3-8.12/testdata/testoutput11-16 pcre3-8.31/testdata/testoutput11-16 --- pcre3-8.12/testdata/testoutput11-16 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput11-16 2012-02-22 13:54:41.000000000 +0000 @@ -0,0 +1,713 @@ +/-- These are a few representative patterns whose lengths and offsets are to be +shown when the link size is 2. This is just a doublecheck test to ensure the +sizes don't go horribly wrong when something is changed. The pattern contents +are all themselves checked in other tests. Unicode, including property support, +is required for these tests. --/ + +/((?i)b)/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 5 CBra 1 + 5 /i b + 7 5 Ket + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/(?s)(.*X|^B)/BM +Memory allocation (code space): 38 +------------------------------------------------------------------ + 0 16 Bra + 2 7 CBra 1 + 5 AllAny* + 7 X + 9 5 Alt + 11 ^ + 12 B + 14 12 Ket + 16 16 Ket + 18 End +------------------------------------------------------------------ + +/(?s:.*X|^B)/BM +Memory allocation (code space): 36 +------------------------------------------------------------------ + 0 15 Bra + 2 6 Bra + 4 AllAny* + 6 X + 8 5 Alt + 10 ^ + 11 B + 13 11 Ket + 15 15 Ket + 17 End +------------------------------------------------------------------ + +/^[[:alnum:]]/BM +Memory allocation (code space): 46 +------------------------------------------------------------------ + 0 20 Bra + 2 ^ + 3 [0-9A-Za-z] + 20 20 Ket + 22 End +------------------------------------------------------------------ + +/#/IxMD +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 2 Bra + 2 2 Ket + 4 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +No first char +No need char + +/a#/IxMD +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +First char = 'a' +No need char + +/x?+/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 x?+ + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/x++/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 x++ + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/x{1,3}+/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 11 Bra + 2 7 Once + 4 x + 6 x{0,2} + 9 7 Ket + 11 11 Ket + 13 End +------------------------------------------------------------------ + +/(x)*+/BM +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 Braposzero + 3 5 CBraPos 1 + 6 x + 8 5 KetRpos + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM +Memory allocation (code space): 142 +------------------------------------------------------------------ + 0 68 Bra + 2 ^ + 3 63 CBra 1 + 6 5 CBra 2 + 9 a+ + 11 5 Ket + 13 21 CBra 3 + 16 [ab]+? + 34 21 Ket + 36 21 CBra 4 + 39 [bc]+ + 57 21 Ket + 59 5 CBra 5 + 62 \w* + 64 5 Ket + 66 63 Ket + 68 68 Ket + 70 End +------------------------------------------------------------------ + +|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM +Memory allocation (code space): 1648 +------------------------------------------------------------------ + 0 821 Bra + 2 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +820 \b +821 821 Ket +823 End +------------------------------------------------------------------ + +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM +Memory allocation (code space): 1628 +------------------------------------------------------------------ + 0 811 Bra + 2 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +810 \b +811 811 Ket +813 End +------------------------------------------------------------------ + +/(a(?1)b)/BM +Memory allocation (code space): 32 +------------------------------------------------------------------ + 0 13 Bra + 2 9 CBra 1 + 5 a + 7 2 Recurse + 9 b + 11 9 Ket + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/(a(?1)+b)/BM +Memory allocation (code space): 40 +------------------------------------------------------------------ + 0 17 Bra + 2 13 CBra 1 + 5 a + 7 4 Once + 9 2 Recurse + 11 4 KetRmax + 13 b + 15 13 Ket + 17 17 Ket + 19 End +------------------------------------------------------------------ + +/a(?Pb|c)d(?Pe)/BM +Memory allocation (code space): 80 +------------------------------------------------------------------ + 0 24 Bra + 2 a + 4 5 CBra 1 + 7 b + 9 4 Alt + 11 c + 13 9 Ket + 15 d + 17 5 CBra 2 + 20 e + 22 5 Ket + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/(?:a(?Pc(?Pd)))(?Pa)/BM +Memory allocation (code space): 73 +------------------------------------------------------------------ + 0 29 Bra + 2 18 Bra + 4 a + 6 12 CBra 1 + 9 c + 11 5 CBra 2 + 14 d + 16 5 Ket + 18 12 Ket + 20 18 Ket + 22 5 CBra 3 + 25 a + 27 5 Ket + 29 29 Ket + 31 End +------------------------------------------------------------------ + +/(?Pa)...(?P=a)bbb(?P>a)d/BM +Memory allocation (code space): 57 +------------------------------------------------------------------ + 0 24 Bra + 2 5 CBra 1 + 5 a + 7 5 Ket + 9 Any + 10 Any + 11 Any + 12 \1 + 14 bbb + 20 2 Recurse + 22 d + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/abc(?C255)de(?C)f/BM +Memory allocation (code space): 50 +------------------------------------------------------------------ + 0 22 Bra + 2 abc + 8 Callout 255 10 1 + 12 de + 16 Callout 0 16 1 + 20 f + 22 22 Ket + 24 End +------------------------------------------------------------------ + +/abcde/CBM +Memory allocation (code space): 78 +------------------------------------------------------------------ + 0 36 Bra + 2 Callout 255 0 1 + 6 a + 8 Callout 255 1 1 + 12 b + 14 Callout 255 2 1 + 18 c + 20 Callout 255 3 1 + 24 d + 26 Callout 255 4 1 + 30 e + 32 Callout 255 5 0 + 36 36 Ket + 38 End +------------------------------------------------------------------ + +/\x{100}/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{1000}/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{1000} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{10000}/8BM +Memory allocation (code space): 16 +------------------------------------------------------------------ + 0 5 Bra + 2 \x{10000} + 5 5 Ket + 7 End +------------------------------------------------------------------ + +/\x{100000}/8BM +Memory allocation (code space): 16 +------------------------------------------------------------------ + 0 5 Bra + 2 \x{100000} + 5 5 Ket + 7 End +------------------------------------------------------------------ + +/\x{10ffff}/8BM +Memory allocation (code space): 16 +------------------------------------------------------------------ + 0 5 Bra + 2 \x{10ffff} + 5 5 Ket + 7 End +------------------------------------------------------------------ + +/\x{110000}/8BM +Failed: character value in \x{...} sequence is too large at offset 9 + +/[\x{ff}]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \xff + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\x{100}]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x80/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x80 + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\xff/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \xff + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 A\x{2262}\x{391}. + 10 10 Ket + 12 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = '.' + +/\x{D55c}\x{ad6d}\x{C5B4}/D8M +Memory allocation (code space): 22 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{d55c}\x{ad6d}\x{c5b4} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/D8M +Memory allocation (code space): 22 +------------------------------------------------------------------ + 0 8 Bra + 2 \x{65e5}\x{672c}\x{8a9e} + 8 8 Ket + 10 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + +/[\x{100}]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \x{100} + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[Z\x{100}]/8BM +Memory allocation (code space): 54 +------------------------------------------------------------------ + 0 24 Bra + 2 [Z\x{100}] + 24 24 Ket + 26 End +------------------------------------------------------------------ + +/^[\x{100}\E-\Q\E\x{150}]/B8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E]/B8M +Memory allocation (code space): 26 +------------------------------------------------------------------ + 0 10 Bra + 2 ^ + 3 [\x{100}-\x{150}] + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E/B8M +Failed: missing terminating ] for character class at offset 13 + +/[\p{L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{^L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\P{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\P{^L}]/BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{L}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[abc\p{L}\x{0660}]/8BM +Memory allocation (code space): 60 +------------------------------------------------------------------ + 0 27 Bra + 2 [a-c\p{L}\x{660}] + 27 27 Ket + 29 End +------------------------------------------------------------------ + +/[\p{Nd}]/8BM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[\p{Nd}+-]+/8BM +Memory allocation (code space): 58 +------------------------------------------------------------------ + 0 26 Bra + 2 [+\-\p{Nd}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM +Memory allocation (code space): 32 +------------------------------------------------------------------ + 0 13 Bra + 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM +Memory allocation (code space): 32 +------------------------------------------------------------------ + 0 13 Bra + 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/[\x{105}-\x{109}]/8iBM +Memory allocation (code space): 24 +------------------------------------------------------------------ + 0 9 Bra + 2 [\x{104}-\x{109}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/( ( (?(1)0|) )* )/xBM +Memory allocation (code space): 52 +------------------------------------------------------------------ + 0 23 Bra + 2 19 CBra 1 + 5 Brazero + 6 13 SCBra 2 + 9 6 Cond + 11 1 Cond ref + 13 0 + 15 2 Alt + 17 8 Ket + 19 13 KetRmax + 21 19 Ket + 23 23 Ket + 25 End +------------------------------------------------------------------ + +/( (?(1)0|)* )/xBM +Memory allocation (code space): 42 +------------------------------------------------------------------ + 0 18 Bra + 2 14 CBra 1 + 5 Brazero + 6 6 SCond + 8 1 Cond ref + 10 0 + 12 2 Alt + 14 8 KetRmax + 16 14 Ket + 18 18 Ket + 20 End +------------------------------------------------------------------ + +/[a]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[a]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 a + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \xaa + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[\xaa]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 \xaa + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^a]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^a] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\xaa] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\xaa]/8BM +Memory allocation (code space): 14 +------------------------------------------------------------------ + 0 4 Bra + 2 [^\xaa] + 4 4 Ket + 6 End +------------------------------------------------------------------ + +/[^\d]/8WB +------------------------------------------------------------------ + 0 9 Bra + 2 [^\p{Nd}] + 9 9 Ket + 11 End +------------------------------------------------------------------ + +/[[:^alpha:][:^cntrl:]]+/8WB +------------------------------------------------------------------ + 0 26 Bra + 2 [ -~\x80-\xff\P{L}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/[[:^cntrl:][:^alpha:]]+/8WB +------------------------------------------------------------------ + 0 26 Bra + 2 [ -~\x80-\xff\P{L}]+ + 26 26 Ket + 28 End +------------------------------------------------------------------ + +/[[:alpha:]]+/8WB +------------------------------------------------------------------ + 0 10 Bra + 2 [\p{L}]+ + 10 10 Ket + 12 End +------------------------------------------------------------------ + +/[[:^alpha:]\S]+/8WB +------------------------------------------------------------------ + 0 13 Bra + 2 [\P{L}\P{Xsp}]+ + 13 13 Ket + 15 End +------------------------------------------------------------------ + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +------------------------------------------------------------------ + 0 60 Bra + 2 abc + 8 5 CBra 1 + 11 d + 13 4 Alt + 15 e + 17 9 Ket + 19 *THEN + 20 x + 22 12 CBra 2 + 25 123 + 31 *THEN + 32 4 + 34 24 Alt + 36 567 + 42 5 CBra 3 + 45 b + 47 4 Alt + 49 q + 51 9 Ket + 53 *THEN + 54 xx + 58 36 Ket + 60 60 Ket + 62 End +------------------------------------------------------------------ + +/-- End of testinput11 --/ diff -Nru pcre3-8.12/testdata/testoutput11-8 pcre3-8.31/testdata/testoutput11-8 --- pcre3-8.12/testdata/testoutput11-8 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput11-8 2012-02-22 13:54:41.000000000 +0000 @@ -0,0 +1,713 @@ +/-- These are a few representative patterns whose lengths and offsets are to be +shown when the link size is 2. This is just a doublecheck test to ensure the +sizes don't go horribly wrong when something is changed. The pattern contents +are all themselves checked in other tests. Unicode, including property support, +is required for these tests. --/ + +/((?i)b)/BM +Memory allocation (code space): 17 +------------------------------------------------------------------ + 0 13 Bra + 3 7 CBra 1 + 8 /i b + 10 7 Ket + 13 13 Ket + 16 End +------------------------------------------------------------------ + +/(?s)(.*X|^B)/BM +Memory allocation (code space): 25 +------------------------------------------------------------------ + 0 21 Bra + 3 9 CBra 1 + 8 AllAny* + 10 X + 12 6 Alt + 15 ^ + 16 B + 18 15 Ket + 21 21 Ket + 24 End +------------------------------------------------------------------ + +/(?s:.*X|^B)/BM +Memory allocation (code space): 23 +------------------------------------------------------------------ + 0 19 Bra + 3 7 Bra + 6 AllAny* + 8 X + 10 6 Alt + 13 ^ + 14 B + 16 13 Ket + 19 19 Ket + 22 End +------------------------------------------------------------------ + +/^[[:alnum:]]/BM +Memory allocation (code space): 41 +------------------------------------------------------------------ + 0 37 Bra + 3 ^ + 4 [0-9A-Za-z] + 37 37 Ket + 40 End +------------------------------------------------------------------ + +/#/IxMD +Memory allocation (code space): 7 +------------------------------------------------------------------ + 0 3 Bra + 3 3 Ket + 6 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +No first char +No need char + +/a#/IxMD +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 a + 5 5 Ket + 8 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: extended +First char = 'a' +No need char + +/x?+/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 x?+ + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/x++/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 x++ + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/x{1,3}+/BM +Memory allocation (code space): 19 +------------------------------------------------------------------ + 0 15 Bra + 3 9 Once + 6 x + 8 x{0,2} + 12 9 Ket + 15 15 Ket + 18 End +------------------------------------------------------------------ + +/(x)*+/BM +Memory allocation (code space): 18 +------------------------------------------------------------------ + 0 14 Bra + 3 Braposzero + 4 7 CBraPos 1 + 9 x + 11 7 KetRpos + 14 14 Ket + 17 End +------------------------------------------------------------------ + +/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM +Memory allocation (code space): 120 +------------------------------------------------------------------ + 0 116 Bra + 3 ^ + 4 109 CBra 1 + 9 7 CBra 2 + 14 a+ + 16 7 Ket + 19 39 CBra 3 + 24 [ab]+? + 58 39 Ket + 61 39 CBra 4 + 66 [bc]+ +100 39 Ket +103 7 CBra 5 +108 \w* +110 7 Ket +113 109 Ket +116 116 Ket +119 End +------------------------------------------------------------------ + +|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM +Memory allocation (code space): 826 +------------------------------------------------------------------ + 0 822 Bra + 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +821 \b +822 822 Ket +825 End +------------------------------------------------------------------ + +|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM +Memory allocation (code space): 816 +------------------------------------------------------------------ + 0 812 Bra + 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X +811 \b +812 812 Ket +815 End +------------------------------------------------------------------ + +/(a(?1)b)/BM +Memory allocation (code space): 22 +------------------------------------------------------------------ + 0 18 Bra + 3 12 CBra 1 + 8 a + 10 3 Recurse + 13 b + 15 12 Ket + 18 18 Ket + 21 End +------------------------------------------------------------------ + +/(a(?1)+b)/BM +Memory allocation (code space): 28 +------------------------------------------------------------------ + 0 24 Bra + 3 18 CBra 1 + 8 a + 10 6 Once + 13 3 Recurse + 16 6 KetRmax + 19 b + 21 18 Ket + 24 24 Ket + 27 End +------------------------------------------------------------------ + +/a(?Pb|c)d(?Pe)/BM +Memory allocation (code space): 36 +------------------------------------------------------------------ + 0 32 Bra + 3 a + 5 7 CBra 1 + 10 b + 12 5 Alt + 15 c + 17 12 Ket + 20 d + 22 7 CBra 2 + 27 e + 29 7 Ket + 32 32 Ket + 35 End +------------------------------------------------------------------ + +/(?:a(?Pc(?Pd)))(?Pa)/BM +Memory allocation (code space): 45 +------------------------------------------------------------------ + 0 41 Bra + 3 25 Bra + 6 a + 8 17 CBra 1 + 13 c + 15 7 CBra 2 + 20 d + 22 7 Ket + 25 17 Ket + 28 25 Ket + 31 7 CBra 3 + 36 a + 38 7 Ket + 41 41 Ket + 44 End +------------------------------------------------------------------ + +/(?Pa)...(?P=a)bbb(?P>a)d/BM +Memory allocation (code space): 34 +------------------------------------------------------------------ + 0 30 Bra + 3 7 CBra 1 + 8 a + 10 7 Ket + 13 Any + 14 Any + 15 Any + 16 \1 + 19 bbb + 25 3 Recurse + 28 d + 30 30 Ket + 33 End +------------------------------------------------------------------ + +/abc(?C255)de(?C)f/BM +Memory allocation (code space): 31 +------------------------------------------------------------------ + 0 27 Bra + 3 abc + 9 Callout 255 10 1 + 15 de + 19 Callout 0 16 1 + 25 f + 27 27 Ket + 30 End +------------------------------------------------------------------ + +/abcde/CBM +Memory allocation (code space): 53 +------------------------------------------------------------------ + 0 49 Bra + 3 Callout 255 0 1 + 9 a + 11 Callout 255 1 1 + 17 b + 19 Callout 255 2 1 + 25 c + 27 Callout 255 3 1 + 33 d + 35 Callout 255 4 1 + 41 e + 43 Callout 255 5 0 + 49 49 Ket + 52 End +------------------------------------------------------------------ + +/\x{100}/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{100} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/\x{1000}/8BM +Memory allocation (code space): 11 +------------------------------------------------------------------ + 0 7 Bra + 3 \x{1000} + 7 7 Ket + 10 End +------------------------------------------------------------------ + +/\x{10000}/8BM +Memory allocation (code space): 12 +------------------------------------------------------------------ + 0 8 Bra + 3 \x{10000} + 8 8 Ket + 11 End +------------------------------------------------------------------ + +/\x{100000}/8BM +Memory allocation (code space): 12 +------------------------------------------------------------------ + 0 8 Bra + 3 \x{100000} + 8 8 Ket + 11 End +------------------------------------------------------------------ + +/\x{10ffff}/8BM +Memory allocation (code space): 12 +------------------------------------------------------------------ + 0 8 Bra + 3 \x{10ffff} + 8 8 Ket + 11 End +------------------------------------------------------------------ + +/\x{110000}/8BM +Failed: character value in \x{...} sequence is too large at offset 9 + +/[\x{ff}]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{ff} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[\x{100}]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{100} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/\x80/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{80} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/\xff/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{ff} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/\x{0041}\x{2262}\x{0391}\x{002e}/D8M +Memory allocation (code space): 18 +------------------------------------------------------------------ + 0 14 Bra + 3 A\x{2262}\x{391}. + 14 14 Ket + 17 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = '.' + +/\x{D55c}\x{ad6d}\x{C5B4}/D8M +Memory allocation (code space): 19 +------------------------------------------------------------------ + 0 15 Bra + 3 \x{d55c}\x{ad6d}\x{c5b4} + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ed} +Need char = \x{b4} + +/\x{65e5}\x{672c}\x{8a9e}/D8M +Memory allocation (code space): 19 +------------------------------------------------------------------ + 0 15 Bra + 3 \x{65e5}\x{672c}\x{8a9e} + 15 15 Ket + 18 End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e6} +Need char = \x{9e} + +/[\x{100}]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{100} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[Z\x{100}]/8BM +Memory allocation (code space): 47 +------------------------------------------------------------------ + 0 43 Bra + 3 [Z\x{100}] + 43 43 Ket + 46 End +------------------------------------------------------------------ + +/^[\x{100}\E-\Q\E\x{150}]/B8M +Memory allocation (code space): 18 +------------------------------------------------------------------ + 0 14 Bra + 3 ^ + 4 [\x{100}-\x{150}] + 14 14 Ket + 17 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E]/B8M +Memory allocation (code space): 18 +------------------------------------------------------------------ + 0 14 Bra + 3 ^ + 4 [\x{100}-\x{150}] + 14 14 Ket + 17 End +------------------------------------------------------------------ + +/^[\QÄ€\E-\QÅ\E/B8M +Failed: missing terminating ] for character class at offset 15 + +/[\p{L}]/BM +Memory allocation (code space): 15 +------------------------------------------------------------------ + 0 11 Bra + 3 [\p{L}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[\p{^L}]/BM +Memory allocation (code space): 15 +------------------------------------------------------------------ + 0 11 Bra + 3 [\P{L}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[\P{L}]/BM +Memory allocation (code space): 15 +------------------------------------------------------------------ + 0 11 Bra + 3 [\P{L}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[\P{^L}]/BM +Memory allocation (code space): 15 +------------------------------------------------------------------ + 0 11 Bra + 3 [\p{L}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[abc\p{L}\x{0660}]/8BM +Memory allocation (code space): 50 +------------------------------------------------------------------ + 0 46 Bra + 3 [a-c\p{L}\x{660}] + 46 46 Ket + 49 End +------------------------------------------------------------------ + +/[\p{Nd}]/8BM +Memory allocation (code space): 15 +------------------------------------------------------------------ + 0 11 Bra + 3 [\p{Nd}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[\p{Nd}+-]+/8BM +Memory allocation (code space): 48 +------------------------------------------------------------------ + 0 44 Bra + 3 [+\-\p{Nd}]+ + 44 44 Ket + 47 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM +Memory allocation (code space): 25 +------------------------------------------------------------------ + 0 21 Bra + 3 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 21 21 Ket + 24 End +------------------------------------------------------------------ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM +Memory allocation (code space): 25 +------------------------------------------------------------------ + 0 21 Bra + 3 A\x{391}\x{10427}\x{ff3a}\x{1fb0} + 21 21 Ket + 24 End +------------------------------------------------------------------ + +/[\x{105}-\x{109}]/8iBM +Memory allocation (code space): 17 +------------------------------------------------------------------ + 0 13 Bra + 3 [\x{104}-\x{109}] + 13 13 Ket + 16 End +------------------------------------------------------------------ + +/( ( (?(1)0|) )* )/xBM +Memory allocation (code space): 38 +------------------------------------------------------------------ + 0 34 Bra + 3 28 CBra 1 + 8 Brazero + 9 19 SCBra 2 + 14 8 Cond + 17 1 Cond ref + 20 0 + 22 3 Alt + 25 11 Ket + 28 19 KetRmax + 31 28 Ket + 34 34 Ket + 37 End +------------------------------------------------------------------ + +/( (?(1)0|)* )/xBM +Memory allocation (code space): 30 +------------------------------------------------------------------ + 0 26 Bra + 3 20 CBra 1 + 8 Brazero + 9 8 SCond + 12 1 Cond ref + 15 0 + 17 3 Alt + 20 11 KetRmax + 23 20 Ket + 26 26 Ket + 29 End +------------------------------------------------------------------ + +/[a]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 a + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[a]/8BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 a + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[\xaa]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 \xaa + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[\xaa]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 \x{aa} + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[^a]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^a] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^a]/8BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^a] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^\xaa]/BM +Memory allocation (code space): 9 +------------------------------------------------------------------ + 0 5 Bra + 3 [^\xaa] + 5 5 Ket + 8 End +------------------------------------------------------------------ + +/[^\xaa]/8BM +Memory allocation (code space): 10 +------------------------------------------------------------------ + 0 6 Bra + 3 [^\x{aa}] + 6 6 Ket + 9 End +------------------------------------------------------------------ + +/[^\d]/8WB +------------------------------------------------------------------ + 0 11 Bra + 3 [^\p{Nd}] + 11 11 Ket + 14 End +------------------------------------------------------------------ + +/[[:^alpha:][:^cntrl:]]+/8WB +------------------------------------------------------------------ + 0 44 Bra + 3 [ -~\x80-\xff\P{L}]+ + 44 44 Ket + 47 End +------------------------------------------------------------------ + +/[[:^cntrl:][:^alpha:]]+/8WB +------------------------------------------------------------------ + 0 44 Bra + 3 [ -~\x80-\xff\P{L}]+ + 44 44 Ket + 47 End +------------------------------------------------------------------ + +/[[:alpha:]]+/8WB +------------------------------------------------------------------ + 0 12 Bra + 3 [\p{L}]+ + 12 12 Ket + 15 End +------------------------------------------------------------------ + +/[[:^alpha:]\S]+/8WB +------------------------------------------------------------------ + 0 15 Bra + 3 [\P{L}\P{Xsp}]+ + 15 15 Ket + 18 End +------------------------------------------------------------------ + +/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B +------------------------------------------------------------------ + 0 73 Bra + 3 abc + 9 7 CBra 1 + 14 d + 16 5 Alt + 19 e + 21 12 Ket + 24 *THEN + 25 x + 27 14 CBra 2 + 32 123 + 38 *THEN + 39 4 + 41 29 Alt + 44 567 + 50 7 CBra 3 + 55 b + 57 5 Alt + 60 q + 62 12 Ket + 65 *THEN + 66 xx + 70 43 Ket + 73 73 Ket + 76 End +------------------------------------------------------------------ + +/-- End of testinput11 --/ diff -Nru pcre3-8.12/testdata/testoutput12 pcre3-8.31/testdata/testoutput12 --- pcre3-8.12/testdata/testoutput12 2010-06-01 16:20:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput12 2012-04-11 15:57:12.000000000 +0000 @@ -1,1179 +1,155 @@ -/-- These tests for Unicode property support test PCRE's API and show some of - the compiled code. They are not Perl-compatible. --/ +/-- This test is run only when JIT support is available. It checks for a +successful and an unsuccessful JIT compile and save and restore behaviour, +and a couple of things that are different with JIT. --/ -/[\p{L}]/DZ ------------------------------------------------------------------- - Bra - [\p{L}] - Ket - End ------------------------------------------------------------------- +/abc/S+I Capturing subpattern count = 0 No options -No first char -No need char - -/[\p{^L}]/DZ ------------------------------------------------------------------- - Bra - [\P{L}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -No options -No first char -No need char +First char = 'a' +Need char = 'c' +Subject length lower bound = 3 +No set of starting bytes +JIT study was successful -/[\P{L}]/DZ ------------------------------------------------------------------- - Bra - [\P{L}] - Ket - End ------------------------------------------------------------------- +/ab(*THEN)/S+I Capturing subpattern count = 0 No options -No first char -No need char +First char = 'a' +Need char = 'b' +Subject length lower bound = 2 +No set of starting bytes +JIT study was not successful -/[\P{^L}]/DZ ------------------------------------------------------------------- - Bra - [\p{L}] - Ket - End ------------------------------------------------------------------- +/abc/S+I>testsavedregex Capturing subpattern count = 0 No options -No first char -No need char - -/[abc\p{L}\x{0660}]/8DZ ------------------------------------------------------------------- - Bra - [a-c\p{L}\x{660}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - -/[\p{Nd}]/8DZ ------------------------------------------------------------------- - Bra - [\p{Nd}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - 1234 - 0: 1 - -/[\p{Nd}+-]+/8DZ ------------------------------------------------------------------- - Bra - [+\-\p{Nd}]+ - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - 1234 - 0: 1234 - 12-34 - 0: 12-34 - 12+\x{661}-34 - 0: 12+\x{661}-34 - ** Failers -No match - abcd -No match - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ ------------------------------------------------------------------- - Bra - NC A\x{391}\x{10427}\x{ff3a}\x{1fb0} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: caseless utf8 -First char = 'A' (caseless) -No need char - -/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ ------------------------------------------------------------------- - Bra - A\x{391}\x{10427}\x{ff3a}\x{1fb0} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'A' -Need char = 176 - -/AB\x{1fb0}/8DZ ------------------------------------------------------------------- - Bra - AB\x{1fb0} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'A' -Need char = 176 - -/AB\x{1fb0}/8DZi ------------------------------------------------------------------- - Bra - NC AB\x{1fb0} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: caseless utf8 -First char = 'A' (caseless) -Need char = 'B' (caseless) - -/[\x{105}-\x{109}]/8iDZ ------------------------------------------------------------------- - Bra - [\x{104}-\x{109}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: caseless utf8 -No first char -No need char - \x{104} - 0: \x{104} - \x{105} - 0: \x{105} - \x{109} - 0: \x{109} - ** Failers -No match - \x{100} -No match - \x{10a} -No match - -/[z-\x{100}]/8iDZ ------------------------------------------------------------------- - Bra - [Z\x{39c}\x{178}z-\x{101}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: caseless utf8 -No first char -No need char - Z - 0: Z - z - 0: z - \x{39c} - 0: \x{39c} - \x{178} - 0: \x{178} - | - 0: | - \x{80} - 0: \x{80} - \x{ff} - 0: \x{ff} - \x{100} - 0: \x{100} - \x{101} - 0: \x{101} - ** Failers -No match - \x{102} -No match - Y -No match - y -No match - -/[z-\x{100}]/8DZi ------------------------------------------------------------------- - Bra - [Z\x{39c}\x{178}z-\x{101}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: caseless utf8 -No first char -No need char - -/(?:[\PPa*]*){8,}/ - -/[\P{Any}]/BZ ------------------------------------------------------------------- - Bra - [\P{Any}] - Ket - End ------------------------------------------------------------------- - -/[\P{Any}\E]/BZ ------------------------------------------------------------------- - Bra - [\P{Any}] - Ket - End ------------------------------------------------------------------- - -/(\P{Yi}+\277)/ - -/(\P{Yi}+\277)?/ - -/(?<=\P{Yi}{3}A)X/ - -/\p{Yi}+(\P{Yi}+)(?1)/ - -/(\P{Yi}{2}\277)?/ - -/[\P{Yi}A]/ - -/[\P{Yi}\P{Yi}\P{Yi}A]/ - -/[^\P{Yi}A]/ - -/[^\P{Yi}\P{Yi}\P{Yi}A]/ - -/(\P{Yi}*\277)*/ - -/(\P{Yi}*?\277)*/ - -/(\p{Yi}*+\277)*/ - -/(\P{Yi}?\277)*/ - -/(\P{Yi}??\277)*/ - -/(\p{Yi}?+\277)*/ - -/(\P{Yi}{0,3}\277)*/ - -/(\P{Yi}{0,3}?\277)*/ - -/(\p{Yi}{0,3}+\277)*/ - -/\p{Zl}{2,3}+/8BZ ------------------------------------------------------------------- - Bra - prop Zl {2} - prop Zl ?+ - Ket - End ------------------------------------------------------------------- - \xe2\x80\xa8\xe2\x80\xa8 - 0: \x{2028}\x{2028} - \x{2028}\x{2028}\x{2028} - 0: \x{2028}\x{2028}\x{2028} - -/\p{Zl}/8BZ ------------------------------------------------------------------- - Bra - prop Zl - Ket - End ------------------------------------------------------------------- - -/\p{Lu}{3}+/8BZ ------------------------------------------------------------------- - Bra - prop Lu {3} - Ket - End ------------------------------------------------------------------- - -/\pL{2}+/8BZ ------------------------------------------------------------------- - Bra - prop L {2} - Ket - End ------------------------------------------------------------------- - -/\p{Cc}{2}+/8BZ ------------------------------------------------------------------- - Bra - prop Cc {2} - Ket - End ------------------------------------------------------------------- - -/^\p{Cs}/8 - \?\x{dfff} - 0: \x{dfff} - ** Failers -No match - \x{09f} -No match - -/^\p{Sc}+/8 - $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} - 0: $\x{a2}\x{a3}\x{a4}\x{a5} - \x{9f2} - 0: \x{9f2} - ** Failers -No match - X -No match - \x{2c2} -No match - -/^\p{Zs}/8 - \ \ - 0: - \x{a0} - 0: \x{a0} - \x{1680} - 0: \x{1680} - \x{180e} - 0: \x{180e} - \x{2000} - 0: \x{2000} - \x{2001} - 0: \x{2001} - ** Failers -No match - \x{2028} -No match - \x{200d} -No match - -/-- These four are here rather than in test 6 because Perl has problems with - the negative versions of the properties. --/ - -/\p{^Lu}/8i - 1234 - 0: 1 - ** Failers - 0: * - ABC -No match - -/\P{Lu}/8i - 1234 - 0: 1 - ** Failers - 0: * - ABC -No match - -/\p{Ll}/8i - a - 0: a - Az - 0: z - ** Failers - 0: a - ABC -No match - -/\p{Lu}/8i - A - 0: A - a\x{10a0}B - 0: \x{10a0} - ** Failers - 0: F - a -No match - \x{1d00} -No match - -/[\x{c0}\x{391}]/8i - \x{c0} - 0: \x{c0} - \x{e0} - 0: \x{e0} - -/-- The next two are special cases where the lengths of the different cases of -the same character differ. The first went wrong with heap frame storage; the -second was broken in all cases. --/ - -/^\x{023a}+?(\x{0130}+)/8i - \x{023a}\x{2c65}\x{0130} - 0: \x{23a}\x{2c65}\x{130} - 1: \x{130} - -/^\x{023a}+([^X])/8i - \x{023a}\x{2c65}X - 0: \x{23a}\x{2c65} - 1: \x{2c65} - -/\x{c0}+\x{116}+/8i - \x{c0}\x{e0}\x{116}\x{117} - 0: \x{c0}\x{e0}\x{116}\x{117} - -/[\x{c0}\x{116}]+/8i - \x{c0}\x{e0}\x{116}\x{117} - 0: \x{c0}\x{e0}\x{116}\x{117} - -/(\x{de})\1/8i - \x{de}\x{de} - 0: \x{de}\x{de} - 1: \x{de} - \x{de}\x{fe} - 0: \x{de}\x{fe} - 1: \x{de} - \x{fe}\x{fe} - 0: \x{fe}\x{fe} - 1: \x{fe} - \x{fe}\x{de} - 0: \x{fe}\x{de} - 1: \x{fe} - -/^\x{c0}$/8i - \x{c0} - 0: \x{c0} - \x{e0} - 0: \x{e0} - -/^\x{e0}$/8i - \x{c0} - 0: \x{c0} - \x{e0} - 0: \x{e0} - -/-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE -will match it only with UCP support, because without that it has no notion -of case for anything other than the ASCII letters. --/ - -/((?i)[\x{c0}])/8 - \x{c0} - 0: \x{c0} - 1: \x{c0} - \x{e0} - 0: \x{e0} - 1: \x{e0} - -/(?i:[\x{c0}])/8 - \x{c0} - 0: \x{c0} - \x{e0} - 0: \x{e0} - -/-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 - -/^\X/8 - A - 0: A - A\x{300}BC - 0: A\x{300} - A\x{300}\x{301}\x{302}BC - 0: A\x{300}\x{301}\x{302} - *** Failers - 0: * - \x{300} -No match - -/-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ - -/^\p{Xan}/8 - ABCD - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - ** Failers -No match - _ABC -No match - -/^\p{Xan}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - ** Failers -No match - _ABC -No match - -/^\p{Xan}+?/8 - \x{6ca}\x{a6c}\x{10a7}_ - 0: \x{6ca} - -/^\p{Xan}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - -/^\p{Xan}{2,9}/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca} - -/^\p{Xan}{2,9}?/8 - \x{6ca}\x{a6c}\x{10a7}_ - 0: \x{6ca}\x{a6c} - -/^[\p{Xan}]/8 - ABCD1234_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - ** Failers -No match - _ABC -No match - -/^[\p{Xan}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - ** Failers -No match - _ABC -No match - -/^>\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - >\x{a0} - 0: >\x{a0} - ** Failers -No match - \x{0b} -No match - -/^>\p{Xsp}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - -/^>\p{Xsp}+?/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - -/^>\p{Xsp}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - -/^>\p{Xsp}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - -/^>\p{Xsp}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09} - -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\p{Xsp}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - -/^>\p{Xps}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - >\x{a0} - 0: >\x{a0} - ** Failers -No match - \x{0b} -No match - -/^>\p{Xps}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}+?/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - -/^>\p{Xps}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^>\p{Xps}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09} - -/^>[\p{Xps}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\p{Xps}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - -/^\p{Xwd}/8 - ABCD - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers -No match - [] -No match - -/^\p{Xwd}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}+?/8 - \x{6ca}\x{a6c}\x{10a7}_ - 0: \x{6ca} - -/^\p{Xwd}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/^\p{Xwd}{2,9}/8 - A_B12\x{6ca}\x{a6c}\x{10a7} - 0: A_B12\x{6ca}\x{a6c}\x{10a7} - -/^\p{Xwd}{2,9}?/8 - \x{6ca}\x{a6c}\x{10a7}_ - 0: \x{6ca}\x{a6c} - -/^[\p{Xwd}]/8 - ABCD1234_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers -No match - [] -No match - -/^[\p{Xwd}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - -/-- A check not in UTF-8 mode --/ - -/^[\p{Xwd}]+/ - ABCD1234_ - 0: ABCD1234_ - -/-- Some negative checks --/ - -/^[\P{Xwd}]+/8 - !.+\x{019}\x{35a}AB - 0: !.+\x{19}\x{35a} - -/^[\p{^Xwd}]+/8 - !.+\x{019}\x{35a}AB - 0: !.+\x{19}\x{35a} - -/[\D]/WBZ8 ------------------------------------------------------------------- - Bra - [\P{Nd}] - Ket - End ------------------------------------------------------------------- - 1\x{3c8}2 - 0: \x{3c8} - -/[\d]/WBZ8 ------------------------------------------------------------------- - Bra - [\p{Nd}] - Ket - End ------------------------------------------------------------------- - >\x{6f4}< - 0: \x{6f4} - -/[\S]/WBZ8 ------------------------------------------------------------------- - Bra - [\P{Xsp}] - Ket - End ------------------------------------------------------------------- - \x{1680}\x{6f4}\x{1680} - 0: \x{6f4} - -/[\s]/WBZ8 ------------------------------------------------------------------- - Bra - [\p{Xsp}] - Ket - End ------------------------------------------------------------------- - >\x{1680}< - 0: \x{1680} - -/[\W]/WBZ8 ------------------------------------------------------------------- - Bra - [\P{Xwd}] - Ket - End ------------------------------------------------------------------- - A\x{1712}B - 0: \x{1712} - -/[\w]/WBZ8 ------------------------------------------------------------------- - Bra - [\p{Xwd}] - Ket - End ------------------------------------------------------------------- - >\x{1723}< - 0: \x{1723} - -/\D/WBZ8 ------------------------------------------------------------------- - Bra - notprop Nd - Ket - End ------------------------------------------------------------------- - 1\x{3c8}2 - 0: \x{3c8} - -/\d/WBZ8 ------------------------------------------------------------------- - Bra - prop Nd - Ket - End ------------------------------------------------------------------- - >\x{6f4}< - 0: \x{6f4} - -/\S/WBZ8 ------------------------------------------------------------------- - Bra - notprop Xsp - Ket - End ------------------------------------------------------------------- - \x{1680}\x{6f4}\x{1680} - 0: \x{6f4} - -/\s/WBZ8 ------------------------------------------------------------------- - Bra - prop Xsp - Ket - End ------------------------------------------------------------------- - >\x{1680}> - 0: \x{1680} - -/\W/WBZ8 ------------------------------------------------------------------- - Bra - notprop Xwd - Ket - End ------------------------------------------------------------------- - A\x{1712}B - 0: \x{1712} - -/\w/WBZ8 ------------------------------------------------------------------- - Bra - prop Xwd - Ket - End ------------------------------------------------------------------- - >\x{1723}< - 0: \x{1723} - -/[[:alpha:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{L}] - Ket - End ------------------------------------------------------------------- - -/[[:lower:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Ll}] - Ket - End ------------------------------------------------------------------- - -/[[:upper:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Lu}] - Ket - End ------------------------------------------------------------------- - -/[[:alnum:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Xan}] - Ket - End ------------------------------------------------------------------- - -/[[:ascii:]]/WBZ ------------------------------------------------------------------- - Bra - [\x00-\x7f] - Ket - End ------------------------------------------------------------------- - -/[[:blank:]]/WBZ ------------------------------------------------------------------- - Bra - [\x09 \xa0] - Ket - End ------------------------------------------------------------------- - -/[[:cntrl:]]/WBZ ------------------------------------------------------------------- - Bra - [\x00-\x1f\x7f] - Ket - End ------------------------------------------------------------------- - -/[[:digit:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Nd}] - Ket - End ------------------------------------------------------------------- - -/[[:graph:]]/WBZ ------------------------------------------------------------------- - Bra - [!-~] - Ket - End ------------------------------------------------------------------- - -/[[:print:]]/WBZ ------------------------------------------------------------------- - Bra - [ -~] - Ket - End ------------------------------------------------------------------- - -/[[:punct:]]/WBZ ------------------------------------------------------------------- - Bra - [!-/:-@[-`{-~] - Ket - End ------------------------------------------------------------------- - -/[[:space:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Xps}] - Ket - End ------------------------------------------------------------------- - -/[[:word:]]/WBZ ------------------------------------------------------------------- - Bra - [\p{Xwd}] - Ket - End ------------------------------------------------------------------- - -/[[:xdigit:]]/WBZ ------------------------------------------------------------------- - Bra - [0-9A-Fa-f] - Ket - End ------------------------------------------------------------------- - -/-- Unicode properties for \b abd \B --/ - -/\b...\B/8W - abc_ - 0: abc - \x{37e}abc\x{376} - 0: abc - \x{37e}\x{376}\x{371}\x{393}\x{394} - 0: \x{376}\x{371}\x{393} - !\x{c0}++\x{c1}\x{c2} - 0: ++\x{c1} - !\x{c0}+++++ - 0: \x{c0}++ - -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ - -/\b...\B/8 - abc_ - 0: abc - ** Failers - 0: Fai - \x{37e}abc\x{376} -No match - \x{37e}\x{376}\x{371}\x{393}\x{394} -No match - !\x{c0}++\x{c1}\x{c2} -No match - !\x{c0}+++++ -No match - -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ - -/\b...\B/W - abc_ - 0: abc - !\x{c0}++\x{c1}\x{c2} - 0: ++\xc1 - !\x{c0}+++++ - 0: \xc0++ - -/-- POSIX interface --/ - -/\w/P - +++\x{c2} -No match: POSIX code 17: match failed - -/\w/WP - +++\x{c2} - 0: \xc2 - -/-- Some of these are silly, but they check various combinations --/ - -/[[:^alpha:][:^cntrl:]]+/8WBZ ------------------------------------------------------------------- - Bra - [ -~\x80-\xff\P{L}]+ - Ket - End ------------------------------------------------------------------- - 123 - 0: 123 - abc - 0: abc - -/[[:^cntrl:][:^alpha:]]+/8WBZ ------------------------------------------------------------------- - Bra - [ -~\x80-\xff\P{L}]+ - Ket - End ------------------------------------------------------------------- - 123 - 0: 123 - abc - 0: abc - -/[[:alpha:]]+/8WBZ ------------------------------------------------------------------- - Bra - [\p{L}]+ - Ket - End ------------------------------------------------------------------- +First char = 'a' +Need char = 'c' +Subject length lower bound = 3 +No set of starting bytes +JIT study was successful +Compiled pattern written to testsavedregex +Study data written to testsavedregex + +b)c/PN + abc +Matched with REG_NOSUB + +/a?|b?/P + abc + 0: a + ** Failers + 0: + ddd\N +No match: POSIX code 17: match failed + +/\w+A/P + CDAAAAB + 0: CDAAAA + +/\w+A/PU + CDAAAAB + 0: CDA + +/\Biss\B/I+P + Mississippi + 0: iss + 0+ issippi + +/abc/\P +Failed: POSIX code 9: bad escape sequence at offset 4 + +/-- End of POSIX tests --/ + +/a\Cb/ + aXb + 0: aXb + a\nb + 0: a\x0ab + ** Failers (too big char) +No match + A\x{123}B +** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. +** Truncation will probably give the wrong result. +No match + +/\x{100}/I +Failed: character value in \x{...} sequence is too large at offset 6 + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: extended +No first char +No need char +Subject length lower bound = 3 +Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 + 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + +/-- Although this saved pattern was compiled with link-size=2, it does no harm +to run this test with other link sizes because it is going to generated a +"compiled in wrong mode" error as soon as it is loaded, so the link size does +not matter. --/ + +\x09< + 0: \x09 + +/[\h]+/BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0]+ + Ket + End +------------------------------------------------------------------ + >\x09\x20\xa0< + 0: \x09 \xa0 + +/[\v]/BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85] + Ket + End +------------------------------------------------------------------ + +/[\H]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] + Ket + End +------------------------------------------------------------------ + +/[^\h]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] (neg) + Ket + End +------------------------------------------------------------------ + +/[\V]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x86-\xff] + Ket + End +------------------------------------------------------------------ + +/[\x0a\V]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x0a\x0e-\x84\x86-\xff] + Ket + End +------------------------------------------------------------------ + +/\777/I +Failed: octal value is greater than \377 in 8-bit non-UTF-8 mode at offset 3 + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K +Failed: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) at offset 259 + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K + XX + 0: XX +MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE + +/\u0100/ +Failed: character value in \u.... sequence is too large at offset 5 + +/[\u0100-\u0200]/ +Failed: character value in \u.... sequence is too large at offset 6 + +/-- End of testinput14 --/ diff -Nru pcre3-8.12/testdata/testoutput15 pcre3-8.31/testdata/testoutput15 --- pcre3-8.12/testdata/testoutput15 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput15 2012-06-17 16:49:26.000000000 +0000 @@ -0,0 +1,1049 @@ +/-- This set of tests is for UTF-8 support, and is relevant only to the 8-bit + library. --/ + +/X(\C{3})/8 + X\x{1234} + 0: X\x{1234} + 1: \x{1234} + +/X(\C{4})/8 + X\x{1234}YZ + 0: X\x{1234}Y + 1: \x{1234}Y + +/X\C*/8 + XYZabcdce + 0: XYZabcdce + +/X\C*?/8 + XYZabcde + 0: X + +/X\C{3,5}/8 + Xabcdefg + 0: Xabcde + X\x{1234} + 0: X\x{1234} + X\x{1234}YZ + 0: X\x{1234}YZ + X\x{1234}\x{512} + 0: X\x{1234}\x{512} + X\x{1234}\x{512}YZ + 0: X\x{1234}\x{512} + +/X\C{3,5}?/8 + Xabcdefg + 0: Xabc + X\x{1234} + 0: X\x{1234} + X\x{1234}YZ + 0: X\x{1234} + X\x{1234}\x{512} + 0: X\x{1234} + +/a\Cb/8 + aXb + 0: aXb + a\nb + 0: a\x{0a}b + +/a\C\Cb/8 + a\x{100}b + 0: a\x{100}b + +/ab\Cde/8 + abXde + 0: abXde + +/a\C\Cb/8 + a\x{100}b + 0: a\x{100}b + ** Failers +No match + a\x{12257}b +No match + +/[Ã]/8 +Failed: invalid UTF-8 string at offset 1 + +/Ã/8 +Failed: invalid UTF-8 string at offset 0 + +/ÃÃÃxxx/8 +Failed: invalid UTF-8 string at offset 0 + +/ÃÃÃxxx/8?DZSS +------------------------------------------------------------------ + Bra + \X{c0}\X{c0}\X{c0}xxx + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf no_utf_check +First char = \x{c3} +Need char = 'x' + +/abc/8 + Ã] +Error -10 (bad UTF-8 string) offset=0 reason=6 + à +Error -10 (bad UTF-8 string) offset=0 reason=1 + ÃÃà +Error -10 (bad UTF-8 string) offset=0 reason=6 + ÃÃÃ\? +No match + \xe1\x88 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \P\xe1\x88 +Error -10 (bad UTF-8 string) offset=0 reason=1 + \P\P\xe1\x88 +Error -25 (short UTF-8 string) offset=0 reason=1 + XX\xea +Error -10 (bad UTF-8 string) offset=2 reason=2 + \O0XX\xea +Error -10 (bad UTF-8 string) + \O1XX\xea +Error -10 (bad UTF-8 string) + \O2XX\xea +Error -10 (bad UTF-8 string) offset=2 reason=2 + XX\xf1 +Error -10 (bad UTF-8 string) offset=2 reason=3 + XX\xf8 +Error -10 (bad UTF-8 string) offset=2 reason=4 + XX\xfc +Error -10 (bad UTF-8 string) offset=2 reason=5 + ZZ\xea\xaf\x20YY +Error -10 (bad UTF-8 string) offset=2 reason=7 + ZZ\xfd\xbf\xbf\x2f\xbf\xbfYY +Error -10 (bad UTF-8 string) offset=2 reason=8 + ZZ\xfd\xbf\xbf\xbf\x2f\xbfYY +Error -10 (bad UTF-8 string) offset=2 reason=9 + ZZ\xfd\xbf\xbf\xbf\xbf\x2fYY +Error -10 (bad UTF-8 string) offset=2 reason=10 + ZZ\xffYY +Error -10 (bad UTF-8 string) offset=2 reason=21 + ZZ\xfeYY +Error -10 (bad UTF-8 string) offset=2 reason=21 + +/anything/8 + \xc0\x80 +Error -10 (bad UTF-8 string) offset=0 reason=15 + \xc1\x8f +Error -10 (bad UTF-8 string) offset=0 reason=15 + \xe0\x9f\x80 +Error -10 (bad UTF-8 string) offset=0 reason=16 + \xf0\x8f\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=17 + \xf8\x87\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=18 + \xfc\x83\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=19 + \xfe\x80\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xff\x80\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=21 + \xc3\x8f +No match + \xe0\xaf\x80 +No match + \xe1\x80\x80 +No match + \xf0\x9f\x80\x80 +No match + \xf1\x8f\x80\x80 +No match + \xf8\x88\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=11 + \xf9\x87\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=11 + \xfc\x84\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=12 + \xfd\x83\x80\x80\x80\x80 +Error -10 (bad UTF-8 string) offset=0 reason=12 + \?\xf8\x88\x80\x80\x80 +No match + \?\xf9\x87\x80\x80\x80 +No match + \?\xfc\x84\x80\x80\x80\x80 +No match + \?\xfd\x83\x80\x80\x80\x80 +No match + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x{1000}/8DZ +------------------------------------------------------------------ + Bra + \x{1000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e1} +Need char = \x{80} + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f0} +Need char = \x{80} + +/\x{100000}/8DZ +------------------------------------------------------------------ + Bra + \x{100000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f4} +Need char = \x{80} + +/\x{10ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{10ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f4} +Need char = \x{bf} + +/[\x{ff}]/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x80/8DZ +------------------------------------------------------------------ + Bra + \x{80} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{80} + +/\xff/8DZ +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 +------------------------------------------------------------------ + Bra + \x{d55c}\x{ad6d}\x{c5b4} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ed} +Need char = \x{b4} + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 +------------------------------------------------------------------ + Bra + \x{65e5}\x{672c}\x{8a9e} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e6} +Need char = \x{9e} + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 +------------------------------------------------------------------ + Bra + \x{80} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{80} + +/\x{084}/DZ8 +------------------------------------------------------------------ + Bra + \x{84} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c2} +Need char = \x{84} + +/\x{104}/DZ8 +------------------------------------------------------------------ + Bra + \x{104} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{84} + +/\x{861}/DZ8 +------------------------------------------------------------------ + Bra + \x{861} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{e0} +Need char = \x{a1} + +/\x{212ab}/DZ8 +------------------------------------------------------------------ + Bra + \x{212ab} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{f0} +Need char = \x{ab} + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \x{e1} + 2: \x{88}\x{b4} + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers +No match + a\x{100}b +No match + +/[^ab\xC0-\xF0]/8SDZ +------------------------------------------------------------------ + Bra + [\x00-`c-\xbf\xf1-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SDZ +------------------------------------------------------------------ + Bra + \x{100}{3} + \x{100}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} +Subject length lower bound = 3 +No set of starting bytes + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}+ + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xc4 + +/(\x{100}*a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}*+ + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xc4 + +/(\x{100}{0,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}{0,2} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xc4 + +/(\x{100}{1,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100} + \x{100}{0,1} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xc4 + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/a\x{100}\x{101}*/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{80} + +/a\x{100}\x{101}+/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{81} + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\xc4] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\xff]/DZ8 +------------------------------------------------------------------ + Bra + \x{ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c3} +Need char = \x{bf} + >\x{ff}< + 0: \x{ff} + +/[^\xff]/8DZ +------------------------------------------------------------------ + Bra + [^\x{ff}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + \x{100}abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +First char = \x{c4} +Need char = 'z' + +/a\x{1234}b/P8 + a\x{1234}b + 0: a\x{1234}b + +/\777/8I +Capturing subpattern count = 0 +Options: utf +First char = \x{c7} +Need char = \x{bf} + \x{1ff} + 0: \x{1ff} + \777 + 0: \x{1ff} + +/\x{100}+\x{200}/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = \x{80} + +/\x{100}+X/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c4} +Need char = 'X' + +/^[\QÄ€\E-\QÅ\E/BZ8 +Failed: missing terminating ] for character class at offset 15 + +/-- This tests the stricter UTF-8 check according to RFC 3629. --/ + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} +No match + \x{d800} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{d800}\? +No match + \x{da00} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{da00}\? +No match + \x{dfff} +Error -10 (bad UTF-8 string) offset=0 reason=14 + \x{dfff}\? +No match + \x{110000} +Error -10 (bad UTF-8 string) offset=0 reason=13 + \x{110000}\? +No match + \x{2000000} +Error -10 (bad UTF-8 string) offset=0 reason=11 + \x{2000000}\? +No match + \x{7fffffff} +Error -10 (bad UTF-8 string) offset=0 reason=12 + \x{7fffffff}\? +No match + +/(*UTF8)\x{1234}/ + abcd\x{1234}pqr + 0: \x{1234} + +/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode utf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + +/\h/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3 + ABC\x{09} + 0: \x{09} + ABC\x{20} + 0: + ABC\x{a0} + 0: \x{a0} + ABC\x{1680} + 0: \x{1680} + ABC\x{180e} + 0: \x{180e} + ABC\x{2000} + 0: \x{2000} + ABC\x{202f} + 0: \x{202f} + ABC\x{205f} + 0: \x{205f} + ABC\x{3000} + 0: \x{3000} + +/\v/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + ABC\x{0a} + 0: \x{0a} + ABC\x{0b} + 0: \x{0b} + ABC\x{0c} + 0: \x{0c} + ABC\x{0d} + 0: \x{0d} + ABC\x{85} + 0: \x{85} + ABC\x{2028} + 0: \x{2028} + +/\h*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 + CDBABC + 0: A + +/\v+A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 2 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + +/\s?xxx\s/8SI +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: \x09 \x0a \x0c \x0d \x20 x + +/\sxxx\s/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 5 +Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2 + AB\x{85}xxx\x{a0}XYZ + 0: \x{85}xxx\x{a0} + AB\x{a0}xxx\x{85}XYZ + 0: \x{a0}xxx\x{85} + +/\S \S/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = ' ' +Subject length lower bound = 3 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e + \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d + \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc0 \xc1 \xc2 \xc3 + \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 + \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 + \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 + \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff + \x{a2} \x{84} + 0: \x{a2} \x{84} + A Z + 0: A Z + +/a+/8 + a\x{123}aa\>1 + 0: aa + a\x{123}aa\>2 +Error -11 (bad UTF-8 offset) + a\x{123}aa\>3 + 0: aa + a\x{123}aa\>4 + 0: a + a\x{123}aa\>5 +No match + a\x{123}aa\>6 +Error -24 (bad offset value) + +/\x{1234}+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \xe1 + +/\x{1234}{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 2 +Starting byte set: \xe1 + +/[^\x{c4}]/8DZ +------------------------------------------------------------------ + Bra + [^\x{c4}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/X+\x{200}/8DZ +------------------------------------------------------------------ + Bra + X++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'X' +Need char = \x{80} + +/\R/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 + +/\777/8DZ +------------------------------------------------------------------ + Bra + \x{1ff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{c7} +Need char = \x{bf} + +/\w+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \w++ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4} + +/\w+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \w+ + \x{c4} + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4}\x{c4} + +/\W+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \W++ + \x{c4} + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{A1}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/\W+\x{A1}/8BZT1 +------------------------------------------------------------------ + Bra + \W+ + \x{a1} + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/X\s+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + X + \s++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0} + +/X\s+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + X + \s+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0}\x{a0} + +/\S+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + \S+ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0}\x{a0} + +/\S+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + \S++ + \x{a0} + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0} + +/\x{a0}+\s!/8BZ +------------------------------------------------------------------ + Bra + \x{a0}++ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/\x{a0}+\s!/8BZT1 +------------------------------------------------------------------ + Bra + \x{a0}+ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/-- End of testinput15 --/ diff -Nru pcre3-8.12/testdata/testoutput16 pcre3-8.31/testdata/testoutput16 --- pcre3-8.12/testdata/testoutput16 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput16 2012-02-22 13:54:41.000000000 +0000 @@ -0,0 +1,121 @@ +/-- This set of tests is run only with the 8-bit library when Unicode property + support is available. It starts with tests of the POSIX interface, because + that is supported only with the 8-bit library. --/ + +/\w/P + +++\x{c2} +No match: POSIX code 17: match failed + +/\w/WP + +++\x{c2} + 0: \xc2 + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ +------------------------------------------------------------------ + Bra + /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +No need char + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{b0} + +/AB\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{b0} + +/AB\x{1fb0}/8DZi +------------------------------------------------------------------ + Bra + /i AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = 'B' (caseless) + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 17 +Starting byte set: \xd0 \xd1 + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i \x{2c65} + Ket + End +------------------------------------------------------------------ + +/[^â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i [^\x{2c65}] + Ket + End +------------------------------------------------------------------ + +/\h/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 + +/\v/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 + +/\R/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 + +/[[:blank:]]/WBZ +------------------------------------------------------------------ + Bra + [\x09 \xa0] + Ket + End +------------------------------------------------------------------ + +/-- End of testinput16 --/ diff -Nru pcre3-8.12/testdata/testoutput17 pcre3-8.31/testdata/testoutput17 --- pcre3-8.12/testdata/testoutput17 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput17 2012-06-17 16:50:26.000000000 +0000 @@ -0,0 +1,543 @@ +/-- This set of tests is for the 16-bit library's basic (non-UTF-16) features + that are not compatible with the 8-bit library, or which give different + output in 16-bit mode. --/ + +/a\Cb/ + aXb + 0: aXb + a\nb + 0: a\x0ab + +/-- Check maximum non-UTF character size --/ + +/\x{ffff}/ + A\x{ffff}B + 0: \x{ffff} + +/\x{10000}/ +Failed: character value in \x{...} sequence is too large at offset 8 + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\xc4] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + + +/\x{100}/I +Capturing subpattern count = 0 +No options +First char = \x{100} +No need char + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/xSI +Capturing subpattern count = 0 +Contains explicit CR or LF match +Options: extended +No first char +No need char +Subject length lower bound = 3 +Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 + 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xff + +/[\h]/BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + >\x09< + 0: \x09 + +/[\h]+/BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]+ + Ket + End +------------------------------------------------------------------ + >\x09\x20\xa0< + 0: \x09 \xa0 + +/[\v]/BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}] + Ket + End +------------------------------------------------------------------ + +/[\H]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\h]/BZ +------------------------------------------------------------------ + Bra + [^\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + +/[\V]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[\x0a\V]/BZ +------------------------------------------------------------------ + Bra + [\x00-\x0a\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/\h+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 \xff + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + 0: \x{200a}\xa0\x{2000} + +/[\h\x{dc00}]+/BZSI +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\xa0\x{2000} + 0: \x{200a}\xa0\x{2000} + +/\H+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + 0: \x9f\xa1\x{2fff}\x{3001} + +/[\H\x{d800}]+/BZSI +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}\x{d800}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001} + 0: \x9f\xa1\x{2fff}\x{3001} + +/\v+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/[\v\x{dc00}]+/BZSI +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/\V+/SI +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + 0: \x09\x0e\x84\x86 + +/[\V\x{d800}]+/BZSI +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}\x{d800}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86 + 0: \x09\x0e\x84\x86 + +/\R+/SI +Capturing subpattern count = 0 +Options: bsr_unicode +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d + 0: \x85\x0a\x0b\x0c\x0d + +/\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I +Capturing subpattern count = 0 +No options +First char = \x{d800} +Need char = \x{dd00} + \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} + 0: \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00} + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ +------------------------------------------------------------------ + Bra + [^\x80] + [^\xff] + [^\x{100}] + [^\x{1000}] + [^\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi +------------------------------------------------------------------ + Bra + /i [^\x80] + /i [^\xff] + /i [^\x{100}] + /i [^\x{1000}] + /i [^\x{ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ +------------------------------------------------------------------ + Bra + [^\x{100}]* + [^\x{1000}]+ + [^\x{ffff}]?? + [^\x{8000}]{4} + [^\x{8000}]* + [^\x{7fff}]{2} + [^\x{7fff}]{0,7}? + [^\x{100}]{5} + [^\x{100}]?+ + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}]* + /i [^\x{1000}]+ + /i [^\x{ffff}]?? + /i [^\x{8000}]{4} + /i [^\x{8000}]* + /i [^\x{7fff}]{2} + /i [^\x{7fff}]{0,7}? + Once + /i [^\x{100}]{5} + /i [^\x{100}]? + Ket + Ket + End +------------------------------------------------------------------ + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K + XX + 0: XX +MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF + +/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K + XX + 0: XX +MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE + +/\u0100/BZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ + +/[\u0100-\u0200]/BZ +------------------------------------------------------------------ + Bra + [\x{100}-\x{200}] + Ket + End +------------------------------------------------------------------ + +/\ud800/BZ +------------------------------------------------------------------ + Bra + \x{d800} + Ket + End +------------------------------------------------------------------ + +/-- End of testinput17 --/ diff -Nru pcre3-8.12/testdata/testoutput18 pcre3-8.31/testdata/testoutput18 --- pcre3-8.12/testdata/testoutput18 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput18 2012-07-06 08:52:55.000000000 +0000 @@ -0,0 +1,998 @@ +/-- This set of tests is for UTF-16 support, and is relevant only to the 16-bit + library. --/ + +/ÃÃÃxxx/8?DZSS +**Failed: invalid UTF-8 string cannot be converted to UTF-16 + +/abc/8 + Ã] +**Failed: invalid UTF-8 string cannot be converted to UTF-16 + +/X(\C{3})/8 + X\x{11234}Y + 0: X\x{11234}Y + 1: \x{11234}Y + +/X(\C{4})/8 + X\x{11234}YZ + 0: X\x{11234}YZ + 1: \x{11234}YZ + +/X\C*/8 + XYZabcdce + 0: XYZabcdce + +/X\C*?/8 + XYZabcde + 0: X + +/X\C{3,5}/8 + Xabcdefg + 0: Xabcde + X\x{11234}Y + 0: X\x{11234}Y + X\x{11234}YZ + 0: X\x{11234}YZ + X\x{11234}\x{512} + 0: X\x{11234}\x{512} + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512}YZ + X\x{11234}\x{512}\x{11234}Z + 0: X\x{11234}\x{512}\x{11234} + +/X\C{3,5}?/8 + Xabcdefg + 0: Xabc + X\x{11234}Y + 0: X\x{11234}Y + X\x{11234}YZ + 0: X\x{11234}Y + X\x{11234}\x{512}YZ + 0: X\x{11234}\x{512} + *** Failers +No match + X\x{11234} +No match + +/a\Cb/8 + aXb + 0: aXb + a\nb + 0: a\x{0a}b + +/a\C\Cb/8 + a\x{12257}b + 0: a\x{12257}b + ** Failers +No match + a\x{100}b +No match + +/ab\Cde/8 + abXde + 0: abXde + +/-- Check maximum character size --/ + +/\x{ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ffff} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d800} +Need char = \x{dc00} + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x{1000}/8DZ +------------------------------------------------------------------ + Bra + \x{1000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{1000} +No need char + +/\x{10000}/8DZ +------------------------------------------------------------------ + Bra + \x{10000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d800} +Need char = \x{dc00} + +/\x{100000}/8DZ +------------------------------------------------------------------ + Bra + \x{100000} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{dbc0} +Need char = \x{dc00} + +/\x{10ffff}/8DZ +------------------------------------------------------------------ + Bra + \x{10ffff} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{dbff} +Need char = \x{dfff} + +/[\x{ff}]/8DZ +------------------------------------------------------------------ + Bra + \xff + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/\x80/8DZ +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\xff/8DZ +------------------------------------------------------------------ + Bra + \xff + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + +/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 +------------------------------------------------------------------ + Bra + \x{d55c}\x{ad6d}\x{c5b4} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d55c} +Need char = \x{c5b4} + \x{D55c}\x{ad6d}\x{C5B4} + 0: \x{d55c}\x{ad6d}\x{c5b4} + +/\x{65e5}\x{672c}\x{8a9e}/DZ8 +------------------------------------------------------------------ + Bra + \x{65e5}\x{672c}\x{8a9e} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{65e5} +Need char = \x{8a9e} + \x{65e5}\x{672c}\x{8a9e} + 0: \x{65e5}\x{672c}\x{8a9e} + +/\x{80}/DZ8 +------------------------------------------------------------------ + Bra + \x80 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{80} +No need char + +/\x{084}/DZ8 +------------------------------------------------------------------ + Bra + \x84 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{84} +No need char + +/\x{104}/DZ8 +------------------------------------------------------------------ + Bra + \x{104} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{104} +No need char + +/\x{861}/DZ8 +------------------------------------------------------------------ + Bra + \x{861} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{861} +No need char + +/\x{212ab}/DZ8 +------------------------------------------------------------------ + Bra + \x{212ab} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{d844} +Need char = \x{deab} + +/-- This one is here not because it's different to Perl, but because the way +the captured single-byte is displayed. (In Perl it becomes a character, and you +can't tell the difference.) --/ + +/X(\C)(.*)/8 + X\x{1234} + 0: X\x{1234} + 1: \x{1234} + 2: + X\nabc + 0: X\x{0a}abc + 1: \x{0a} + 2: abc + +/-- This one is here because Perl gives out a grumbly error message (quite +correctly, but that messes up comparisons). --/ + +/a\Cb/8 + *** Failers +No match + a\x{100}b + 0: a\x{100}b + +/[^ab\xC0-\xF0]/8SDZ +------------------------------------------------------------------ + Bra + [\x00-`c-\xbf\xf1-\xff] (neg) + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a + \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 + \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 + 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y + Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f + \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e + \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d + \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac + \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb + \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb + \xfc \xfd \xfe \xff + \x{f1} + 0: \x{f1} + \x{bf} + 0: \x{bf} + \x{100} + 0: \x{100} + \x{1000} + 0: \x{1000} + *** Failers + 0: * + \x{c0} +No match + \x{f0} +No match + +/Ä€{3,4}/8SDZ +------------------------------------------------------------------ + Bra + \x{100}{3} + \x{100}? + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{100} +Subject length lower bound = 3 +No set of starting bytes + \x{100}\x{100}\x{100}\x{100\x{100} + 0: \x{100}\x{100}\x{100} + +/(\x{100}+|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}+ + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/(\x{100}*a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}*+ + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{0,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100}{0,2} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: a x \xff + +/(\x{100}{1,2}a|x)/8SDZ +------------------------------------------------------------------ + Bra + CBra 1 + \x{100} + \x{100}{0,1} + a + Alt + x + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: x \xff + +/\x{100}/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + +/a\x{100}\x{101}*/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}* + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{100} + +/a\x{100}\x{101}+/8DZ +------------------------------------------------------------------ + Bra + a\x{100} + \x{101}+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'a' +Need char = \x{101} + +/[^\x{c4}]/DZ +------------------------------------------------------------------ + Bra + [^\xc4] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char + +/[\x{100}]/8DZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +No need char + \x{100} + 0: \x{100} + Z\x{100} + 0: \x{100} + \x{100}Z + 0: \x{100} + *** Failers +No match + +/[\xff]/DZ8 +------------------------------------------------------------------ + Bra + \xff + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{ff} +No need char + >\x{ff}< + 0: \x{ff} + +/[^\xff]/8DZ +------------------------------------------------------------------ + Bra + [^\xff] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/\x{100}abc(xyz(?1))/8DZ +------------------------------------------------------------------ + Bra + \x{100}abc + CBra 1 + xyz + Recurse + Ket + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: utf +First char = \x{100} +Need char = 'z' + +/\777/8I +Capturing subpattern count = 0 +Options: utf +First char = \x{1ff} +No need char + \x{1ff} + 0: \x{1ff} + \777 + 0: \x{1ff} + +/\x{100}+\x{200}/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = \x{200} + +/\x{100}+X/8DZ +------------------------------------------------------------------ + Bra + \x{100}++ + X + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = \x{100} +Need char = 'X' + +/^[\QÄ€\E-\QÅ\E/BZ8 +Failed: missing terminating ] for character class at offset 13 + +/X/8 + \x{0}\x{d7ff}\x{e000}\x{10ffff} +No match + \x{d800} +Error -10 (bad UTF-16 string) offset=0 reason=1 + \x{d800}\? +No match + \x{da00} +Error -10 (bad UTF-16 string) offset=0 reason=1 + \x{da00}\? +No match + \x{dc00} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{dc00}\? +No match + \x{de00} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{de00}\? +No match + \x{dfff} +Error -10 (bad UTF-16 string) offset=0 reason=3 + \x{dfff}\? +No match + \x{110000} +**Failed: character value greater than 0x10ffff cannot be converted to UTF-16 + \x{d800}\x{1234} +Error -10 (bad UTF-16 string) offset=1 reason=2 + \x{fffe} +Error -10 (bad UTF-16 string) offset=0 reason=4 + +/(*UTF16)\x{11234}/ + abcd\x{11234}pqr + 0: \x{11234} + +/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I +Capturing subpattern count = 0 +Options: bsr_unicode utf +Forced newline sequence: CRLF +First char = 'a' +Need char = 'b' + +/\h/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x09 \x20 \xa0 \xff + ABC\x{09} + 0: \x{09} + ABC\x{20} + 0: + ABC\x{a0} + 0: \x{a0} + ABC\x{1680} + 0: \x{1680} + ABC\x{180e} + 0: \x{180e} + ABC\x{2000} + 0: \x{2000} + ABC\x{202f} + 0: \x{202f} + ABC\x{205f} + 0: \x{205f} + ABC\x{3000} + 0: \x{3000} + +/\v/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + ABC\x{0a} + 0: \x{0a} + ABC\x{0b} + 0: \x{0b} + ABC\x{0c} + 0: \x{0c} + ABC\x{0d} + 0: \x{0d} + ABC\x{85} + 0: \x{85} + ABC\x{2028} + 0: \x{2028} + +/\h*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x09 \x20 A \xa0 \xff + CDBABC + 0: A + \x{2000}ABC + 0: \x{2000}A + +/\R*A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff + CDBABC + 0: A + \x{2028}A + 0: \x{2028}A + +/\v+A/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'A' +Subject length lower bound = 2 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/\s?xxx\s/8SI +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: \x09 \x0a \x0c \x0d \x20 x + +/\sxxx\s/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = 'x' +Subject length lower bound = 5 +Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0 + AB\x{85}xxx\x{a0}XYZ + 0: \x{85}xxx\x{a0} + AB\x{a0}xxx\x{85}XYZ + 0: \x{a0}xxx\x{85} + +/\S \S/I8ST1 +Capturing subpattern count = 0 +Options: utf +No first char +Need char = ' ' +Subject length lower bound = 3 +Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e + \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d + \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e + f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 + \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 + \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3 + \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 + \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 + \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 + \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf + \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee + \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd + \xfe \xff + \x{a2} \x{84} + 0: \x{a2} \x{84} + A Z + 0: A Z + +/a+/8 + a\x{123}aa\>1 + 0: aa + a\x{123}aa\>2 + 0: aa + a\x{123}aa\>3 + 0: a + a\x{123}aa\>4 +No match + a\x{123}aa\>5 +Error -24 (bad offset value) + a\x{123}aa\>6 +Error -24 (bad offset value) + +/\x{1234}+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +No need char +Subject length lower bound = 1 +No set of starting bytes + +/\x{1234}{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{1234} +Need char = \x{1234} +Subject length lower bound = 2 +No set of starting bytes + +/[^\x{c4}]/8DZ +------------------------------------------------------------------ + Bra + [^\xc4] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + +/X+\x{200}/8DZ +------------------------------------------------------------------ + Bra + X++ + \x{200} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'X' +Need char = \x{200} + +/\R/SI8 +Capturing subpattern count = 0 +Options: utf +No first char +No need char +Subject length lower bound = 1 +Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff + +/-- Check bad offset --/ + +/a/8 + \x{10000}\>1 +Error -11 (bad UTF-16 offset) + \x{10000}ab\>2 + 0: a + \x{10000}ab\>3 +No match + \x{10000}ab\>4 +No match + \x{10000}ab\>5 +Error -24 (bad offset value) + +/í¼€/8 +Failed: invalid UTF-16 string at offset 0 + +/\w+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \w++ + \xc4 + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4} + +/\w+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \w+ + \xc4 + Ket + End +------------------------------------------------------------------ + a\x{C4}\x{C4} + 0: a\x{c4}\x{c4} + +/\W+\x{C4}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \xc4 + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{C4}/8BZT1 +------------------------------------------------------------------ + Bra + \W++ + \xc4 + Ket + End +------------------------------------------------------------------ + !\x{C4} + 0: !\x{c4} + +/\W+\x{A1}/8BZ +------------------------------------------------------------------ + Bra + \W+ + \xa1 + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/\W+\x{A1}/8BZT1 +------------------------------------------------------------------ + Bra + \W+ + \xa1 + Ket + End +------------------------------------------------------------------ + !\x{A1} + 0: !\x{a1} + +/X\s+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + X + \s++ + \xa0 + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0} + +/X\s+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + X + \s+ + \xa0 + Ket + End +------------------------------------------------------------------ + X\x20\x{A0}\x{A0} + 0: X \x{a0}\x{a0} + +/\S+\x{A0}/8BZ +------------------------------------------------------------------ + Bra + \S+ + \xa0 + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0}\x{a0} + +/\S+\x{A0}/8BZT1 +------------------------------------------------------------------ + Bra + \S++ + \xa0 + Ket + End +------------------------------------------------------------------ + X\x{A0}\x{A0} + 0: X\x{a0} + +/\x{a0}+\s!/8BZ +------------------------------------------------------------------ + Bra + \xa0++ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/\x{a0}+\s!/8BZT1 +------------------------------------------------------------------ + Bra + \xa0+ + \s + ! + Ket + End +------------------------------------------------------------------ + \x{a0}\x20! + 0: \x{a0} ! + +/-- End of testinput18 --/ diff -Nru pcre3-8.12/testdata/testoutput19 pcre3-8.31/testdata/testoutput19 --- pcre3-8.12/testdata/testoutput19 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput19 2011-12-28 16:57:52.000000000 +0000 @@ -0,0 +1,88 @@ +/-- This set of tests is for Unicode property support, relevant only to the + 16-bit library. --/ + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ +------------------------------------------------------------------ + Bra + /i A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = \x{1fb0} (caseless) + +/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + A\x{391}\x{10427}\x{ff3a}\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{1fb0} + +/AB\x{1fb0}/8DZ +------------------------------------------------------------------ + Bra + AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +First char = 'A' +Need char = \x{1fb0} + +/AB\x{1fb0}/8DZi +------------------------------------------------------------------ + Bra + /i AB\x{1fb0} + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +First char = 'A' (caseless) +Need char = \x{1fb0} (caseless) + +/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI +Capturing subpattern count = 0 +Options: caseless utf +First char = \x{401} (caseless) +Need char = \x{42f} (caseless) +Subject length lower bound = 17 +No set of starting bytes + \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f} + \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f} + +/[â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i \x{2c65} + Ket + End +------------------------------------------------------------------ + +/[^â±¥]/8iBZ +------------------------------------------------------------------ + Bra + /i [^\x{2c65}] + Ket + End +------------------------------------------------------------------ + +/[[:blank:]]/WBZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}] + Ket + End +------------------------------------------------------------------ + +/-- End of testinput19 --/ diff -Nru pcre3-8.12/testdata/testoutput2 pcre3-8.31/testdata/testoutput2 --- pcre3-8.12/testdata/testoutput2 2010-11-23 15:27:30.000000000 +0000 +++ pcre3-8.31/testdata/testoutput2 2012-06-01 17:53:58.000000000 +0000 @@ -3,12 +3,11 @@ It also checks the non-Perl syntax the PCRE supports (Python, .NET, Oniguruma). Finally, there are some tests where PCRE and Perl differ, either because PCRE can't be compatible, or there is a possible Perl - bug. --/ + bug. + + NOTE: This is a non-UTF set of tests. When UTF support is needed, use + test 5, and if Unicode Property Support is needed, use test 7. --/ -/-- Originally, the Perl >= 5.10 things were in here too, but now I have - separated many (most?) of them out into test 11. However, there may still - be some that were overlooked. --/ - /(a)b|/I Capturing subpattern count = 1 No options @@ -377,61 +376,6 @@ 2: 3: def -/abc/P - abc - 0: abc - *** Failers -No match: POSIX code 17: match failed - -/^abc|def/P - abcdef - 0: abc - abcdef\B - 0: def - -/.*((abc)$|(def))/P - defabc - 0: defabc - 1: abc - 2: abc - \Zdefabc - 0: def - 1: def - 3: def - -/the quick brown fox/P - the quick brown fox - 0: the quick brown fox - *** Failers -No match: POSIX code 17: match failed - The Quick Brown Fox -No match: POSIX code 17: match failed - -/the quick brown fox/Pi - the quick brown fox - 0: the quick brown fox - The Quick Brown Fox - 0: The Quick Brown Fox - -/abc.def/P - *** Failers -No match: POSIX code 17: match failed - abc\ndef -No match: POSIX code 17: match failed - -/abc$/P - abc - 0: abc - abc\n - 0: abc - -/(abc)\2/P -Failed: POSIX code 15: bad back reference at offset 7 - -/(abc\1)/P - abc -No match: POSIX code 17: match failed - /)/ Failed: unmatched parentheses at offset 0 @@ -507,6 +451,7 @@ No options First char = 'f' Need char = 'o' +Max lookbehind = 6 foo 0: foo catfoo @@ -632,10 +577,8 @@ ------------------------------------------------------------------ Bra CBra 1 - 01 Opt - NC b + /i b Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -716,6 +659,7 @@ No options No first char No need char +Max lookbehind = 3 Subject length lower bound = 1 Starting byte set: a b @@ -724,6 +668,7 @@ No options No first char Need char = 'a' +Max lookbehind = 3 Subject length lower bound = 5 Starting byte set: a o @@ -741,6 +686,7 @@ Options: multiline No first char Need char = 'r' +Max lookbehind = 4 foo\nbarbar 0: bar ***Failers @@ -758,6 +704,7 @@ Options: multiline First char at start or follows newline Need char = 'r' +Max lookbehind = 4 foo\nbarbar 0: bar ***Failers @@ -799,6 +746,7 @@ No options First char = '-' Need char = 't' +Max lookbehind = 7 the bullock-cart 0: -cart a donkey-cart race @@ -815,12 +763,14 @@ No options No first char No need char +Max lookbehind = 3 /(?>.*)(?<=(abcd)|(xyz))/I Capturing subpattern count = 2 No options First char at start or follows newline No need char +Max lookbehind = 4 alphabetabcd 0: alphabetabcd 1: abcd @@ -834,6 +784,7 @@ No options First char = 'Z' Need char = 'Z' +Max lookbehind = 4 abxyZZ 0: ZZ abXyZZ @@ -862,6 +813,7 @@ No options First char = 'b' Need char = 'r' +Max lookbehind = 4 bar 0: bar foobbar @@ -1033,9 +985,6 @@ /abc/\ Failed: \ at end of pattern at offset 4 -/abc/\P -Failed: POSIX code 9: bad escape sequence at offset 4 - /abc/\i Failed: \ at end of pattern at offset 4 @@ -1151,7 +1100,7 @@ No need char abc\00def\L\C0 0: abc\x00def - 0C abc (7) + 0C abc\x00def (7) 0L abc /word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ @@ -1247,15 +1196,12 @@ ------------------------------------------------------------------ Bra Bra - 04 Opt AllAny* X Alt - 04 Opt ^ B Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -1269,11 +1215,7 @@ No options First char = 'i' Need char = 's' - Mississippi - 0: iss - 0+ issippi - -/\Biss\B/I+P +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1294,6 +1236,7 @@ No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1303,6 +1246,7 @@ No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1318,6 +1262,7 @@ No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1329,6 +1274,7 @@ No options First char = 'i' Need char = 's' +Max lookbehind = 1 Mississippi 0: iss 0+ issippi @@ -1407,7 +1353,7 @@ Contains explicit CR or LF match Options: multiline First char at start or follows newline -Need char = 10 +Need char = \x0a ab\nab\ncd 0: ab\x0a 0+ ab\x0acd @@ -1509,6 +1455,7 @@ No options No first char No need char +Max lookbehind = 3 /abc(?!pqr)/I Capturing subpattern count = 0 @@ -1694,33 +1641,6 @@ \Nabc No match -/a*(b+)(z)(z)/P - aaaabbbbzzzz - 0: aaaabbbbzz - 1: bbbb - 2: z - 3: z - aaaabbbbzzzz\O0 - aaaabbbbzzzz\O1 - 0: aaaabbbbzz - aaaabbbbzzzz\O2 - 0: aaaabbbbzz - 1: bbbb - aaaabbbbzzzz\O3 - 0: aaaabbbbzz - 1: bbbb - 2: z - aaaabbbbzzzz\O4 - 0: aaaabbbbzz - 1: bbbb - 2: z - 3: z - aaaabbbbzzzz\O5 - 0: aaaabbbbzz - 1: bbbb - 2: z - 3: z - /^.?abcd/IS Capturing subpattern count = 0 Options: anchored @@ -2764,8 +2684,7 @@ ------------------------------------------------------------------ Bra a - 01 Opt - NC b + /i b Ket End ------------------------------------------------------------------ @@ -2787,10 +2706,8 @@ Bra CBra 1 a - 01 Opt - NC b + /i b Ket - 00 Opt Ket End ------------------------------------------------------------------ @@ -2812,7 +2729,7 @@ / (?i)abc/IxDZ ------------------------------------------------------------------ Bra - NC abc + /i abc Ket End ------------------------------------------------------------------ @@ -2825,7 +2742,7 @@ (?i)abc/IxDZ ------------------------------------------------------------------ Bra - NC abc + /i abc Ket End ------------------------------------------------------------------ @@ -2998,12 +2915,10 @@ /(x)*+/DZ ------------------------------------------------------------------ Bra - Once - Brazero - CBra 1 + Braposzero + CBraPos 1 x - KetRmax - Ket + KetRpos Ket End ------------------------------------------------------------------ @@ -3321,6 +3236,7 @@ No options First char = '8' Need char = 'X' +Max lookbehind = 1 |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ ------------------------------------------------------------------ @@ -3334,6 +3250,7 @@ No options First char = '$' Need char = 'X' +Max lookbehind = 1 /(.*)\d+\1/I Capturing subpattern count = 1 @@ -3590,7 +3507,27 @@ 1 ^ ^ f 0: abcdef -/(?C1)\dabc(?C2)def/I +/(?C1)\dabc(?C2)def/IS +Capturing subpattern count = 0 +No options +No first char +Need char = 'f' +Subject length lower bound = 7 +Starting byte set: 0 1 2 3 4 5 6 7 8 9 + 1234abcdef +--->1234abcdef + 1 ^ \d + 1 ^ \d + 1 ^ \d + 1 ^ \d + 2 ^ ^ d + 0: 4abcdef + *** Failers +No match + abcdef +No match + +/(?C1)\dabc(?C2)def/ISS Capturing subpattern count = 0 No options No first char @@ -3829,6 +3766,7 @@ No options First char = 'x' Need char = 'z' +Max lookbehind = 3 abcxyz\C+ Callout 0: last capture = 1 0: @@ -3994,9 +3932,7 @@ Bra CBra 1 a - Once Recurse - Ket b Ket Ket @@ -4217,9 +4153,7 @@ Any \1 bbb - Once Recurse - Ket d Ket End @@ -4591,9 +4525,7 @@ a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4613,9 +4545,7 @@ a CBra 2 b - Once Recurse - Ket c Ket KetRmax @@ -4636,9 +4566,7 @@ a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4647,9 +4575,7 @@ a CBra 2 b - Once Recurse - Ket c Ket Ket @@ -4788,7 +4714,51 @@ +4 ^ ^ e No match -/a*b/ICDZ +/a*b/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 2 + a*+ + Callout 255 2 1 + b + Callout 255 3 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: +No first char +Need char = 'b' +Subject length lower bound = 1 +Starting byte set: a b + ab +--->ab + +0 ^ a* + +2 ^^ b + +3 ^ ^ + 0: ab + aaaab +--->aaaab + +0 ^ a* + +2 ^ ^ b + +3 ^ ^ + 0: aaaab + aaaacb +--->aaaacb + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^ ^ b + +0 ^ a* + +2 ^^ b + +0 ^ a* + +2 ^ b + +3 ^^ + 0: b + +/a*b/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 2 @@ -4871,7 +4841,83 @@ +2 ^^ b No match -/(abc|def)x/ICDZ +/(abc|def)x/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 9 + CBra 1 + Callout 255 1 1 + a + Callout 255 2 1 + b + Callout 255 3 1 + c + Callout 255 4 0 + Alt + Callout 255 5 1 + d + Callout 255 6 1 + e + Callout 255 7 1 + f + Callout 255 8 0 + Ket + Callout 255 9 1 + x + Callout 255 10 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +Need char = 'x' +Subject length lower bound = 4 +Starting byte set: a d + abcx +--->abcx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x ++10 ^ ^ + 0: abcx + 1: abc + defx +--->defx + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x ++10 ^ ^ + 0: defx + 1: def + ** Failers +No match + abcdefzx +--->abcdefzx + +0 ^ (abc|def) + +1 ^ a + +2 ^^ b + +3 ^ ^ c + +4 ^ ^ | + +9 ^ ^ x + +5 ^ d + +0 ^ (abc|def) + +1 ^ a + +5 ^ d + +6 ^^ e + +7 ^ ^ f + +8 ^ ^ ) + +9 ^ ^ x +No match + +/(abc|def)x/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 9 @@ -4925,6 +4971,8 @@ +10 ^ ^ 0: defx 1: def + ** Failers +No match abcdefzx --->abcdefzx +0 ^ (abc|def) @@ -5025,7 +5073,58 @@ 0: abcdcdcd 1: cd -/([ab]{,4}c|xy)/ICDZ +/([ab]{,4}c|xy)/ICDZS +------------------------------------------------------------------ + Bra + Callout 255 0 14 + CBra 1 + Callout 255 1 4 + [ab] + Callout 255 5 1 + { + Callout 255 6 1 + , + Callout 255 7 1 + 4 + Callout 255 8 1 + } + Callout 255 9 1 + c + Callout 255 10 0 + Alt + Callout 255 11 1 + x + Callout 255 12 1 + y + Callout 255 13 0 + Ket + Callout 255 14 0 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +Options: +No first char +No need char +Subject length lower bound = 2 +Starting byte set: a b x + Note: that { does NOT introduce a quantifier +--->Note: that { does NOT introduce a quantifier + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x + +0 ^ ([ab]{,4}c|xy) + +1 ^ [ab] + +5 ^^ { ++11 ^ x +No match + +/([ab]{,4}c|xy)/ICDZSS ------------------------------------------------------------------ Bra Callout 255 0 14 @@ -5315,6 +5414,7 @@ No options No first char No need char +Max lookbehind = 1 ab cd\>1 0: cd @@ -5323,6 +5423,7 @@ Options: dotall No first char No need char +Max lookbehind = 1 ab cd\>1 0: cd @@ -5477,15 +5578,18 @@ 123456\P No match -/abc/I>testsavedregex +/abc/IS>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' -Compiled regex written to testsavedregex +Subject length lower bound = 3 +No set of starting bytes +Compiled pattern written to testsavedregex +Study data written to testsavedregex testsavedregex +/abc/ISS>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' -Compiled regex written to testsavedregex +Compiled pattern written to testsavedregex testsavedregex -Capturing subpattern count = 1 +/abc/IFS>testsavedregex +Capturing subpattern count = 0 No options -No first char +First char = 'a' +Need char = 'c' +Subject length lower bound = 3 +No set of starting bytes +Compiled pattern written to testsavedregex +Study data written to testsavedregex +testsavedregex +Capturing subpattern count = 0 +No options +First char = 'a' +Need char = 'c' +Compiled pattern written to testsavedregex +testsavedregex +Capturing subpattern count = 1 +No options +No first char No need char Subject length lower bound = 1 Starting byte set: a b -Compiled regex written to testsavedregex +Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Compiled pattern written to testsavedregex +testsavedregex Capturing subpattern count = 1 No options @@ -5537,10 +5694,10 @@ No need char Subject length lower bound = 1 Starting byte set: a b -Compiled regex written to testsavedregex +Compiled pattern written to testsavedregex Study data written to testsavedregex testsavedregex +Capturing subpattern count = 1 +No options +No first char +No need char +Compiled pattern written to testsavedregex +(.)*~smgI Capturing subpattern count = 3 Max back reference = 1 Options: multiline dotall First char = '<' Need char = '>' - \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n + \J1024\n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n 0: \x0a\x0aPartner der LCO\x0ade\x0aPartner der LINEAS Consulting\x0aGmbH\x0aLINEAS Consulting GmbH Hamburg\x0aPartnerfirmen\x0a30 days\x0aindex,follow\x0a\x0aja\x0a3\x0aPartner\x0a\x0a\x0aLCO\x0aLINEAS Consulting\x0a15.10.2003\x0a\x0a\x0a\x0a\x0aDie Partnerfirmen der LINEAS Consulting\x0aGmbH\x0a\x0a\x0a \x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a 1: seite 2: \x0a @@ -5606,24 +5781,6 @@ line one\nthis is a line\nbreak in the second line No match -/ab.cd/P - ab-cd - 0: ab-cd - ab=cd - 0: ab=cd - ** Failers -No match: POSIX code 17: match failed - ab\ncd -No match: POSIX code 17: match failed - -/ab.cd/Ps - ab-cd - 0: ab-cd - ab=cd - 0: ab=cd - ab\ncd - 0: ab\x0acd - /(?i)(?-i)AbCd/I Capturing subpattern count = 0 No options @@ -5916,21 +6073,10 @@ ((this)) 0: ((this)) -/a(b)c/PN - abc -Matched with REG_NOSUB - -/a(?Pb)c/PN - abc -Matched with REG_NOSUB - -/\x{100}/I -Failed: character value in \x{...} sequence is too large at offset 6 - /\x{0000ff}/I Capturing subpattern count = 0 No options -First char = 255 +First char = \xff No need char /^((?Pa1)|(?Pa2)b)/I @@ -6040,7 +6186,7 @@ 0: a1 1: a1 2: a1 -copy substring Z failed -7 +get substring Z failed -7 G a1 (2) A /^(?Pa)(?Pb)/IJ @@ -6072,7 +6218,7 @@ G a (1) A cd\GA 0: cd -copy substring A failed -7 +get substring A failed -7 /^(?Pa)(?Pb)|cd(?Pef)(?Pgh)/IJ Capturing subpattern count = 4 @@ -6240,9 +6386,6 @@ 9: 10: Y -/\777/I -Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3 - /\s*,\s*/IS Capturing subpattern count = 0 No options @@ -6674,8 +6817,8 @@ ------------------------------------------------------------------ Bra ^ - a* - NC A + /i a* + /i A \d Ket End @@ -7303,8 +7446,8 @@ /[^a]+a/BZi ------------------------------------------------------------------ Bra - [^A]++ - NC a + /i [^a]++ + /i a Ket End ------------------------------------------------------------------ @@ -7312,8 +7455,8 @@ /[^a]+A/BZi ------------------------------------------------------------------ Bra - [^A]++ - NC A + /i [^a]++ + /i A Ket End ------------------------------------------------------------------ @@ -7508,9 +7651,7 @@ ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket [()] CBra 1 Ket @@ -7544,9 +7685,7 @@ ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket () CBra 1 Ket @@ -7558,9 +7697,7 @@ ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket [(\]a] CBra 1 Ket @@ -7573,9 +7710,7 @@ ------------------------------------------------------------------ Bra ^ - Once Recurse - Ket CBra 1 Ket Ket @@ -7707,9 +7842,6 @@ First char = 'x' Need char = 'z' -/(?(DEFINE) abc){3} xyz/x -Failed: repeating a DEFINE group is not allowed at offset 17 - /(a|)*\d/ \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match @@ -8027,10 +8159,8 @@ Alt c Ket - Once Recurse Ket - Ket End ------------------------------------------------------------------ abc @@ -8041,9 +8171,7 @@ ------------------------------------------------------------------ Bra xy - Once Recurse - Ket CBra 1 abc Ket @@ -8273,66 +8401,6 @@ 3: 4: x -/[\h]/BZ ------------------------------------------------------------------- - Bra - [\x09 \xa0] - Ket - End ------------------------------------------------------------------- - >\x09< - 0: \x09 - -/[\h]+/BZ ------------------------------------------------------------------- - Bra - [\x09 \xa0]+ - Ket - End ------------------------------------------------------------------- - >\x09\x20\xa0< - 0: \x09 \xa0 - -/[\v]/BZ ------------------------------------------------------------------- - Bra - [\x0a-\x0d\x85] - Ket - End ------------------------------------------------------------------- - -/[\H]/BZ ------------------------------------------------------------------- - Bra - [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] - Ket - End ------------------------------------------------------------------- - -/[^\h]/BZ ------------------------------------------------------------------- - Bra - [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] (neg) - Ket - End ------------------------------------------------------------------- - -/[\V]/BZ ------------------------------------------------------------------- - Bra - [\x00-\x09\x0e-\x84\x86-\xff] - Ket - End ------------------------------------------------------------------- - -/[\x0a\V]/BZ ------------------------------------------------------------------- - Bra - [\x00-\x0a\x0e-\x84\x86-\xff] - Ket - End ------------------------------------------------------------------- - /\H++X/BZ ------------------------------------------------------------------ Bra @@ -8524,7 +8592,7 @@ ------------------------------------------------------------------ /\( (?: [^()]* | (?R) )* \)/x -(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) +\J1024(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) 0: (0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(0(00)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0)0) /[\E]AAA/ @@ -8706,8 +8774,13 @@ /\g6666666666/ Failed: number is too big at offset 11 -/[\g6666666666]/ -Failed: number is too big at offset 12 +/[\g6666666666]/BZ +------------------------------------------------------------------ + Bra + [6g] + Ket + End +------------------------------------------------------------------ /(?1)\c[/ Failed: reference to non-existent subpattern at offset 3 @@ -9013,6 +9086,12 @@ /\k{}/ Failed: subpattern name expected at offset 3 +/\k/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2 + +/\kabc/ +Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5 + /(?P=)/ Failed: subpattern name expected at offset 4 @@ -9234,14 +9313,6 @@ First char at start or follows newline No need char -/a?|b?/P - abc - 0: a - ** Failers - 0: - ddd\N -No match: POSIX code 17: match failed - /xyz/C xyz --->xyz @@ -9636,14 +9707,6 @@ abc\P\P 0: abc -/\w+A/P - CDAAAAB - 0: CDAAAA - -/\w+A/PU - CDAAAAB - 0: CDA - /abc\K123/ xyzabc123pqr 0: 123 @@ -9671,12 +9734,8 @@ /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra - Once Recurse - Ket - Once Recurse - Ket Cond Cond def CBra 1 @@ -9697,12 +9756,8 @@ /(?&word)(?&element)(?(DEFINE)(?<[^\d][^>]>[^<])(?\w*+))/BZ ------------------------------------------------------------------ Bra - Once Recurse - Ket - Once Recurse - Ket Cond Cond def CBra 1 @@ -10044,210 +10099,6 @@ Subject length lower bound = 22 No set of starting bytes -/ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional leading comment -(?: (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # one word, optionally followed by.... -(?: -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... -\( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) | # comments, or... - -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -# quoted strings -)* -< (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # leading < -(?: @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* - -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* , (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -)* # further okay, if led by comma -: # closing colon -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* )? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address spec -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* > # trailing > -# name and address -) (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional trailing comment -/xSI -Capturing subpattern count = 0 -Contains explicit CR or LF match -Options: extended -No first char -No need char -Subject length lower bound = 3 -Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8 - 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e - f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f - /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS Capturing subpattern count = 11 Options: caseless dotall @@ -10443,12 +10294,10 @@ Cond nrecurse 1 $ Alt - Once Recurse Ket Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 4 @@ -10586,11 +10435,9 @@ /(?i)a(?-i)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 00 Opt + /i a b Alt - 00 Opt c Ket End @@ -10609,12 +10456,9 @@ /(?i)a(?s)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 05 Opt - NC b + /i ab Alt - 05 Opt - NC c + /i c Ket End ------------------------------------------------------------------ @@ -10622,11 +10466,9 @@ /(?i)a(?s-i)b|c/BZ ------------------------------------------------------------------ Bra - NC a - 04 Opt + /i a b Alt - 04 Opt c Ket End @@ -10673,12 +10515,10 @@ ------------------------------------------------------------------ Bra ^ - Once - Brazero - Once + Braposzero + SBraPos Recurse - KetRmax - Ket + KetRpos Cond Cond def CBra 1 @@ -10767,152 +10607,22 @@ AC No match -/--- A whole lot of tests of verbs with arguments are here rather than in test - 11 because Perl doesn't seem to follow its specification entirely - correctly. ---/ - -/--- Perl 5.11 sets $REGERROR on the AC failure case here; PCRE does not. It is - not clear how Perl defines "involved in the failure of the match". ---/ - -/^(A(*THEN:A)B|C(*THEN:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match - CB -No match, mark = B - -/--- Check the use of names for success and failure. PCRE doesn't show these -names for success, though Perl does, contrary to its spec. ---/ - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match, mark = A - CB -No match, mark = B - -/--- An empty name does not pass back an empty string. It is the same as if no -name were given. ---/ - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/K - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - -/--- PRUNE goes to next bumpalong; COMMIT does not. ---/ - -/A(*PRUNE:A)B/K - ACAB - 0: AB - -/(*MARK:A)(*PRUNE:B)(C|X)/K - C - 0: C - 1: C -MK: A - D -No match, mark = B - -/(*MARK:A)(*THEN:B)(C|X)/K - C - 0: C - 1: C -MK: A - D -No match, mark = B - -/--- This should fail, as the skip causes a bump to offset 3 (the skip) ---/ - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xK - AAAC -No match - -/--- Same --/ - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xK - AAAC -No match - /--- This should fail; the SKIP advances by one, but when we get to AC, the - PRUNE kills it. ---/ + PRUNE kills it. Perl behaves differently. ---/ /A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK AAAC -No match - -/A(*:A)A+(*SKIP)(B|Z) | AC/xK - AAAC -No match - -/--- This should fail, as a null name is the same as no name ---/ - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xK - AAAC -No match - -/--- This fails in PCRE, and I think that is in accordance with Perl's - documentation, though in Perl it succeeds. ---/ - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xK - AAAC -No match +No match, mark = A -/--- Mark names can be duplicated ---/ +/--- Mark names can be duplicated. Perl doesn't give a mark for this one, +though PCRE does. ---/ -/A(*:A)B|X(*:A)Y/K - AABC - 0: AB -MK: A - XXYZ - 0: XY -MK: A - /^A(*:A)B|^X(*:A)Y/K ** Failers No match XAQQ No match, mark = A -/--- A check on what happens after hitting a mark and them bumping along to -something that does not even start. Perl reports tags after the failures here, -though it does not when the individual letters are made into something -more complicated. ---/ - -/A(*:A)B|XX(*:B)Y/K - AABC - 0: AB -MK: A - XXYZ - 0: XXY -MK: B - ** Failers -No match - XAQQ -No match - XAQQXZZ -No match - AXQQQ -No match - AXXQQQ -No match - /--- COMMIT at the start of a pattern should be the same as an anchor. Perl optimizations defeat this. So does the PCRE optimization unless we disable it with \Y. ---/ @@ -10925,132 +10635,12 @@ DEFGABC\Y No match -/--- Repeat some tests with added studying. ---/ - -/A(*COMMIT)B/+KS - ACABX +/^(ab (c+(*THEN)cd) | xyz)/x + abcccd No match - -/A(*THEN)B|A(*THEN)C/KS - AC - 0: AC -/A(*PRUNE)B|A(*PRUNE)C/KS - AC -No match - -/^(A(*THEN:A)B|C(*THEN:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match - CB -No match, mark = B - -/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - ** Failers -No match - AC -No match, mark = A - CB -No match, mark = B - -/^(A(*PRUNE:)B|C(*PRUNE:B)D)/KS - AB - 0: AB - 1: AB - CD - 0: CD - 1: CD - -/A(*PRUNE:A)B/KS - ACAB - 0: AB - -/(*MARK:A)(*PRUNE:B)(C|X)/KS - C - 0: C - 1: C -MK: A - D -No match - -/(*MARK:A)(*THEN:B)(C|X)/KS - C - 0: C - 1: C -MK: A - D -No match - -/A(*MARK:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*MARK:B)(*SKIP:B)(B|Z) | AC/xKS - AAAC -No match - -/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xKS - AAAC -No match - -/A(*:A)A+(*SKIP)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*SKIP:)(B|Z) | AC/xKS - AAAC -No match - -/A(*MARK:A)A+(*SKIP:B)(B|Z) | AAC/xKS - AAAC -No match - -/A(*:A)B|XX(*:B)Y/KS - AABC - 0: AB -MK: A - XXYZ - 0: XXY -MK: B - ** Failers -No match - XAQQ -No match - XAQQXZZ -No match - AXQQQ -No match - AXXQQQ -No match - -/(*COMMIT)ABC/ - ABCDEFG - 0: ABC - ** Failers -No match - DEFGABC\Y -No match - -/^(ab (c+(*THEN)cd) | xyz)/x - abcccd -No match - -/^(ab (c+(*PRUNE)cd) | xyz)/x - abcccd +/^(ab (c+(*PRUNE)cd) | xyz)/x + abcccd No match /^(ab (c+(*FAIL)cd) | xyz)/x @@ -11165,11 +10755,76 @@ /\s*\R/BZ ------------------------------------------------------------------ Bra - \s*+ + \s* + \R + Ket + End +------------------------------------------------------------------ + \x20\x0a + 0: \x0a + \x20\x0d + 0: \x0d + \x20\x0d\x0a + 0: \x0d\x0a + +/\S*\R/BZ +------------------------------------------------------------------ + Bra + \S*+ + \R + Ket + End +------------------------------------------------------------------ + a\x0a + 0: a\x0a + +/X\h*\R/BZ +------------------------------------------------------------------ + Bra + X + \h*+ + \R + Ket + End +------------------------------------------------------------------ + X\x20\x0a + 0: X \x0a + +/X\H*\R/BZ +------------------------------------------------------------------ + Bra + X + \H* + \R + Ket + End +------------------------------------------------------------------ + X\x0d\x0a + 0: X\x0d\x0a + +/X\H+\R/BZ +------------------------------------------------------------------ + Bra + X + \H+ + \R + Ket + End +------------------------------------------------------------------ + X\x0d\x0a + 0: X\x0d\x0a + +/X\H++\R/BZ +------------------------------------------------------------------ + Bra + X + \H++ \R Ket End ------------------------------------------------------------------ + X\x0d\x0a +No match /-- Perl treats this one differently, not failing the second string. I believe that is a bug in Perl. --/ @@ -11251,9 +10906,9 @@ abc\>3 No match abc\>4 -Error -24 +Error -24 (bad offset value) abc\>-4 -Error -24 +Error -24 (bad offset value) /^\cÄ£/ Failed: \c must be followed by an ASCII character at offset 3 @@ -11305,4 +10960,1405 @@ End ------------------------------------------------------------------ +/-- These tests are here because Perl gets the first one wrong. --/ + +/(\R*)(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + +/(\R)*(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0a + 2: \x0d + +/((?>\r\n|\n|\x0b|\f|\r|\x85)*)(.)/s + \r\n + 0: \x0d + 1: + 2: \x0d + \r\r\n\n\r + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + \r\r\n\n\r\n + 0: \x0d\x0d\x0a\x0a\x0d + 1: \x0d\x0d\x0a\x0a + 2: \x0d + +/-- --/ + +/^abc$/BZ +------------------------------------------------------------------ + Bra + ^ + abc + $ + Ket + End +------------------------------------------------------------------ + +/^abc$/BZm +------------------------------------------------------------------ + Bra + /m ^ + abc + /m $ + Ket + End +------------------------------------------------------------------ + +/^(a)*+(\w)/S + aaaaX + 0: aaaaX + 1: a + 2: X + ** Failers +No match + aaaa +No match + +/^(?:a)*+(\w)/S + aaaaX + 0: aaaaX + 1: X + ** Failers +No match + aaaa +No match + +/(a)++1234/SDZ +------------------------------------------------------------------ + Bra + CBraPos 1 + a + KetRpos + 1234 + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = '4' +Subject length lower bound = 5 +No set of starting bytes + +/([abc])++1234/SI +Capturing subpattern count = 1 +No options +No first char +Need char = '4' +Subject length lower bound = 5 +Starting byte set: a b c + +/(?<=(abc)+)X/ +Failed: lookbehind assertion is not fixed length at offset 10 + +/(^ab)/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab)++/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab|^)+/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(^ab|^)++/I +Capturing subpattern count = 1 +Options: anchored +No first char +No need char + +/(?:^ab)/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab)++/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab|^)+/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(?:^ab|^)++/I +Capturing subpattern count = 0 +Options: anchored +No first char +No need char + +/(.*ab)/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +Need char = 'b' + +/(.*ab)++/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +Need char = 'b' + +/(.*ab|.*)+/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(.*ab|.*)++/I +Capturing subpattern count = 1 +No options +First char at start or follows newline +No need char + +/(?:.*ab)/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/(?:.*ab)++/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +Need char = 'b' + +/(?:.*ab|.*)+/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +No need char + +/(?:.*ab|.*)++/I +Capturing subpattern count = 0 +No options +First char at start or follows newline +No need char + +/(?=a)[bcd]/I +Capturing subpattern count = 0 +No options +First char = 'a' +No need char + +/((?=a))[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/((?=a))+[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/((?=a))++[bcd]/I +Capturing subpattern count = 1 +No options +First char = 'a' +No need char + +/(?=a+)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a+?)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a++)[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +No need char + +/(?=a{3})[bcd]/iI +Capturing subpattern count = 0 +Options: caseless +First char = 'a' (caseless) +Need char = 'a' (caseless) + +/(abc)\1+/S + +/-- Perl doesn't get these right IMO (the 3rd is PCRE-specific) --/ + +/(?1)(?:(b(*ACCEPT))){0}/ + b + 0: b + +/(?1)(?:(b(*ACCEPT))){0}c/ + bc + 0: bc + ** Failers +No match + b +No match + +/(?1)(?:((*ACCEPT))){0}c/ + c + 0: c + c\N + 0: c + +/^.*?(?(?=a)a|b(*THEN)c)/ + ba +No match + +/^.*?(?(?=a)a|bc)/ + ba + 0: ba + +/^.*?(?(?=a)a(*THEN)b|c)/ + ac +No match + +/^.*?(?(?=a)a(*THEN)b)c/ + ac +No match + +/^.*?(a(*THEN)b)c/ + aabc +No match + +/^.*? (?1) c (?(DEFINE)(a(*THEN)b))/x + aabc + 0: aabc + +/^.*?(a(*THEN)b|z)c/ + aabc + 0: aabc + 1: ab + +/^.*?(z|a(*THEN)b)c/ + aabc + 0: aabc + 1: ab + +/-- --/ + +/-- These studied versions are here because they are not Perl-compatible; the + studying means the mark is not seen. --/ + +/(*MARK:A)(*SKIP:B)(C|X)/KS + C + 0: C + 1: C +MK: A + D +No match, mark = A + +/(*:A)A+(*SKIP:A)(B|Z)/KS + AAAC +No match, mark = A + +/-- --/ + +"(?=a*(*ACCEPT)b)c" + c + 0: c + c\N + 0: c + +/(?1)c(?(DEFINE)((*ACCEPT)b))/ + c + 0: c + c\N + 0: c + +/(?>(*ACCEPT)b)c/ + c + 0: + c\N +No match + +/(?:(?>(a)))+a%/++ + %aa% + 0: aa% + 0+ + 1: a + 1+ a% + +/(a)b|ac/++SS + ac\O3 +Matched, but too many substrings + 0: ac + 0+ + +/(a)(b)x|abc/++ + abc\O6 + 0: abc + 0+ + +/(a)bc|(a)(b)\2/ + \O3abc +Matched, but too many substrings + 0: abc + \O4abc +Matched, but too many substrings + 0: abc + +/(?(DEFINE)(a(?2)|b)(b(?1)|a))(?:(?1)|(?2))/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a b + +/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI +Capturing subpattern count = 2 +No options +No first char +No need char +Subject length lower bound = 4 +Starting byte set: a b + +/(abc)(?1)/SI +Capturing subpattern count = 1 +No options +First char = 'a' +Need char = 'c' +Subject length lower bound = 6 +No set of starting bytes + +/^(?>a)++/ + aa\M +Minimum match() limit = 5 +Minimum match() recursion limit = 2 + 0: aa + aaaaaaaaa\M +Minimum match() limit = 12 +Minimum match() recursion limit = 2 + 0: aaaaaaaaa + +/(a)(?1)++/ + aa\M +Minimum match() limit = 7 +Minimum match() recursion limit = 4 + 0: aa + 1: a + aaaaaaaaa\M +Minimum match() limit = 21 +Minimum match() recursion limit = 4 + 0: aaaaaaaaa + 1: a + +/(?:(foo)|(bar)|(baz))X/SS= + bazfooX + 0: fooX + 1: foo + 2: + 3: + foobazbarX + 0: barX + 1: + 2: bar + 3: + barfooX + 0: fooX + 1: foo + 2: + 3: + bazX + 0: bazX + 1: + 2: + 3: baz + foobarbazX + 0: bazX + 1: + 2: + 3: baz + bazfooX\O0 +Matched, but too many substrings + bazfooX\O2 +Matched, but too many substrings + 0: fooX + bazfooX\O4 +Matched, but too many substrings + 0: fooX + 1: + bazfooX\O6 +Matched, but too many substrings + 0: fooX + 1: foo + 2: + bazfooX\O8 +Matched, but too many substrings + 0: fooX + 1: foo + 2: + 3: + bazfooX\O10 + 0: fooX + 1: foo + 2: + 3: + +/(?=abc){3}abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc)+abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc)++abc/BZ +------------------------------------------------------------------ + Bra + Assert + abc + Ket + abc + Ket + End +------------------------------------------------------------------ + +/(?=abc){0}xyz/BZ +------------------------------------------------------------------ + Bra + Skip zero + Assert + abc + Ket + xyz + Ket + End +------------------------------------------------------------------ + +/(?=(a))?./BZ +------------------------------------------------------------------ + Bra + Brazero + Assert + CBra 1 + a + Ket + Ket + Any + Ket + End +------------------------------------------------------------------ + +/(?=(a))??./BZ +------------------------------------------------------------------ + Bra + Braminzero + Assert + CBra 1 + a + Ket + Ket + Any + Ket + End +------------------------------------------------------------------ + +/^(?=(a)){0}b(?1)/BZ +------------------------------------------------------------------ + Bra + ^ + Skip zero + Assert + CBra 1 + a + Ket + Ket + b + Recurse + Ket + End +------------------------------------------------------------------ + +/(?(DEFINE)(a))?b(?1)/BZ +------------------------------------------------------------------ + Bra + Cond + Cond def + CBra 1 + a + Ket + Ket + b + Recurse + Ket + End +------------------------------------------------------------------ + +/^(?=(?1))?[az]([abc])d/BZ +------------------------------------------------------------------ + Bra + ^ + Brazero + Assert + Recurse + Ket + [az] + CBra 1 + [a-c] + Ket + d + Ket + End +------------------------------------------------------------------ + +/^(?!a){0}\w+/BZ +------------------------------------------------------------------ + Bra + ^ + Skip zero + Assert not + a + Ket + \w+ + Ket + End +------------------------------------------------------------------ + +/(?<=(abc))?xyz/BZ +------------------------------------------------------------------ + Bra + Brazero + AssertB + Reverse + CBra 1 + abc + Ket + Ket + xyz + Ket + End +------------------------------------------------------------------ + +/[:a[:abc]b:]/BZ +------------------------------------------------------------------ + Bra + [:[a-c] + b:] + Ket + End +------------------------------------------------------------------ + +/((?2))((?1))/SS + abc +Error -26 (nested recursion at the same subject position) + +/((?(R2)a+|(?1)b))/SS + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(?(R)a*(?1)|((?R))b)/SS + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(a+|(?R)b)/ +Failed: recursive call could loop indefinitely at offset 7 + +/^(a(*:A)(d|e(*:B))z|aeq)/C + adz +--->adz + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++10 ^ ^ | ++18 ^ ^ z ++19 ^ ^ | ++24 ^ ^ + 0: adz + 1: adz + 2: d + aez +--->aez + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++11 ^^ e ++12 ^ ^ (*:B) ++17 ^ ^ ) +Latest Mark: B ++18 ^ ^ z ++19 ^ ^ | ++24 ^ ^ + 0: aez + 1: aez + 2: e + aeqwerty +--->aeqwerty + +0 ^ ^ + +1 ^ (a(*:A)(d|e(*:B))z|aeq) + +2 ^ a + +3 ^^ (*:A) + +8 ^^ (d|e(*:B)) +Latest Mark: A + +9 ^^ d ++11 ^^ e ++12 ^ ^ (*:B) ++17 ^ ^ ) +Latest Mark: B ++18 ^ ^ z ++20 ^ a ++21 ^^ e ++22 ^ ^ q ++23 ^ ^ ) ++24 ^ ^ + 0: aeq + 1: aeq + +/.(*F)/ + \P\Pabc +No match + +/\btype\b\W*?\btext\b\W*?\bjavascript\b/IS +Capturing subpattern count = 0 +No options +First char = 't' +Need char = 't' +Max lookbehind = 1 +Subject length lower bound = 18 +No set of starting bytes + +/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|a+)(?>(z+))\w/BZ +------------------------------------------------------------------ + Bra + ^ + Once_NC + a+ + Ket + Once + CBra 1 + z+ + Ket + Ket + \w + Ket + End +------------------------------------------------------------------ + aaaazzzzb + 0: aaaazzzzb + 1: zzzz + ** Failers +No match + aazz +No match + +/(.)(\1|a(?2))/ + bab + 0: bab + 1: b + 2: ab + +/\1|(.)(?R)\1/ + cbbbc + 0: cbbbc + 1: c + +/(.)((?(1)c|a)|a(?2))/ + baa +No match + +/(?P(?P=abn)xxx)/BZ +------------------------------------------------------------------ + Bra + Once + CBra 1 + \1 + xxx + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/(a\1z)/BZ +------------------------------------------------------------------ + Bra + Once + CBra 1 + a + \1 + z + Ket + Ket + Ket + End +------------------------------------------------------------------ + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + \Maabbccddee +Minimum match() limit = 12 +Minimum match() recursion limit = 3 + 0: aabbccddee + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + \Maabbccddee +Minimum match() limit = 22 +Minimum match() recursion limit = 21 + 0: aabbccddee + 1: aa + 2: bb + 3: cc + 4: dd + 5: ee + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + \Maabbccddee +Minimum match() limit = 18 +Minimum match() recursion limit = 13 + 0: aabbccddee + 1: aa + 2: cc + 3: ee + +/^a\x41z/ + aAz + 0: aAz + *** Failers +No match + ax41z +No match + +/^a[m\x41]z/ + aAz + 0: aAz + +/^a\x1z/ + ax1z + 0: ax1z + +/^a\u0041z/ + aAz + 0: aAz + *** Failers +No match + au0041z +No match + +/^a[m\u0041]z/ + aAz + 0: aAz + +/^a\u041z/ + au041z + 0: au041z + *** Failers +No match + aAz +No match + +/^a\U0041z/ + aU0041z + 0: aU0041z + *** Failers +No match + aAz +No match + +/(?(?=c)c|d)++Y/BZ +------------------------------------------------------------------ + Bra + BraPos + Cond + Assert + c + Ket + c + Alt + d + Ket + KetRpos + Y + Ket + End +------------------------------------------------------------------ + +/(?(?=c)c|d)*+Y/BZ +------------------------------------------------------------------ + Bra + Braposzero + BraPos + Cond + Assert + c + Ket + c + Alt + d + Ket + KetRpos + Y + Ket + End +------------------------------------------------------------------ + +/a[\NB]c/ +Failed: \N is not supported in a class at offset 3 + +/a[B-\Nc]/ +Failed: \N is not supported in a class at offset 5 + +/(a)(?2){0,1999}?(b)/ + +/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/ + +/--- This test, with something more complicated than individual letters, causes +different behaviour in Perl. Perhaps it disables some optimization; no tag is +passed back for the failures, whereas in PCRE there is a tag. ---/ + +/(A|P)(*:A)(B|P) | (X|P)(X|P)(*:B)(Y|P)/xK + AABC + 0: AB + 1: A + 2: B +MK: A + XXYZ + 0: XXY + 1: + 2: + 3: X + 4: X + 5: Y +MK: B + ** Failers +No match + XAQQ +No match, mark = A + XAQQXZZ +No match, mark = A + AXQQQ +No match, mark = A + AXXQQQ +No match, mark = B + +/-- Perl doesn't give marks for these, though it does if the alternatives are +replaced by single letters. --/ + +/(b|q)(*:m)f|a(*:n)w/K + aw + 0: aw +MK: n + ** Failers +No match, mark = n + abc +No match, mark = m + +/(q|b)(*:m)f|a(*:n)w/K + aw + 0: aw +MK: n + ** Failers +No match, mark = n + abc +No match, mark = m + +/-- After a partial match, the behaviour is as for a failure. --/ + +/^a(*:X)bcde/K + abc\P +Partial match, mark=X: abc + +/-- These are here because Perl doesn't return a mark, except for the first --/ + +/(?=(*:x))(q|)/K+ + abc + 0: + 0+ abc + 1: +MK: x + +/(?=(*:x))((*:y)q|)/K+ + abc + 0: + 0+ abc + 1: +MK: x + +/(?=(*:x))(?:(*:y)q|)/K+ + abc + 0: + 0+ abc +MK: x + +/(?=(*:x))(?>(*:y)q|)/K+ + abc + 0: + 0+ abc +MK: x + +/(?=a(*:x))(?!a(*:y)c)/K+ + ab + 0: + 0+ ab +MK: x + +/(?=a(*:x))(?=a(*:y)c|)/K+ + ab + 0: + 0+ ab +MK: x + +/(..)\1/ + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P + 0: abab + 1: ab + +/(..)\1/i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P + 0: aBAb + 1: aB + +/(..)\1{2,}/ + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P +Partial match: abab + ababa\P +Partial match: ababa + ababab\P + 0: ababab + 1: ab + ababab\P\P +Partial match: ababab + abababa\P + 0: ababab + 1: ab + abababa\P\P +Partial match: abababa + +/(..)\1{2,}/i + ab\P +Partial match: ab + aBa\P +Partial match: aBa + aBAb\P +Partial match: aBAb + AbaBA\P +Partial match: AbaBA + abABAb\P + 0: abABAb + 1: ab + aBAbaB\P\P +Partial match: aBAbaB + abABabA\P + 0: abABab + 1: ab + abaBABa\P\P +Partial match: abaBABa + +/(..)\1{2,}?x/i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P +Partial match: aBAb + abaBA\P +Partial match: abaBA + abAbaB\P +Partial match: abAbaB + abaBabA\P +Partial match: abaBabA + abAbABaBx\P + 0: abAbABaBx + 1: ab + +/^(..)\1/ + aba\P +Partial match: aba + +/^(..)\1{2,3}x/ + aba\P +Partial match: aba + ababa\P +Partial match: ababa + ababa\P\P +Partial match: ababa + abababx + 0: abababx + 1: ab + ababababx + 0: ababababx + 1: ab + +/^(..)\1{2,3}?x/ + aba\P +Partial match: aba + ababa\P +Partial match: ababa + ababa\P\P +Partial match: ababa + abababx + 0: abababx + 1: ab + ababababx + 0: ababababx + 1: ab + +/^(..)(\1{2,3})ab/ + abababab + 0: abababab + 1: ab + 2: abab + +/^\R/ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/^\R{2,3}x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R{2,3}?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + x + 0: x + \rx + 0: \x0dx + +/^\R+x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\n\P +Partial match: \x0d\x0a + \r\n\P\P +Partial match: \x0d\x0a + \rx + 0: \x0dx + +/^a$/ + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^a$/m + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/ + a\r\P + 0: a\x0d + 1: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/m + a\r\P + 0: a\x0d + 1: a\x0d + a\r\P\P +Partial match: a\x0d + +/./ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/.{2,3}/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/.{2,3}?/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d + \r\r\r\P\P + 0: \x0d\x0d + +/-- These two are here because Perl does not match: it seems to allow the +COMMIT to escape from the assertion. --/ + +/(?=a(*COMMIT)b|ac)ac|ac/ + ac + 0: ac + +/(?=a(*COMMIT)b|(ac)) ac | (a)c/x + ac + 0: ac + 1: + 2: a + +"AB(C(D))(E(F))?(?(?=\2)(?=\4))" + ABCDGHI\O03 +Matched, but too many substrings + 0: ABCD + +/-- This one is here because Perl does not confine the *COMMIT to the +assertion, and therefore fails the entire subroutine call. --/ + +/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/ + ac + 0: ac + /-- End of testinput2 --/ diff -Nru pcre3-8.12/testdata/testoutput20 pcre3-8.31/testdata/testoutput20 --- pcre3-8.12/testdata/testoutput20 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput20 2011-12-28 16:57:55.000000000 +0000 @@ -0,0 +1,24 @@ +/-- These tests are for the handling of characters greater than 255 in 16-bit, + non-UTF-16 mode. --/ + +/^\x{ffff}+/i + \x{ffff} + 0: \x{ffff} + +/^\x{ffff}?/i + \x{ffff} + 0: \x{ffff} + +/^\x{ffff}*/i + \x{ffff} + 0: \x{ffff} + +/^\x{ffff}{3}/i + \x{ffff}\x{ffff}\x{ffff} + 0: \x{ffff}\x{ffff}\x{ffff} + +/^\x{ffff}{0,3}/i + \x{ffff} + 0: \x{ffff} + +/-- End of testinput20 --/ diff -Nru pcre3-8.12/testdata/testoutput21 pcre3-8.31/testdata/testoutput21 --- pcre3-8.12/testdata/testoutput21 1970-01-01 00:00:00.000000000 +0000 +++ pcre3-8.31/testdata/testoutput21 2012-01-20 14:18:24.000000000 +0000 @@ -0,0 +1,78 @@ +/-- Tests for reloading pre-compile patterns. The first one gives an error +right away. The others require the linke size to be 2. */ + +(?:[AaLl]+)[^xX-]*?)(?P[\x{150}-\x{250}\x{300}]|[^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$ --/ + +[aZ\x{400}-\x{10ffff}]{4,}[\x{f123}\x{10039}\x{20000}-\x{21234}]?|[A-Cx-z\x{100000}-\x{1000a7}\x{101234}])(?[^az]) --/8 + += 5.10 and both the 8-bit and 16-bit + PCRE libraries. --/ /a.b/8 acb @@ -255,46 +256,6 @@ XYZ No match -/X(\C{3})/8 - X\x{1234} - 0: X\x{1234} - 1: \x{1234} - -/X(\C{4})/8 - X\x{1234}YZ - 0: X\x{1234}Y - 1: \x{1234}Y - -/X\C*/8 - XYZabcdce - 0: XYZabcdce - -/X\C*?/8 - XYZabcde - 0: X - -/X\C{3,5}/8 - Xabcdefg - 0: Xabcde - X\x{1234} - 0: X\x{1234} - X\x{1234}YZ - 0: X\x{1234}YZ - X\x{1234}\x{512} - 0: X\x{1234}\x{512} - X\x{1234}\x{512}YZ - 0: X\x{1234}\x{512} - -/X\C{3,5}?/8 - Xabcdefg - 0: Xabc - X\x{1234} - 0: X\x{1234} - X\x{1234}YZ - 0: X\x{1234} - X\x{1234}\x{512} - 0: X\x{1234} - /[^a]+/8g bcd 0: bcd @@ -791,22 +752,6 @@ \x{200}X No match -/a\Cb/ - aXb - 0: aXb - a\nb - 0: a\x0ab - -/a\Cb/8 - aXb - 0: aXb - a\nb - 0: a\x{0a}b - -/a\C\Cb/8 - a\x{100}b - 0: a\x{100}b - /[z-\x{100}]/8i z 0: z @@ -1128,4 +1073,22 @@ 0: AA 0: +/(abc)\1/8i + abc +No match + +/(abc)\1/8 + abc +No match + +/a(*:a\x{1234}b)/8K + abc + 0: a +MK: a\x{1234}b + +/a(*:a£b)/8K + abc + 0: a +MK: a\x{a3}b + /-- End of testinput4 --/ diff -Nru pcre3-8.12/testdata/testoutput5 pcre3-8.31/testdata/testoutput5 --- pcre3-8.12/testdata/testoutput5 2010-11-20 17:25:30.000000000 +0000 +++ pcre3-8.31/testdata/testoutput5 2012-06-17 16:43:31.000000000 +0000 @@ -1,113 +1,9 @@ -/-- This set of tests checks the API, internals, and non-Perl stuff for UTF-8 - support, excluding Unicode properties. --/ +/-- This set of tests checks the API, internals, and non-Perl stuff for UTF + support, excluding Unicode properties. However, tests that give different + results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/ -/\x{100}/8DZ ------------------------------------------------------------------- - Bra - \x{100} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - -/\x{1000}/8DZ ------------------------------------------------------------------- - Bra - \x{1000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 225 -Need char = 128 - -/\x{10000}/8DZ ------------------------------------------------------------------- - Bra - \x{10000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 240 -Need char = 128 - -/\x{100000}/8DZ ------------------------------------------------------------------- - Bra - \x{100000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 244 -Need char = 128 - -/\x{1000000}/8DZ ------------------------------------------------------------------- - Bra - \x{1000000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 249 -Need char = 128 - -/\x{4000000}/8DZ ------------------------------------------------------------------- - Bra - \x{4000000} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 252 -Need char = 128 - -/\x{7fffFFFF}/8DZ ------------------------------------------------------------------- - Bra - \x{7fffffff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 253 -Need char = 191 - -/[\x{ff}]/8DZ ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - -/[\x{100}]/8DZ ------------------------------------------------------------------- - Bra - [\x{100}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char +/\x{110000}/8DZ +Failed: character value in \x{...} sequence is too large at offset 9 /\x{ffffffff}/8 Failed: character value in \x{...} sequence is too large at offset 11 @@ -115,34 +11,20 @@ /\x{100000000}/8 Failed: character value in \x{...} sequence is too large at offset 12 +/\x{d800}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{dfff}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{d7ff}/8 + +/\x{e000}/8 + /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd 0: \x{100}a\x{1234} -/\x80/8DZ ------------------------------------------------------------------- - Bra - \x{80} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 194 -Need char = 128 - -/\xff/8DZ ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - /\x{0041}\x{2262}\x{0391}\x{002e}/DZ8 ------------------------------------------------------------------ Bra @@ -151,100 +33,12 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'A' Need char = '.' \x{0041}\x{2262}\x{0391}\x{002e} 0: A\x{2262}\x{391}. -/\x{D55c}\x{ad6d}\x{C5B4}/DZ8 ------------------------------------------------------------------- - Bra - \x{d55c}\x{ad6d}\x{c5b4} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 237 -Need char = 180 - \x{D55c}\x{ad6d}\x{C5B4} - 0: \x{d55c}\x{ad6d}\x{c5b4} - -/\x{65e5}\x{672c}\x{8a9e}/DZ8 ------------------------------------------------------------------- - Bra - \x{65e5}\x{672c}\x{8a9e} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 230 -Need char = 158 - \x{65e5}\x{672c}\x{8a9e} - 0: \x{65e5}\x{672c}\x{8a9e} - -/\x{80}/DZ8 ------------------------------------------------------------------- - Bra - \x{80} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 194 -Need char = 128 - -/\x{084}/DZ8 ------------------------------------------------------------------- - Bra - \x{84} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 194 -Need char = 132 - -/\x{104}/DZ8 ------------------------------------------------------------------- - Bra - \x{104} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 132 - -/\x{861}/DZ8 ------------------------------------------------------------------- - Bra - \x{861} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 224 -Need char = 161 - -/\x{212ab}/DZ8 ------------------------------------------------------------------- - Bra - \x{212ab} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 240 -Need char = 171 - /.{3,5}X/DZ8 ------------------------------------------------------------------ Bra @@ -255,13 +49,12 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char Need char = 'X' \x{212ab}\x{212ab}\x{212ab}\x{861}X 0: \x{212ab}\x{212ab}\x{212ab}\x{861}X - /.{3,5}?/DZ8 ------------------------------------------------------------------ Bra @@ -271,7 +64,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char \x{212ab}\x{212ab}\x{212ab}\x{861} @@ -280,29 +73,6 @@ /(?<=\C)X/8 Failed: \C not allowed in lookbehind assertion at offset 6 -/-- This one is here not because it's different to Perl, but because the way -the captured single-byte is displayed. (In Perl it becomes a character, and you -can't tell the difference.) --/ - -/X(\C)(.*)/8 - X\x{1234} - 0: X\x{1234} - 1: \xe1 - 2: \x88\xb4 - X\nabc - 0: X\x{0a}abc - 1: \x{0a} - 2: abc - -/-- This one is here because Perl gives out a grumbly error message (quite -correctly, but that messes up comparisons). --/ - -/a\Cb/8 - *** Failers -No match - a\x{100}b -No match - /^[ab]/8DZ ------------------------------------------------------------------ Bra @@ -312,7 +82,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char bar @@ -335,7 +105,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char c @@ -349,136 +119,6 @@ aaa No match -/[^ab\xC0-\xF0]/8SDZ ------------------------------------------------------------------- - Bra - [\x00-`c-\xbf\xf1-\xff] (neg) - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a - \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 - \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 - 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y - Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f - \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 - \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf - \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee - \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd - \xfe \xff - \x{f1} - 0: \x{f1} - \x{bf} - 0: \x{bf} - \x{100} - 0: \x{100} - \x{1000} - 0: \x{1000} - *** Failers - 0: * - \x{c0} -No match - \x{f0} -No match - -/Ä€{3,4}/8SDZ ------------------------------------------------------------------- - Bra - \x{100}{3} - \x{100}? - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 -Subject length lower bound = 3 -No set of starting bytes - \x{100}\x{100}\x{100}\x{100\x{100} - 0: \x{100}\x{100}\x{100} - -/(\x{100}+|x)/8SDZ ------------------------------------------------------------------- - Bra - CBra 1 - \x{100}+ - Alt - x - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: x \xc4 - -/(\x{100}*a|x)/8SDZ ------------------------------------------------------------------- - Bra - CBra 1 - \x{100}*+ - a - Alt - x - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: a x \xc4 - -/(\x{100}{0,2}a|x)/8SDZ ------------------------------------------------------------------- - Bra - CBra 1 - \x{100}{0,2} - a - Alt - x - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: a x \xc4 - -/(\x{100}{1,2}a|x)/8SDZ ------------------------------------------------------------------- - Bra - CBra 1 - \x{100} - \x{100}{0,1} - a - Alt - x - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: x \xc4 - /\x{100}*(\d+|"(?1)")/8 1234 0: 1234 @@ -503,18 +143,6 @@ \x{100}\x{100}abcd No match -/\x{100}/8DZ ------------------------------------------------------------------- - Bra - \x{100} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - /\x{100}*/8DZ ------------------------------------------------------------------ Bra @@ -523,7 +151,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -536,7 +164,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'a' No need char @@ -549,36 +177,10 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf First char = 'a' Need char = 'b' -/a\x{100}\x{101}*/8DZ ------------------------------------------------------------------- - Bra - a\x{100} - \x{101}* - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'a' -Need char = 128 - -/a\x{100}\x{101}+/8DZ ------------------------------------------------------------------- - Bra - a\x{100} - \x{101}+ - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'a' -Need char = 129 - /\x{100}*A/8DZ ------------------------------------------------------------------ Bra @@ -588,7 +190,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char Need char = 'A' A @@ -599,60 +201,14 @@ Bra \x{100}*+ \d - Once Recurse Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - -/[^\x{c4}]/DZ ------------------------------------------------------------------- - Bra - [^\xc4] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -No options -No first char -No need char - -/[^\x{c4}]/8DZ ------------------------------------------------------------------- - Bra - [\x00-\xc3\xc5-\xff] (neg) - Ket End ------------------------------------------------------------------ -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - -/[\x{100}]/8DZ ------------------------------------------------------------------- - Bra - [\x{100}] - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - \x{100} - 0: \x{100} - Z\x{100} - 0: \x{100} - \x{100}Z - 0: \x{100} - *** Failers -No match +Capturing subpattern count = 0 +Options: utf +No first char +No need char /[Z\x{100}]/8DZ ------------------------------------------------------------------ @@ -662,7 +218,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char Z\x{100} @@ -697,7 +253,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -709,7 +265,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char \x{100} @@ -726,25 +282,11 @@ ------------------------------------------------------------------ Capturing subpattern count = 0 No options -First char = 255 +First char = \xff No need char >\xff< 0: \xff -/[\xff]/DZ8 ------------------------------------------------------------------- - Bra - \x{ff} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 195 -Need char = 191 - >\x{ff}< - 0: \x{ff} - /[^\xFF]/DZ ------------------------------------------------------------------ Bra @@ -757,18 +299,6 @@ No first char No need char -/[^\xff]/8DZ ------------------------------------------------------------------- - Bra - [\x00-\xfe] (neg) - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char - /[Ä-Ãœ]/8 Ö # Matches without Study 0: \x{d6} @@ -793,105 +323,6 @@ \x{d6} 0: \x{d6} -/[Ã]/8 -Failed: invalid UTF-8 string at offset 2 - -/Ã/8 -Failed: invalid UTF-8 string at offset 1 - -/ÃÃÃxxx/8 -Failed: invalid UTF-8 string at offset 1 - -/ÃÃÃxxx/8?DZ ------------------------------------------------------------------- - Bra - \X{c0}\X{c0}\X{c0}xxx - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 no_utf8_check -First char = 195 -Need char = 'x' - -/abc/8 - Ã] -Error -10 - à -Error -10 - ÃÃà -Error -10 - ÃÃÃ\? -No match - \xe1\x88 -Error -10 - \P\xe1\x88 -Error -10 - \P\P\xe1\x88 -Error -25 - -/anything/8 - \xc0\x80 -Error -10 - \xc1\x8f -Error -10 - \xe0\x9f\x80 -Error -10 - \xf0\x8f\x80\x80 -Error -10 - \xf8\x87\x80\x80\x80 -Error -10 - \xfc\x83\x80\x80\x80\x80 -Error -10 - \xfe\x80\x80\x80\x80\x80 -Error -10 - \xff\x80\x80\x80\x80\x80 -Error -10 - \xc3\x8f -No match - \xe0\xaf\x80 -No match - \xe1\x80\x80 -No match - \xf0\x9f\x80\x80 -No match - \xf1\x8f\x80\x80 -No match - \xf8\x88\x80\x80\x80 -Error -10 - \xf9\x87\x80\x80\x80 -Error -10 - \xfc\x84\x80\x80\x80\x80 -Error -10 - \xfd\x83\x80\x80\x80\x80 -Error -10 - \?\xf8\x88\x80\x80\x80 -No match - \?\xf9\x87\x80\x80\x80 -No match - \?\xfc\x84\x80\x80\x80\x80 -No match - \?\xfd\x83\x80\x80\x80\x80 -No match - -/\x{100}abc(xyz(?1))/8DZ ------------------------------------------------------------------- - Bra - \x{100}abc - CBra 1 - xyz - Once - Recurse - Ket - Ket - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 1 -Options: utf8 -First char = 196 -Need char = 'z' - /[^\x{100}]abc(xyz(?1))/8DZ ------------------------------------------------------------------ Bra @@ -899,15 +330,13 @@ abc CBra 1 xyz - Once Recurse Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 -Options: utf8 +Options: utf No first char Need char = 'z' @@ -918,15 +347,13 @@ abc CBra 1 xyz - Once Recurse Ket Ket - Ket End ------------------------------------------------------------------ Capturing subpattern count = 1 -Options: utf8 +Options: utf No first char Need char = 'z' @@ -938,9 +365,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -948,7 +373,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -961,9 +386,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -972,9 +395,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -983,7 +404,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -995,9 +416,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -1005,7 +424,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -1018,9 +437,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -1029,9 +446,7 @@ \x{100} CBra 2 b - Once Recurse - Ket c Ket Ket @@ -1040,7 +455,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 2 -Options: utf8 +Options: utf No first char No need char @@ -1054,10 +469,6 @@ \x{100}X 0: X -/a\x{1234}b/P8 - a\x{1234}b - 0: a\x{1234}b - /^\ሴ/8DZ ------------------------------------------------------------------ Bra @@ -1067,23 +478,10 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: anchored utf8 +Options: anchored utf No first char No need char -/\777/I -Failed: octal value is greater than \377 (not in UTF-8 mode) at offset 3 - -/\777/8I -Capturing subpattern count = 0 -Options: utf8 -First char = 199 -Need char = 191 - \x{1ff} - 0: \x{1ff} - \777 - 0: \x{1ff} - /\x{100}*\d/8DZ ------------------------------------------------------------------ Bra @@ -1093,7 +491,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1106,7 +504,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1119,7 +517,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1132,7 +530,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1145,7 +543,7 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char @@ -1158,49 +556,10 @@ End ------------------------------------------------------------------ Capturing subpattern count = 0 -Options: utf8 +Options: utf No first char No need char -/\x{100}+\x{200}/8DZ ------------------------------------------------------------------- - Bra - \x{100}++ - \x{200} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 128 - -/\x{100}+X/8DZ ------------------------------------------------------------------- - Bra - \x{100}++ - X - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 196 -Need char = 'X' - -/X+\x{200}/8DZ ------------------------------------------------------------------- - Bra - X++ - \x{200} - Ket - End ------------------------------------------------------------------- -Capturing subpattern count = 0 -Options: utf8 -First char = 'X' -Need char = 128 - /()()()()()()()()()() ()()()()()()()()()() ()()()()()()()()()() @@ -1242,9 +601,6 @@ End ------------------------------------------------------------------ -/^[\QÄ€\E-\QÅ\E/BZ8 -Failed: missing terminating ] for character class at offset 15 - /^abc./mgx8 abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK 0: abc1 @@ -1430,7 +786,7 @@ /[\H]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{7fffffff}] + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}] Ket End ------------------------------------------------------------------ @@ -1438,7 +794,7 @@ /[\V]/8BZ ------------------------------------------------------------------ Bra - [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{2029}-\x{7fffffff}] + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}] Ket End ------------------------------------------------------------------ @@ -1447,39 +803,9 @@ \x{1ec5} 0: \x{1ec5} -/-- This tests the stricter UTF-8 check according to RFC 3629. --/ - -/X/8 - \x{0}\x{d7ff}\x{e000}\x{10ffff} -No match - \x{d800} -Error -10 - \x{d800}\? -No match - \x{da00} -Error -10 - \x{da00}\? -No match - \x{dfff} -Error -10 - \x{dfff}\? -No match - \x{110000} -Error -10 - \x{110000}\? -No match - \x{2000000} -Error -10 - \x{2000000}\? -No match - \x{7fffffff} -Error -10 - \x{7fffffff}\? -No match - /a\Rb/I8 Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb @@ -1497,7 +823,7 @@ /a\Rb/I8 Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb @@ -1519,7 +845,7 @@ /a\R?b/I8 Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf utf First char = 'a' Need char = 'b' a\rb @@ -1537,7 +863,7 @@ /a\R?b/I8 Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode utf First char = 'a' Need char = 'b' a\rb @@ -1594,26 +920,11 @@ \x{de}\x{de} 0: \xde\xde 1: \xde - \x{123} -** Character \x{123} is greater than 255 and UTF-8 mode is not enabled. -** Truncation will probably give the wrong result. -No match /X/8f A\x{1ec5}ABCXYZ 0: X -/(*UTF8)\x{1234}/ - abcd\x{1234}pqr - 0: \x{1234} - -/(*CRLF)(*UTF8)(*BSR_UNICODE)a\Rb/I -Capturing subpattern count = 0 -Options: bsr_unicode utf8 -Forced newline sequence: CRLF -First char = 'a' -Need char = 'b' - /Xa{2,4}b/8 X\P Partial match: X @@ -2091,152 +1402,16 @@ \PX Partial match: X -/\h/SI -Capturing subpattern count = 0 -No options -No first char -No need char -Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xa0 - -/\h/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3 - ABC\x{09} - 0: \x{09} - ABC\x{20} - 0: - ABC\x{a0} - 0: \x{a0} - ABC\x{1680} - 0: \x{1680} - ABC\x{180e} - 0: \x{180e} - ABC\x{2000} - 0: \x{2000} - ABC\x{202f} - 0: \x{202f} - ABC\x{205f} - 0: \x{205f} - ABC\x{3000} - 0: \x{3000} - -/\v/SI -Capturing subpattern count = 0 -No options -No first char -No need char -Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \x85 - -/\v/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char -Subject length lower bound = 1 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 - ABC\x{0a} - 0: \x{0a} - ABC\x{0b} - 0: \x{0b} - ABC\x{0c} - 0: \x{0c} - ABC\x{0d} - 0: \x{0d} - ABC\x{85} - 0: \x{85} - ABC\x{2028} - 0: \x{2028} - -/\R/SI -Capturing subpattern count = 0 -No options -No first char -No need char -Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \x85 - -/\R/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -No need char -Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 - -/\h*A/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -Need char = 'A' -Subject length lower bound = 1 -Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3 - CDBABC - 0: A - -/\v+A/SI8 -Capturing subpattern count = 0 -Options: utf8 -No first char -Need char = 'A' -Subject length lower bound = 2 -Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2 - -/\s?xxx\s/8SI -Capturing subpattern count = 0 -Options: utf8 -No first char -Need char = 'x' -Subject length lower bound = 4 -Starting byte set: \x09 \x0a \x0c \x0d \x20 x - /\sxxx\s/8T1 AB\x{85}xxx\x{a0}XYZ 0: \x{85}xxx\x{a0} AB\x{a0}xxx\x{85}XYZ 0: \x{a0}xxx\x{85} -/\sxxx\s/I8ST1 -Capturing subpattern count = 0 -Options: utf8 -No first char -Need char = 'x' -Subject length lower bound = 5 -Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2 - AB\x{85}xxx\x{a0}XYZ - 0: \x{85}xxx\x{a0} - AB\x{a0}xxx\x{85}XYZ - 0: \x{a0}xxx\x{85} - /\S \S/8T1 \x{a2} \x{84} 0: \x{a2} \x{84} -/\S \S/I8ST1 -Capturing subpattern count = 0 -Options: utf8 -No first char -Need char = ' ' -Subject length lower bound = 3 -Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e - \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d - \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ - A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e - f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc0 \xc1 \xc2 \xc3 - \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 - \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 - \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 - \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff - \x{a2} \x{84} - 0: \x{a2} \x{84} - A Z - 0: A Z - 'A#хц'8xBZ ------------------------------------------------------------------ Bra @@ -2298,21 +1473,377 @@ End ------------------------------------------------------------------ -/a+/8 - a\x{123}aa\>1 - 0: aa - a\x{123}aa\>2 -Error -11 - a\x{123}aa\>3 - 0: aa - a\x{123}aa\>4 - 0: a - a\x{123}aa\>5 -No match - a\x{123}aa\>6 -Error -24 - /^\cÄ£/8 Failed: \c must be followed by an ASCII character at offset 3 +/(\R*)(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0d}\x{0d}\x{0a}\x{0a} + 2: \x{0d} + +/(\R)*(.)/s8 + \r\n + 0: \x{0d} + 1: + 2: \x{0d} + \r\r\n\n\r + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + \r\r\n\n\r\n + 0: \x{0d}\x{0d}\x{0a}\x{0a}\x{0d} + 1: \x{0a} + 2: \x{0d} + +/[^\x{1234}]+/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]+?/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]++/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 1 +No set of starting bytes + +/[^\x{1234}]{2}/iS8I +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char +Subject length lower bound = 2 +No set of starting bytes + +// +Failed: inconsistent NEWLINE options at offset 0 + +/f.*/ + \P\Pfor +Partial match: for + +/f.*/s + \P\Pfor +Partial match: for + +/f.*/8 + \P\Pfor +Partial match: for + +/f.*/8s + \P\Pfor +Partial match: for + +/\x{d7ff}\x{e000}/8 + +/\x{d800}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\x{dfff}/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 + +/\h+/8 + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + 0: \x{200a}\x{a0}\x{2000} + +/[\h\x{e000}]+/8BZ +------------------------------------------------------------------ + Bra + [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+ + Ket + End +------------------------------------------------------------------ + \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000} + 0: \x{1680}\x{2000}\x{202f}\x{3000} + \x{3001}\x{2fff}\x{200a}\x{a0}\x{2000} + 0: \x{200a}\x{a0}\x{2000} + +/\H+/8 + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + 0: \x{9f}\x{a1}\x{2fff}\x{3001} + +/[\H\x{d7ff}]+/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+ + Ket + End +------------------------------------------------------------------ + \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f} + 0: \x{167f}\x{1681}\x{180d}\x{180f} + \x{2000}\x{200a}\x{1fff}\x{200b} + 0: \x{1fff}\x{200b} + \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060} + 0: \x{202e}\x{2030}\x{205e}\x{2060} + \x{a0}\x{3000}\x{9f}\x{a1}\x{2fff}\x{3001} + 0: \x{9f}\x{a1}\x{2fff}\x{3001} + +/\v+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/[\v\x{e000}]+/8BZ +------------------------------------------------------------------ + Bra + [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+ + Ket + End +------------------------------------------------------------------ + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/\V+/8 + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + 0: \x{09}\x{0e}\x{84}\x{86} + +/[\V\x{d7ff}]+/8BZ +------------------------------------------------------------------ + Bra + [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+ + Ket + End +------------------------------------------------------------------ + \x{2028}\x{2029}\x{2027}\x{2030} + 0: \x{2027}\x{2030} + \x{85}\x0a\x0b\x0c\x0d\x09\x0e\x{84}\x{86} + 0: \x{09}\x{0e}\x{84}\x{86} + +/\R+/8 + \x{2027}\x{2030}\x{2028}\x{2029} + 0: \x{2028}\x{2029} + \x09\x0e\x{84}\x{86}\x{85}\x0a\x0b\x0c\x0d + 0: \x{85}\x{0a}\x{0b}\x{0c}\x{0d} + +/(..)\1/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P + 0: abab + 1: ab + +/(..)\1/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P + 0: aBAb + 1: aB + +/(..)\1{2,}/8 + ab\P +Partial match: ab + aba\P +Partial match: aba + abab\P +Partial match: abab + ababa\P +Partial match: ababa + ababab\P + 0: ababab + 1: ab + ababab\P\P +Partial match: ababab + abababa\P + 0: ababab + 1: ab + abababa\P\P +Partial match: abababa + +/(..)\1{2,}/8i + ab\P +Partial match: ab + aBa\P +Partial match: aBa + aBAb\P +Partial match: aBAb + AbaBA\P +Partial match: AbaBA + abABAb\P + 0: abABAb + 1: ab + aBAbaB\P\P +Partial match: aBAbaB + abABabA\P + 0: abABab + 1: ab + abaBABa\P\P +Partial match: abaBABa + +/(..)\1{2,}?x/8i + ab\P +Partial match: ab + abA\P +Partial match: abA + aBAb\P +Partial match: aBAb + abaBA\P +Partial match: abaBA + abAbaB\P +Partial match: abAbaB + abaBabA\P +Partial match: abaBabA + abAbABaBx\P + 0: abAbABaBx + 1: ab + +/./8 + \r\P + 0: \x{0d} + \r\P\P +Partial match: \x{0d} + +/.{2,3}/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d}\x{0d} + \r\r\r\P\P +Partial match: \x{0d}\x{0d}\x{0d} + +/.{2,3}?/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d} + \r\r\r\P\P + 0: \x{0d}\x{0d} + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}] + [^\x{1234}] + [^\x{ffff}] + [^\x{10000}] + [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}][^\x{1234}][^\x{ffff}][^\x{10000}][^\x{10ffff}]/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}] + /i [^\x{1234}] + /i [^\x{ffff}] + /i [^\x{10000}] + /i [^\x{10ffff}] + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZ +------------------------------------------------------------------ + Bra + [^\x{100}]* + [^\x{10000}]+ + [^\x{10ffff}]?? + [^\x{8000}]{4} + [^\x{8000}]* + [^\x{7fff}]{2} + [^\x{7fff}]{0,7}? + [^\x{fffff}]{5} + [^\x{fffff}]?+ + Ket + End +------------------------------------------------------------------ + +/[^\x{100}]*[^\x{10000}]+[^\x{10ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{fffff}]{5,6}+/8BZi +------------------------------------------------------------------ + Bra + /i [^\x{100}]* + /i [^\x{10000}]+ + /i [^\x{10ffff}]?? + /i [^\x{8000}]{4} + /i [^\x{8000}]* + /i [^\x{7fff}]{2} + /i [^\x{7fff}]{0,7}? + Once + /i [^\x{fffff}]{5} + /i [^\x{fffff}]? + Ket + Ket + End +------------------------------------------------------------------ + +/(?<=\x{1234}\x{1234})\bxy/I8 +Capturing subpattern count = 0 +Options: utf +First char = 'x' +Need char = 'y' +Max lookbehind = 2 + +/(?8BZ +------------------------------------------------------------------ + Bra + \x{100} + Ket + End +------------------------------------------------------------------ + +/[\u0100-\u0200]/8BZ +------------------------------------------------------------------ + Bra + [\x{100}-\x{200}] + Ket + End +------------------------------------------------------------------ + +/\ud800/8 +Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5 + /-- End of testinput5 --/ diff -Nru pcre3-8.12/testdata/testoutput6 pcre3-8.31/testdata/testoutput6 --- pcre3-8.12/testdata/testoutput6 2010-10-27 09:26:16.000000000 +0000 +++ pcre3-8.31/testdata/testoutput6 2012-02-28 14:28:09.000000000 +0000 @@ -1114,6 +1114,8 @@ 0: A\x80 /^[\p{Arabic}]/8 + \x{604} + 0: \x{604} \x{60e} 0: \x{60e} \x{656} @@ -1144,8 +1146,6 @@ 0: \x{6fa} ** Failers No match - \x{600} -No match \x{650} No match \x{651} @@ -1176,8 +1176,6 @@ 0: \x{964} \x{965} 0: \x{965} - \x{970} - 0: \x{970} /^\p{Inherited}/8 \x{64b} @@ -1353,4 +1351,26 @@ a\xFCb No match +/â±¥/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/[â±¥]/8i + â±¥ + 0: \x{2c65} + Ⱥx + 0: \x{23a} + Ⱥ + 0: \x{23a} + +/Ⱥ/8i + Ⱥ + 0: \x{23a} + â±¥ + 0: \x{2c65} + /-- End of testinput6 --/ diff -Nru pcre3-8.12/testdata/testoutput7 pcre3-8.31/testdata/testoutput7 --- pcre3-8.12/testdata/testoutput7 2010-11-21 17:39:31.000000000 +0000 +++ pcre3-8.31/testdata/testoutput7 2012-06-01 18:23:30.000000000 +0000 @@ -1,7700 +1,1316 @@ -/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). - The -dfa flag must be used with pcretest when running it. --/ - -/abc/ - abc - 0: abc - -/ab*c/ - abc - 0: abc - abbbbc - 0: abbbbc - ac - 0: ac - -/ab+c/ - abc - 0: abc - abbbbbbc - 0: abbbbbbc - *** Failers -No match - ac -No match - ab -No match - -/a*/ - a - 0: a - 1: - aaaaaaaaaaaaaaaaa - 0: aaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaa - 4: aaaaaaaaaaaaa - 5: aaaaaaaaaaaa - 6: aaaaaaaaaaa - 7: aaaaaaaaaa - 8: aaaaaaaaa - 9: aaaaaaaa -10: aaaaaaa -11: aaaaaa -12: aaaaa -13: aaaa -14: aaa -15: aa -16: a -17: - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaaaaaaaaaaaaaaa - 4: aaaaaaaaaaaaaaaaaaaaaaaaaa - 5: aaaaaaaaaaaaaaaaaaaaaaaaa - 6: aaaaaaaaaaaaaaaaaaaaaaaa - 7: aaaaaaaaaaaaaaaaaaaaaaa - 8: aaaaaaaaaaaaaaaaaaaaaa - 9: aaaaaaaaaaaaaaaaaaaaa -10: aaaaaaaaaaaaaaaaaaaa -11: aaaaaaaaaaaaaaaaaaa -12: aaaaaaaaaaaaaaaaaa -13: aaaaaaaaaaaaaaaaa -14: aaaaaaaaaaaaaaaa -15: aaaaaaaaaaaaaaa -16: aaaaaaaaaaaaaa -17: aaaaaaaaaaaaa -18: aaaaaaaaaaaa -19: aaaaaaaaaaa -20: aaaaaaaaaa -21: aaaaaaaaa - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F - 0: - -/(a|abcd|african)/ - a - 0: a - abcd - 0: abcd - 1: a - african - 0: african - 1: a - -/^abc/ - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/^abc/m - abcdef - 0: abc - xyz\nabc - 0: abc - *** Failers -No match - xyzabc -No match - -/\Aabc/ - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/\Aabc/m - abcdef - 0: abc - *** Failers -No match - xyzabc -No match - xyz\nabc -No match - -/\Gabc/ - abcdef - 0: abc - xyzabc\>3 - 0: abc - *** Failers -No match - xyzabc -No match - xyzabc\>2 -No match - -/x\dy\Dz/ - x9yzz - 0: x9yzz - x0y+z - 0: x0y+z - *** Failers -No match - xyz -No match - xxy0z -No match - -/x\sy\Sz/ - x yzz - 0: x yzz - x y+z - 0: x y+z - *** Failers -No match - xyz -No match - xxyyz -No match - -/x\wy\Wz/ - xxy+z - 0: xxy+z - *** Failers -No match - xxy0z -No match - x+y+z -No match - -/x.y/ - x+y - 0: x+y - x-y - 0: x-y - *** Failers -No match - x\ny -No match - -/x.y/s - x+y - 0: x+y - x-y - 0: x-y - x\ny - 0: x\x0ay - -/(a.b(?s)c.d|x.y)p.q/ - a+bc+dp+q - 0: a+bc+dp+q - a+bc\ndp+q - 0: a+bc\x0adp+q - x\nyp+q - 0: x\x0ayp+q - *** Failers -No match - a\nbc\ndp+q -No match - a+bc\ndp\nq -No match - x\nyp\nq -No match - -/a\d\z/ - ba0 - 0: a0 - *** Failers -No match - ba0\n -No match - ba0\ncd -No match - -/a\d\z/m - ba0 - 0: a0 - *** Failers -No match - ba0\n -No match - ba0\ncd -No match - -/a\d\Z/ - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match - -/a\d\Z/m - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match - -/a\d$/ - ba0 - 0: a0 - ba0\n - 0: a0 - *** Failers -No match - ba0\ncd -No match - -/a\d$/m - ba0 - 0: a0 - ba0\n - 0: a0 - ba0\ncd - 0: a0 - *** Failers -No match - -/abc/i - abc - 0: abc - aBc - 0: aBc - ABC - 0: ABC - -/[^a]/ - abcd - 0: b - -/ab?\w/ - abz - 0: abz - 1: ab - abbz - 0: abb - 1: ab - azz - 0: az - -/x{0,3}yz/ - ayzq - 0: yz - axyzq - 0: xyz - axxyz - 0: xxyz - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - -/x{3}yz/ - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - ayzq -No match - axyzq -No match - axxyz -No match - -/x{2,3}yz/ - axxyz - 0: xxyz - axxxyzq - 0: xxxyz - axxxxyzq - 0: xxxyz - *** Failers -No match - ax -No match - axx -No match - ayzq -No match - axyzq -No match - -/[^a]+/ - bac - 0: b - bcdefax - 0: bcdef - 1: bcde - 2: bcd - 3: bc - 4: b - *** Failers - 0: *** F - 1: *** - 2: *** - 3: ** - 4: * - aaaaa -No match - -/[^a]*/ - bac - 0: b - 1: - bcdefax - 0: bcdef - 1: bcde - 2: bcd - 3: bc - 4: b - 5: - *** Failers - 0: *** F - 1: *** - 2: *** - 3: ** - 4: * - 5: - aaaaa - 0: - -/[^a]{3,5}/ - xyz - 0: xyz - awxyza - 0: wxyz - 1: wxy - abcdefa - 0: bcdef - 1: bcde - 2: bcd - abcdefghijk - 0: bcdef - 1: bcde - 2: bcd - *** Failers - 0: *** F - 1: *** - 2: *** - axya -No match - axa -No match - aaaaa -No match - -/\d*/ - 1234b567 - 0: 1234 - 1: 123 - 2: 12 - 3: 1 - 4: - xyz - 0: - -/\D*/ - a1234b567 - 0: a - 1: - xyz - 0: xyz - 1: xy - 2: x - 3: - -/\d+/ - ab1234c56 - 0: 1234 - 1: 123 - 2: 12 - 3: 1 - *** Failers -No match - xyz -No match - -/\D+/ - ab123c56 - 0: ab - 1: a - *** Failers - 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - 7: *** - 8: *** - 9: ** -10: * - 789 -No match - -/\d?A/ - 045ABC - 0: 5A - ABC - 0: A - *** Failers -No match - XYZ -No match - -/\D?A/ - ABC - 0: A - BAC - 0: BA - 9ABC - 0: A - *** Failers -No match - -/a+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/^.*xyz/ - xyz - 0: xyz - ggggggggxyz - 0: ggggggggxyz - -/^.+xyz/ - abcdxyz - 0: abcdxyz - axyz - 0: axyz - *** Failers -No match - xyz -No match - -/^.?xyz/ - xyz - 0: xyz - cxyz - 0: cxyz - -/^\d{2,3}X/ - 12X - 0: 12X - 123X - 0: 123X - *** Failers -No match - X -No match - 1X -No match - 1234X -No match - -/^[abcd]\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - *** Failers -No match - e45 -No match - abcd -No match - abcd1234 -No match - 1234 -No match - -/^[abcd]*\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - abcd1234 - 0: abcd1 - 1234 - 0: 1 - *** Failers -No match - e45 -No match - abcd -No match - -/^[abcd]+\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - abcd1234 - 0: abcd1 - *** Failers -No match - 1234 -No match - e45 -No match - abcd -No match - -/^a+X/ - aX - 0: aX - aaX - 0: aaX - -/^[abcd]?\d/ - a45 - 0: a4 - b93 - 0: b9 - c99z - 0: c9 - d04 - 0: d0 - 1234 - 0: 1 - *** Failers -No match - abcd1234 -No match - e45 -No match - -/^[abcd]{2,3}\d/ - ab45 - 0: ab4 - bcd93 - 0: bcd9 - *** Failers -No match - 1234 -No match - a36 -No match - abcd1234 -No match - ee45 -No match - -/^(abc)*\d/ - abc45 - 0: abc4 - abcabcabc45 - 0: abcabcabc4 - 42xyz - 0: 4 - *** Failers -No match - -/^(abc)+\d/ - abc45 - 0: abc4 - abcabcabc45 - 0: abcabcabc4 - *** Failers -No match - 42xyz -No match - -/^(abc)?\d/ - abc45 - 0: abc4 - 42xyz - 0: 4 - *** Failers -No match - abcabcabc45 -No match - -/^(abc){2,3}\d/ - abcabc45 - 0: abcabc4 - abcabcabc45 - 0: abcabcabc4 - *** Failers -No match - abcabcabcabc45 -No match - abc45 -No match - 42xyz -No match - -/1(abc|xyz)2(?1)3/ - 1abc2abc3456 - 0: 1abc2abc3 - 1abc2xyz3456 - 0: 1abc2xyz3 - -/^(a*\w|ab)=(a*\w|ab)/ - ab=ab - 0: ab=ab - 1: ab=a - -/^(a*\w|ab)=(?1)/ - ab=ab - 0: ab=ab - -/^([^()]|\((?1)*\))*$/ - abc - 0: abc - a(b)c - 0: a(b)c - a(b(c))d - 0: a(b(c))d - *** Failers) -No match - a(b(c)d -No match - -/^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)a*)\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9 - *** Failers -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x - <> - 0: <> - - 0: - hij> - 0: hij> - hij> - 0: - def> - 0: def> - - 0: <> - *** Failers -No match - abcxyz - 1 ^ ^ x - 0: abcxyz - 123abcxyz999 ---->123abcxyz999 - 1 ^ ^ x - 0: abcxyz - -/(ab|cd){3,4}/C - ababab ---->ababab - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - 0: ababab - abcdabcd ---->abcdabcd - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) - +1 ^ ^ a - +4 ^ ^ c - +2 ^ ^ b - +3 ^ ^ | -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - 0: abcdabcd - 1: abcdab - abcdcdcdcdcd ---->abcdcdcdcdcd - +0 ^ (ab|cd){3,4} - +1 ^ a - +4 ^ c - +2 ^^ b - +3 ^ ^ | - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - +1 ^ ^ a - +4 ^ ^ c - +5 ^ ^ d - +6 ^ ^ ) -+12 ^ ^ - 0: abcdcdcd - 1: abcdcd - -/^abc/ - abcdef - 0: abc - *** Failers -No match - abcdef\B -No match - -/^(a*|xyz)/ - bcd - 0: - aaabcd - 0: aaa - 1: aa - 2: a - 3: - xyz - 0: xyz - 1: - xyz\N - 0: xyz - *** Failers - 0: - bcd\N -No match - -/xyz$/ - xyz - 0: xyz - xyz\n - 0: xyz - *** Failers -No match - xyz\Z -No match - xyz\n\Z -No match - -/xyz$/m - xyz - 0: xyz - xyz\n - 0: xyz - abcxyz\npqr - 0: xyz - abcxyz\npqr\Z - 0: xyz - xyz\n\Z - 0: xyz - *** Failers -No match - xyz\Z -No match - -/\Gabc/ - abcdef - 0: abc - defabcxyz\>3 - 0: abc - *** Failers -No match - defabcxyz -No match - -/^abcdef/ - ab\P -Partial match: ab - abcde\P -Partial match: abcde - abcdef\P - 0: abcdef - *** Failers -No match - abx\P -No match - -/^a{2,4}\d+z/ - a\P -Partial match: a - aa\P -Partial match: aa - aa2\P -Partial match: aa2 - aaa\P -Partial match: aaa - aaa23\P -Partial match: aaa23 - aaaa12345\P -Partial match: aaaa12345 - aa0z\P - 0: aa0z - aaaa4444444444444z\P - 0: aaaa4444444444444z - *** Failers -No match - az\P -No match - aaaaa\P -No match - a56\P -No match - -/^abcdef/ - abc\P -Partial match: abc - def\R - 0: def - -/(?<=foo)bar/ - xyzfo\P -No match - foob\P\>2 -Partial match: foob - foobar...\R\P\>4 - 0: ar - xyzfo\P -No match - foobar\>2 - 0: bar - *** Failers -No match - xyzfo\P -No match - obar\R -No match - -/(ab*(cd|ef))+X/ - adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z -No match - lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z -Partial match: abbbbbbcdaefabbbbbbbefa - cdabbbbbbbb\P\R\B\Z -Partial match: cdabbbbbbbb - efabbbbbbbbbbbbbbbb\P\R\B\Z -Partial match: efabbbbbbbbbbbbbbbb - bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z - 0: bbbbbbbbbbbbcdX - -/(a|b)/SF>testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex ->>aaabxyzpqrrrabbxyyyypqAzz - 0: aaabxyzpqrrrabbxyyyypqAzz - >aaaabxyzpqrrrabbxyyyypqAzz - 0: aaaabxyzpqrrrabbxyyyypqAzz - >>>>abcxyzpqrrrabbxyyyypqAzz - 0: abcxyzpqrrrabbxyyyypqAzz - *** Failers -No match - abxyzpqrrabbxyyyypqAzz -No match - abxyzpqrrrrabbxyyyypqAzz -No match - abxyzpqrrrabxyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyypqAzz -No match - aaabcxyzpqrrrabbxyyyypqqqqqqqAzz -No match - -/^(abc){1,2}zz/ - abczz - 0: abczz - abcabczz - 0: abcabczz - *** Failers -No match - zz -No match - abcabcabczz -No match - >>abczz -No match - -/^(b+?|a){1,2}?c/ - bc - 0: bc - bbc - 0: bbc - bbbc - 0: bbbc - bac - 0: bac - bbac - 0: bbac - aac - 0: aac - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - *** Failers -No match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}c/ - bc - 0: bc - bbc - 0: bbc - bbbc - 0: bbbc - bac - 0: bac - bbac - 0: bbac - aac - 0: aac - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - *** Failers -No match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}?bc/ - bbc - 0: bbc - -/^(b*|ba){1,2}?bc/ - babc - 0: babc - bbabc - 0: bbabc - bababc - 0: bababc - *** Failers -No match - bababbc -No match - babababc -No match - -/^(ba|b*){1,2}?bc/ - babc - 0: babc - bbabc - 0: bbabc - bababc - 0: bababc - *** Failers -No match - bababbc -No match - babababc -No match - -/^\ca\cA\c[\c{\c:/ - \x01\x01\e;z - 0: \x01\x01\x1b;z - -/^[ab\]cde]/ - athing - 0: a - bthing - 0: b - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e - *** Failers -No match - fthing -No match - [thing -No match - \\thing -No match - -/^[]cde]/ - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e - *** Failers -No match - athing -No match - fthing -No match - -/^[^ab\]cde]/ - fthing - 0: f - [thing - 0: [ - \\thing - 0: \ - *** Failers - 0: * - athing -No match - bthing -No match - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -/^[^]cde]/ - athing - 0: a - fthing - 0: f - *** Failers - 0: * - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -/^\/ - - 0: \x81 - -/^ÿ/ - ÿ - 0: \xff - -/^[0-9]+$/ - 0 - 0: 0 - 1 - 0: 1 - 2 - 0: 2 - 3 - 0: 3 - 4 - 0: 4 - 5 - 0: 5 - 6 - 0: 6 - 7 - 0: 7 - 8 - 0: 8 - 9 - 0: 9 - 10 - 0: 10 - 100 - 0: 100 - *** Failers -No match - abc -No match - -/^.*nter/ - enter - 0: enter - inter - 0: inter - uponter - 0: uponter - -/^xxx[0-9]+$/ - xxx0 - 0: xxx0 - xxx1234 - 0: xxx1234 - *** Failers -No match - xxx -No match - -/^.+[0-9][0-9][0-9]$/ - x123 - 0: x123 - xx123 - 0: xx123 - 123456 - 0: 123456 - *** Failers -No match - 123 -No match - x1234 - 0: x1234 - -/^.+?[0-9][0-9][0-9]$/ - x123 - 0: x123 - xx123 - 0: xx123 - 123456 - 0: 123456 - *** Failers -No match - 123 -No match - x1234 - 0: x1234 - -/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ - abc!pqr=apquxz.ixr.zzz.ac.uk - 0: abc!pqr=apquxz.ixr.zzz.ac.uk - *** Failers -No match - !pqr=apquxz.ixr.zzz.ac.uk -No match - abc!=apquxz.ixr.zzz.ac.uk -No match - abc!pqr=apquxz:ixr.zzz.ac.uk -No match - abc!pqr=apquxz.ixr.zzz.ac.ukk -No match - -/:/ - Well, we need a colon: somewhere - 0: : - *** Fail if we don't -No match - -/([\da-f:]+)$/i - 0abc - 0: 0abc - abc - 0: abc - fed - 0: fed - E - 0: E - :: - 0: :: - 5f03:12C0::932e - 0: 5f03:12C0::932e - fed def - 0: def - Any old stuff - 0: ff - *** Failers -No match - 0zzz -No match - gzzz -No match - fed\x20 -No match - Any old rubbish -No match - -/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ - .1.2.3 - 0: .1.2.3 - A.12.123.0 - 0: A.12.123.0 - *** Failers -No match - .1.2.3333 -No match - 1.2.3 -No match - 1234.2.3 -No match - -/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ - 1 IN SOA non-sp1 non-sp2( - 0: 1 IN SOA non-sp1 non-sp2( - 1 IN SOA non-sp1 non-sp2 ( - 0: 1 IN SOA non-sp1 non-sp2 ( - *** Failers -No match - 1IN SOA non-sp1 non-sp2( -No match - -/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ - a. - 0: a. - Z. - 0: Z. - 2. - 0: 2. - ab-c.pq-r. - 0: ab-c.pq-r. - sxk.zzz.ac.uk. - 0: sxk.zzz.ac.uk. - x-.y-. - 0: x-.y-. - *** Failers -No match - -abc.peq. -No match - -/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ - *.a - 0: *.a - *.b0-a - 0: *.b0-a - *.c3-b.c - 0: *.c3-b.c - *.c-a.b-c - 0: *.c-a.b-c - *** Failers -No match - *.0 -No match - *.a- -No match - *.a-b.c- -No match - *.c-a.0-c -No match - -/^(?=ab(de))(abd)(e)/ - abde - 0: abde - -/^(?!(ab)de|x)(abd)(f)/ - abdf - 0: abdf - -/^(?=(ab(cd)))(ab)/ - abcd - 0: ab - -/^[\da-f](\.[\da-f])*$/i - a.b.c.d - 0: a.b.c.d - A.B.C.D - 0: A.B.C.D - a.b.c.1.2.3.C - 0: a.b.c.1.2.3.C - -/^\".*\"\s*(;.*)?$/ - \"1234\" - 0: "1234" - \"abcd\" ; - 0: "abcd" ; - \"\" ; rhubarb - 0: "" ; rhubarb - *** Failers -No match - \"1234\" : things -No match - -/^$/ - \ - 0: - *** Failers -No match - -/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x - ab c - 0: ab c - *** Failers -No match - abc -No match - ab cde -No match - -/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ - ab c - 0: ab c - *** Failers -No match - abc -No match - ab cde -No match - -/^ a\ b[c ]d $/x - a bcd - 0: a bcd - a b d - 0: a b d - *** Failers -No match - abcd -No match - ab d -No match - -/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - -/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - -/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ - a+ Z0+\x08\n\x1d\x12 - 0: a+ Z0+\x08\x0a\x1d\x12 - -/^[.^$|()*+?{,}]+/ - .^\$(*+)|{?,?} - 0: .^$(*+)|{?,?} - 1: .^$(*+)|{?,? - 2: .^$(*+)|{?, - 3: .^$(*+)|{? - 4: .^$(*+)|{ - 5: .^$(*+)| - 6: .^$(*+) - 7: .^$(*+ - 8: .^$(* - 9: .^$( -10: .^$ -11: .^ -12: . - -/^a*\w/ - z - 0: z - az - 0: az - 1: a - aaaz - 0: aaaz - 1: aaa - 2: aa - 3: a - a - 0: a - aa - 0: aa - 1: a - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - a+ - 0: a - aa+ - 0: aa - 1: a - -/^a*?\w/ - z - 0: z - az - 0: az - 1: a - aaaz - 0: aaaz - 1: aaa - 2: aa - 3: a - a - 0: a - aa - 0: aa - 1: a - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - a+ - 0: a - aa+ - 0: aa - 1: a - -/^a+\w/ - az - 0: az - aaaz - 0: aaaz - 1: aaa - 2: aa - aa - 0: aa - aaaa - 0: aaaa - 1: aaa - 2: aa - aa+ - 0: aa - -/^a+?\w/ - az - 0: az - aaaz - 0: aaaz - 1: aaa - 2: aa - aa - 0: aa - aaaa - 0: aaaa - 1: aaa - 2: aa - aa+ - 0: aa - -/^\d{8}\w{2,}/ - 1234567890 - 0: 1234567890 - 12345678ab - 0: 12345678ab - 12345678__ - 0: 12345678__ - *** Failers -No match - 1234567 -No match - -/^[aeiou\d]{4,5}$/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 12345 - aaaaa - 0: aaaaa - *** Failers -No match - 123456 -No match - -/^[aeiou\d]{4,5}?/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 12345 - 1: 1234 - aaaaa - 0: aaaaa - 1: aaaa - 123456 - 0: 12345 - 1: 1234 - -/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - -/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - From abcd Mon Sep 1 12:33:02 1997 - 0: From abcd Mon Sep 1 12:33 - *** Failers -No match - From abcd Sep 01 12:33:02 1997 -No match - -/^12.34/s - 12\n34 - 0: 12\x0a34 - 12\r34 - 0: 12\x0d34 - -/\w+(?=\t)/ - the quick brown\t fox - 0: brown - -/foo(?!bar)(.*)/ - foobar is foolish see? - 0: foolish see? - 1: foolish see - 2: foolish se - 3: foolish s - 4: foolish - 5: foolish - 6: foolis - 7: fooli - 8: fool - 9: foo - -/(?:(?!foo)...|^.{0,2})bar(.*)/ - foobar crowbar etc - 0: rowbar etc - 1: rowbar et - 2: rowbar e - 3: rowbar - 4: rowbar - barrel - 0: barrel - 1: barre - 2: barr - 3: bar - 2barrel - 0: 2barrel - 1: 2barre - 2: 2barr - 3: 2bar - A barrel - 0: A barrel - 1: A barre - 2: A barr - 3: A bar - -/^(\D*)(?=\d)(?!123)/ - abc456 - 0: abc - *** Failers -No match - abc123 -No match - -/^1234(?# test newlines - inside)/ - 1234 - 0: 1234 - -/^1234 #comment in extended re - /x - 1234 - 0: 1234 - -/#rhubarb - abcd/x - abcd - 0: abcd - -/^abcd#rhubarb/x - abcd - 0: abcd - -/(?!^)abc/ - the abc - 0: abc - *** Failers -No match - abc -No match - -/(?=^)abc/ - abc - 0: abc - *** Failers -No match - the abc -No match - -/^[ab]{1,3}(ab*|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}?(ab*|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}?(ab*?|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/^[ab]{1,3}(ab*?|b)/ - aabbbbb - 0: aabbbbb - 1: aabbbb - 2: aabbb - 3: aabb - 4: aab - 5: aa - -/ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional leading comment -(?: (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # one word, optionally followed by.... -(?: -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... -\( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) | # comments, or... - -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -# quoted strings -)* -< (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # leading < -(?: @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* - -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* , (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -)* # further okay, if led by comma -: # closing colon -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* )? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address spec -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* > # trailing > -# name and address -) (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional trailing comment -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - 1: user@dom - user\@dom.ain - 0: user@dom.ain - 1: user@dom - \"A. Other\" (a comment) - 0: "A. Other" (a comment) - 1: "A. Other" - 2: "A. Other" - A. Other (a comment) - 0: Other (a comment) - 1: Other - 2: Other - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re - A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -# leading word -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces -(?: -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -| -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -) # "special" comment or quoted string -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" -)* -< -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# < -(?: -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -(?: , -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -)* # additional domains -: -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address spec -> # > -# name and address -) -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - 1: user@dom - user\@dom.ain - 0: user@dom.ain - 1: user@dom - \"A. Other\" (a comment) - 0: "A. Other" - A. Other (a comment) - 0: Other - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re - A missing angle - a\rb - 0: a\x0db - *** Failers -No match - a\nb -No match - -/abc$/ - abc - 0: abc - abc\n - 0: abc - *** Failers -No match - abc\ndef -No match - -/(abc)\123/ - abc\x53 - 0: abcS - -/(abc)\223/ - abc\x93 - 0: abc\x93 - -/(abc)\323/ - abc\xd3 - 0: abc\xd3 - -/(abc)\100/ - abc\x40 - 0: abc@ - abc\100 - 0: abc@ - -/(abc)\1000/ - abc\x400 - 0: abc@0 - abc\x40\x30 - 0: abc@0 - abc\1000 - 0: abc@0 - abc\100\x30 - 0: abc@0 - abc\100\060 - 0: abc@0 - abc\100\60 - 0: abc@0 - -/abc\81/ - abc\081 - 0: abc\x0081 - abc\0\x38\x31 - 0: abc\x0081 - -/abc\91/ - abc\091 - 0: abc\x0091 - abc\0\x39\x31 - 0: abc\x0091 - -/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ - abcdefghijk\12S - 0: abcdefghijk\x0aS - -/ab\idef/ - abidef - 0: abidef - -/a{0}bc/ - bc - 0: bc - -/(a|(bc)){0,0}?xyz/ - xyz - 0: xyz - -/abc[\10]de/ - abc\010de - 0: abc\x08de - -/abc[\1]de/ - abc\1de - 0: abc\x01de - -/(abc)[\1]de/ - abc\1de - 0: abc\x01de - -/(?s)a.b/ - a\nb - 0: a\x0ab - -/^([^a])([^\b])([^c]*)([^d]{3,4})/ - baNOTccccd - 0: baNOTcccc - 1: baNOTccc - 2: baNOTcc - 3: baNOTc - 4: baNOT - baNOTcccd - 0: baNOTccc - 1: baNOTcc - 2: baNOTc - 3: baNOT - baNOTccd - 0: baNOTcc - 1: baNOTc - 2: baNOT - bacccd - 0: baccc - *** Failers - 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - anything -No match - b\bc -No match - baccd -No match - -/[^a]/ - Abc - 0: A - -/[^a]/i - Abc - 0: b - -/[^a]+/ - AAAaAbc - 0: AAA - 1: AA - 2: A - -/[^a]+/i - AAAaAbc - 0: bc - 1: b - -/[^a]+/ - bbb\nccc - 0: bbb\x0accc - 1: bbb\x0acc - 2: bbb\x0ac - 3: bbb\x0a - 4: bbb - 5: bb - 6: b - -/[^k]$/ - abc - 0: c - *** Failers - 0: s - abk -No match - -/[^k]{2,3}$/ - abc - 0: abc - kbc - 0: bc - kabc - 0: abc - *** Failers - 0: ers - abk -No match - akb -No match - akk -No match - -/^\d{8,}\@.+[^k]$/ - 12345678\@a.b.c.d - 0: 12345678@a.b.c.d - 123456789\@x.y.z - 0: 123456789@x.y.z - *** Failers -No match - 12345678\@x.y.uk -No match - 1234567\@a.b.c.d -No match - -/[^a]/ - aaaabcd - 0: b - aaAabcd - 0: A - -/[^a]/i - aaaabcd - 0: b - aaAabcd - 0: b - -/[^az]/ - aaaabcd - 0: b - aaAabcd - 0: A - -/[^az]/i - aaaabcd - 0: b - aaAabcd - 0: b - -/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ - \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 - 0: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff - -/P[^*]TAIRE[^*]{1,6}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/P[^*]TAIRE[^*]{1,}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/(\.\d\d[1-9]?)\d+/ - 1.230003938 - 0: .230003938 - 1: .23000393 - 2: .2300039 - 3: .230003 - 4: .23000 - 5: .2300 - 6: .230 - 1.875000282 - 0: .875000282 - 1: .87500028 - 2: .8750002 - 3: .875000 - 4: .87500 - 5: .8750 - 6: .875 - 1.235 - 0: .235 - -/(\.\d\d((?=0)|\d(?=\d)))/ - 1.230003938 - 0: .230 - 1: .23 - 1.875000282 - 0: .875 - *** Failers -No match - 1.235 -No match - -/a(?)b/ - ab - 0: ab - -/\b(foo)\s+(\w+)/i - Food is on the foo table - 0: foo table - 1: foo tabl - 2: foo tab - 3: foo ta - 4: foo t - -/foo(.*)bar/ - The food is under the bar in the barn. - 0: food is under the bar in the bar - 1: food is under the bar - -/foo(.*?)bar/ - The food is under the bar in the barn. - 0: food is under the bar in the bar - 1: food is under the bar - -/(.*)(\d*)/ - I have 2 numbers: 53147 -Matched, but too many subsidiary matches - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 numbers: - 6: I have 2 numbers: - 7: I have 2 numbers - 8: I have 2 number - 9: I have 2 numbe -10: I have 2 numb -11: I have 2 num -12: I have 2 nu -13: I have 2 n -14: I have 2 -15: I have 2 -16: I have -17: I have -18: I hav -19: I ha -20: I h -21: I - -/(.*)(\d+)/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 - -/(.*?)(\d*)/ - I have 2 numbers: 53147 -Matched, but too many subsidiary matches - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 numbers: - 6: I have 2 numbers: - 7: I have 2 numbers - 8: I have 2 number - 9: I have 2 numbe -10: I have 2 numb -11: I have 2 num -12: I have 2 nu -13: I have 2 n -14: I have 2 -15: I have 2 -16: I have -17: I have -18: I hav -19: I ha -20: I h -21: I - -/(.*?)(\d+)/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: I have 2 numbers: 531 - 3: I have 2 numbers: 53 - 4: I have 2 numbers: 5 - 5: I have 2 - -/(.*)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*?)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*)\b(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/(.*\D)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - -/^\D*(?!123)/ - ABC123 - 0: AB - 1: A - 2: - -/^(\D*)(?=\d)(?!123)/ - ABC445 - 0: ABC - *** Failers -No match - ABC123 -No match - -/^[W-]46]/ - W46]789 - 0: W46] - -46]789 - 0: -46] - *** Failers -No match - Wall -No match - Zebra -No match - 42 -No match - [abcd] -No match - ]abcd[ -No match - -/^[W-\]46]/ - W46]789 - 0: W - Wall - 0: W - Zebra - 0: Z - Xylophone - 0: X - 42 - 0: 4 - [abcd] - 0: [ - ]abcd[ - 0: ] - \\backslash - 0: \ - *** Failers -No match - -46]789 -No match - well -No match - -/\d\d\/\d\d\/\d\d\d\d/ - 01/01/2000 - 0: 01/01/2000 - -/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match - -/^(a){0,0}/ - bcd - 0: - abc - 0: - aab - 0: - -/^(a){0,1}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: a - 1: - -/^(a){0,2}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - -/^(a){0,3}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - aaa - 0: aaa - 1: aa - 2: a - 3: - -/^(a){0,}/ - bcd - 0: - abc - 0: a - 1: - aab - 0: aa - 1: a - 2: - aaa - 0: aaa - 1: aa - 2: a - 3: - aaaaaaaa - 0: aaaaaaaa - 1: aaaaaaa - 2: aaaaaa - 3: aaaaa - 4: aaaa - 5: aaa - 6: aa - 7: a - 8: - -/^(a){1,1}/ - bcd -No match - abc - 0: a - aab - 0: a - -/^(a){1,2}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - -/^(a){1,3}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: aa - 2: a - -/^(a){1,}/ - bcd -No match - abc - 0: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: aa - 2: a - aaaaaaaa - 0: aaaaaaaa - 1: aaaaaaa - 2: aaaaaa - 3: aaaaa - 4: aaaa - 5: aaa - 6: aa - 7: a - -/.*\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.{0,}\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/m - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*\.gif/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*$/ - borfle\nbib.gif\nno - 0: no - -/.*$/m - borfle\nbib.gif\nno - 0: borfle - -/.*$/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - -/.*$/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - 1: borfle\x0abib.gif - 2: borfle - -/.*$/ - borfle\nbib.gif\nno\n - 0: no - -/.*$/m - borfle\nbib.gif\nno\n - 0: borfle - -/.*$/s - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - 1: borfle\x0abib.gif\x0ano - -/.*$/ms - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - 1: borfle\x0abib.gif\x0ano - 2: borfle\x0abib.gif - 3: borfle - -/(.*X|^B)/ - abcde\n1234Xyz - 0: 1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(.*X|^B)/m - abcde\n1234Xyz - 0: 1234X - BarFoo - 0: B - abcde\nBar - 0: B - -/(.*X|^B)/s - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(.*X|^B)/ms - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - abcde\nBar - 0: B - -/(?s)(.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/(?s:.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B - *** Failers -No match - abcde\nBar -No match - -/^.*B/ - **** Failers -No match - abc\nB -No match - -/(?s)^.*B/ - abc\nB - 0: abc\x0aB - -/(?m)^.*B/ - abc\nB - 0: B - -/(?ms)^.*B/ - abc\nB - 0: abc\x0aB - -/(?ms)^B/ - abc\nB - 0: B - -/(?s)B$/ - B\n - 0: B - -/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ - 123456654321 - 0: 123456654321 - -/^\d\d\d\d\d\d\d\d\d\d\d\d/ - 123456654321 - 0: 123456654321 - -/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ - 123456654321 - 0: 123456654321 - -/^[abc]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^[a-c]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^(a|b|c){12}/ - abcabcabcabc - 0: abcabcabcabc - -/^[abcdefghijklmnopqrstuvwxy0123456789]/ - n - 0: n - *** Failers -No match - z -No match - -/abcde{0,0}/ - abcd - 0: abcd - *** Failers -No match - abce -No match - -/ab[cd]{0,0}e/ - abe - 0: abe - *** Failers -No match - abcde -No match - -/ab(c){0,0}d/ - abd - 0: abd - *** Failers -No match - abcd -No match - -/a(b*)/ - a - 0: a - ab - 0: ab - 1: a - abbbb - 0: abbbb - 1: abbb - 2: abb - 3: ab - 4: a - *** Failers - 0: a - bbbbb -No match - -/ab\d{0}e/ - abe - 0: abe - *** Failers -No match - ab1e -No match - -/"([^\\"]+|\\.)*"/ - the \"quick\" brown fox - 0: "quick" - \"the \\\"quick\\\" brown fox\" - 0: "the \"quick\" brown fox" - -/.*?/g+ - abc - 0: abc - 0+ - 1: ab - 2: a - 3: - 0: - 0+ - -/\b/g+ - abc - 0: - 0+ abc - 0: - 0+ - -/\b/+g - abc - 0: - 0+ abc - 0: - 0+ - -//g - abc - 0: - 0: - 0: - 0: - -/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is - 43.
    Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide - 0: 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide - -/a[^a]b/ - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/ - acb - 0: acb - *** Failers -No match - a\nb -No match - -/a[^a]b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/^(b+?|a){1,2}?c/ - bac - 0: bac - bbac - 0: bbac - bbbac - 0: bbbac - bbbbac - 0: bbbbac - bbbbbac - 0: bbbbbac - -/^(b+|a){1,2}?c/ - bac - 0: bac - bbac - 0: bbac - bbbac - 0: bbbac - bbbbac - 0: bbbbac - bbbbbac - 0: bbbbbac - -/(?!\A)x/m - x\nb\n -No match - a\bx\n - 0: x - -/\x0{ab}/ - \0{ab} - 0: \x00{ab} - -/(A|B)*?CD/ - CD - 0: CD - -/(A|B)*CD/ - CD - 0: CD - -/(?.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ -No match - -"(?>.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - -/(?>(\.\d\d[1-9]?))\d+/ - 1.230003938 - 0: .230003938 - 1: .23000393 - 2: .2300039 - 3: .230003 - 4: .23000 - 5: .2300 - 6: .230 - 1.875000282 - 0: .875000282 - 1: .87500028 - 2: .8750002 - 3: .875000 - 4: .87500 - 5: .8750 - *** Failers -No match - 1.235 -No match - -/^((?>\w+)|(?>\s+))*$/ - now is the time for all good men to come to the aid of the party - 0: now is the time for all good men to come to the aid of the party - *** Failers -No match - this is not a line with only words and spaces! -No match - -/(\d+)(\w)/ - 12345a - 0: 12345a - 1: 12345 - 2: 1234 - 3: 123 - 4: 12 - 12345+ - 0: 12345 - 1: 1234 - 2: 123 - 3: 12 - -/((?>\d+))(\w)/ - 12345a - 0: 12345a - *** Failers -No match - 12345+ -No match - -/(?>a+)b/ - aaab - 0: aaab - -/((?>a+)b)/ - aaab - 0: aaab - -/(?>(a+))b/ - aaab - 0: aaab - -/(?>b)+/ - aaabbbccc - 0: bbb - 1: bb - 2: b - -/(?>a+|b+|c+)*c/ - aaabbbbccccd - 0: aaabbbbcccc - 1: aaabbbbc - -/(a+|b+|c+)*c/ - aaabbbbccccd - 0: aaabbbbcccc - 1: aaabbbbccc - 2: aaabbbbcc - 3: aaabbbbc - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: abc(ade)ufh()() - 2: abc(ade)ufh() - 3: abc(ade)ufh - 4: abc(ade) - 5: abc - -/\(((?>[^()]+)|\([^()]+\))+\)/ - (abc) - 0: (abc) - (abc(def)xyz) - 0: (abc(def)xyz) - *** Failers -No match - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/a(?-i)b/i - ab - 0: ab - Ab - 0: Ab - *** Failers -No match - aB -No match - AB -No match - -/(a (?x)b c)d e/ - a bcd e - 0: a bcd e - *** Failers -No match - a b cd e -No match - abcd e -No match - a bcde -No match - -/(a b(?x)c d (?-x)e f)/ - a bcde f - 0: a bcde f - *** Failers -No match - abcdef -No match - -/(a(?i)b)c/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - abC -No match - aBC -No match - Abc -No match - ABc -No match - ABC -No match - AbC -No match - -/a(?i:b)c/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - ABC -No match - abC -No match - aBC -No match - -/a(?i:b)*c/ - aBc - 0: aBc - aBBc - 0: aBBc - *** Failers -No match - aBC -No match - aBBC -No match - -/a(?=b(?i)c)\w\wd/ - abcd - 0: abcd - abCd - 0: abCd - *** Failers -No match - aBCd -No match - abcD -No match - -/(?s-i:more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million - *** Failers -No match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?:(?s-i)more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million - *** Failers -No match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?>a(?i)b+)+c/ - abc - 0: abc - aBbc - 0: aBbc - aBBc - 0: aBBc - *** Failers -No match - Abc -No match - abAb -No match - abbC -No match - -/(?=a(?i)b)\w\wc/ - abc - 0: abc - aBc - 0: aBc - *** Failers -No match - Ab -No match - abC -No match - aBC -No match - -/(?<=a(?i)b)(\w\w)c/ - abxxc - 0: xxc - aBxxc - 0: xxc - *** Failers -No match - Abxxc -No match - ABxxc -No match - abxxC -No match - -/^(?(?=abc)\w{3}:|\d\d)$/ - abc: - 0: abc: - 12 - 0: 12 - *** Failers -No match - 123 -No match - xyz -No match - -/^(?(?!abc)\d\d|\w{3}:)$/ - abc: - 0: abc: - 12 - 0: 12 - *** Failers -No match - 123 -No match - xyz -No match - -/(?(?<=foo)bar|cat)/ - foobar - 0: bar - cat - 0: cat - fcat - 0: cat - focat - 0: cat - *** Failers -No match - foocat -No match - -/(?(?a*)*/ - a - 0: a - 1: - aa - 0: aa - 1: - aaaa - 0: aaaa - 1: - -/(abc|)+/ - abc - 0: abc - 1: - abcabc - 0: abcabc - 1: abc - 2: - abcabcabc - 0: abcabcabc - 1: abcabc - 2: abc - 3: - xyz - 0: - -/([a]*)*/ - a - 0: a - 1: - aaaaa - 0: aaaaa - 1: aaaa - 2: aaa - 3: aa - 4: a - 5: - -/([ab]*)*/ - a - 0: a - 1: - b - 0: b - 1: - ababab - 0: ababab - 1: ababa - 2: abab - 3: aba - 4: ab - 5: a - 6: - aaaabcde - 0: aaaab - 1: aaaa - 2: aaa - 3: aa - 4: a - 5: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - -/([^a]*)*/ - b - 0: b - 1: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - aaa - 0: - -/([^ab]*)*/ - cccc - 0: cccc - 1: ccc - 2: cc - 3: c - 4: - abab - 0: - -/([a]*?)*/ - a - 0: a - 1: - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/([ab]*?)*/ - a - 0: a - 1: - b - 0: b - 1: - abab - 0: abab - 1: aba - 2: ab - 3: a - 4: - baba - 0: baba - 1: bab - 2: ba - 3: b - 4: - -/([^a]*?)*/ - b - 0: b - 1: - bbbb - 0: bbbb - 1: bbb - 2: bb - 3: b - 4: - aaa - 0: - -/([^ab]*?)*/ - c - 0: c - 1: - cccc - 0: cccc - 1: ccc - 2: cc - 3: c - 4: - baba - 0: - -/(?>a*)*/ - a - 0: a - 1: - aaabcde - 0: aaa - 1: - -/((?>a*))*/ - aaaaa - 0: aaaaa - 1: - aabbaa - 0: aa - 1: - -/((?>a*?))*/ - aaaaa - 0: aaaaa - 1: - aabbaa - 0: aa - 1: - -/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x - 12-sep-98 - 0: 12-sep-98 - 12-09-98 - 0: 12-09-98 - *** Failers -No match - sep-12-98 -No match - -/(?i:saturday|sunday)/ - saturday - 0: saturday - sunday - 0: sunday - Saturday - 0: Saturday - Sunday - 0: Sunday - SATURDAY - 0: SATURDAY - SUNDAY - 0: SUNDAY - SunDay - 0: SunDay - -/(a(?i)bc|BB)x/ - abcx - 0: abcx - aBCx - 0: aBCx - bbx - 0: bbx - BBx - 0: BBx - *** Failers -No match - abcX -No match - aBCX -No match - bbX -No match - BBX -No match - -/^([ab](?i)[cd]|[ef])/ - ac - 0: ac - aC - 0: aC - bD - 0: bD - elephant - 0: e - Europe - 0: E - frog - 0: f - France - 0: F - *** Failers -No match - Africa -No match - -/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ - ab - 0: ab - aBd - 0: aBd - xy - 0: xy - xY - 0: xY - zebra - 0: z - Zambesi - 0: Z - *** Failers -No match - aCD -No match - XY -No match - -/(?<=foo\n)^bar/m - foo\nbar - 0: bar - *** Failers -No match - bar -No match - baz\nbar -No match - -/(?<=(?]&/ - <&OUT - 0: <& - -/(?:(f)(o)(o)|(b)(a)(r))*/ - foobar - 0: foobar - 1: foo - 2: - -/(?<=a)b/ - ab - 0: b - *** Failers -No match - cb -No match - b -No match - -/(?a+)ab/ - -/(?>a+)b/ - aaab - 0: aaab - -/([[:]+)/ - a:[b]: - 0: :[ - 1: : - -/([[=]+)/ - a=[b]= - 0: =[ - 1: = - -/([[.]+)/ - a.[b]. - 0: .[ - 1: . - -/((?>a+)b)/ - aaab - 0: aaab - -/(?>(a+))b/ - aaab - 0: aaab - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: abc(ade)ufh()() - 2: abc(ade)ufh() - 3: abc(ade)ufh - 4: abc(ade) - 5: abc +/[\p{^L}]/DZ +------------------------------------------------------------------ + Bra + [\P{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/a\Z/ - *** Failers -No match - aaab -No match - a\nb\n -No match +/[\P{L}]/DZ +------------------------------------------------------------------ + Bra + [\P{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/b\Z/ - a\nb\n - 0: b +/[\P{^L}]/DZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +No options +No first char +No need char -/b\z/ +/[abc\p{L}\x{0660}]/8DZ +------------------------------------------------------------------ + Bra + [a-c\p{L}\x{660}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char -/b\Z/ - a\nb - 0: b +/[\p{Nd}]/8DZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + 1234 + 0: 1 -/b\z/ - a\nb - 0: b - *** Failers -No match - -/(?>.*)(?<=(abcd|wxyz))/ - alphabetabcd - 0: alphabetabcd - endingwxyz - 0: endingwxyz - *** Failers +/[\p{Nd}+-]+/8DZ +------------------------------------------------------------------ + Bra + [+\-\p{Nd}]+ + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: utf +No first char +No need char + 1234 + 0: 1234 + 12-34 + 0: 12-34 + 12+\x{661}-34 + 0: 12+\x{661}-34 + ** Failers No match - a rather long string that doesn't end with one of them + abcd No match -/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match +/[\x{105}-\x{109}]/8iDZ +------------------------------------------------------------------ + Bra + [\x{104}-\x{109}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + \x{104} + 0: \x{104} + \x{105} + 0: \x{105} + \x{109} + 0: \x{109} + ** Failers +No match + \x{100} +No match + \x{10a} +No match + +/[z-\x{100}]/8iDZ +------------------------------------------------------------------ + Bra + [Z\x{39c}\x{178}z-\x{101}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char + Z + 0: Z + z + 0: z + \x{39c} + 0: \x{39c} + \x{178} + 0: \x{178} + | + 0: | + \x{80} + 0: \x{80} + \x{ff} + 0: \x{ff} + \x{100} + 0: \x{100} + \x{101} + 0: \x{101} + ** Failers +No match + \x{102} +No match + Y +No match + y +No match + +/[z-\x{100}]/8DZi +------------------------------------------------------------------ + Bra + [Z\x{39c}\x{178}z-\x{101}] + Ket + End +------------------------------------------------------------------ +Capturing subpattern count = 0 +Options: caseless utf +No first char +No need char -/(?<=\d{3}(?!999))foo/ - 999foo - 0: foo - 123999foo - 0: foo - *** Failers -No match - 123abcfoo -No match - -/(?<=(?!...999)\d{3})foo/ - 999foo - 0: foo - 123999foo - 0: foo - *** Failers -No match - 123abcfoo -No match +/(?:[\PPa*]*){8,}/ -/(?<=\d{3}(?!999)...)foo/ - 123abcfoo - 0: foo - 123456foo - 0: foo - *** Failers -No match - 123999foo -No match - -/(?<=\d{3}...)(?Z)+|A)*/ - ZABCDEFG - 0: ZA - 1: Z - 2: - -/((?>)+|A)*/ - ZABCDEFG - 0: +/[\P{Any}\E]/BZ +------------------------------------------------------------------ + Bra + [\P{Any}] + Ket + End +------------------------------------------------------------------ -/a*/g - abbab - 0: a - 1: - 0: - 0: - 0: a - 1: - 0: - 0: +/(\P{Yi}+\277)/ -/^[a-\d]/ - abcde - 0: a - -things - 0: - - 0digit - 0: 0 - *** Failers -No match - bcdef -No match +/(\P{Yi}+\277)?/ -/^[\d-a]/ - abcde - 0: a - -things - 0: - - 0digit - 0: 0 - *** Failers -No match - bcdef -No match - -/[[:space:]]+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d\x0b - 1: \x09\x0a\x0c\x0d - 2: \x09\x0a\x0c - 3: \x09\x0a - 4: \x09 - 5: - -/[[:blank:]]+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09 - 1: - -/[\s]+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d - 1: \x09\x0a\x0c - 2: \x09\x0a - 3: \x09 - 4: - -/\s+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d - 1: \x09\x0a\x0c - 2: \x09\x0a - 3: \x09 - 4: - -/a b/x - ab -No match - -/(?!\A)x/m - a\nxb\n - 0: x - -/(?!^)x/m - a\nxb\n -No match - -/abc\Qabc\Eabc/ - abcabcabc - 0: abcabcabc - -/abc\Q(*+|\Eabc/ - abc(*+|abc - 0: abc(*+|abc - -/ abc\Q abc\Eabc/x - abc abcabc - 0: abc abcabc - *** Failers -No match - abcabcabc -No match - -/abc#comment - \Q#not comment - literal\E/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal\E #more comment - /x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/abc#comment - \Q#not comment - literal\E #more comment/x - abc#not comment\n literal - 0: abc#not comment\x0a literal - -/\Qabc\$xyz\E/ - abc\\\$xyz - 0: abc\$xyz - -/\Qabc\E\$\Qxyz\E/ - abc\$xyz - 0: abc$xyz +/(?<=\P{Yi}{3}A)X/ -/\Gabc/ - abc - 0: abc - *** Failers -No match - xyzabc -No match +/\p{Yi}+(\P{Yi}+)(?1)/ -/\Gabc./g - abc1abc2xyzabc3 - 0: abc1 - 0: abc2 +/(\P{Yi}{2}\277)?/ -/abc./g - abc1abc2xyzabc3 - 0: abc1 - 0: abc2 - 0: abc3 +/[\P{Yi}A]/ -/a(?x: b c )d/ - XabcdY - 0: abcd - *** Failers -No match - Xa b c d Y -No match +/[\P{Yi}\P{Yi}\P{Yi}A]/ -/((?x)x y z | a b c)/ - XabcY - 0: abc - AxyzB - 0: xyz +/[^\P{Yi}A]/ -/(?i)AB(?-i)C/ - XabCY - 0: abC - *** Failers -No match - XabcY -No match +/[^\P{Yi}\P{Yi}\P{Yi}A]/ -/((?i)AB(?-i)C|D)E/ - abCE - 0: abCE - DE - 0: DE - *** Failers -No match - abcE -No match - abCe -No match - dE -No match - De -No match +/(\P{Yi}*\277)*/ -/[z\Qa-d]\E]/ - z - 0: z - a - 0: a - - - 0: - - d - 0: d - ] - 0: ] - *** Failers - 0: a - b -No match +/(\P{Yi}*?\277)*/ -/[\z\C]/ - z - 0: z - C - 0: C - -/\M/ - M - 0: M - -/(a+)*b/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ - REGular - 0: REGular - regulaer - 0: regulaer - Regex - 0: Regex - regulär - 0: regul\xe4r - -/Åæåä[à-ÿÀ-ß]+/ - Åæåäà - 0: \xc5\xe6\xe5\xe4\xe0 - Åæåäÿ - 0: \xc5\xe6\xe5\xe4\xff - ÅæåäÀ - 0: \xc5\xe6\xe5\xe4\xc0 - Åæåäß - 0: \xc5\xe6\xe5\xe4\xdf - -/(?<=Z)X./ - \x84XAZXB - 0: XB - -/^(?(2)a|(1)(2))+$/ - 123a -Error -17 - -/(?<=a|bbbb)c/ - ac - 0: c - bbbbc - 0: c - -/abc/>testsavedregex -Compiled regex written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex -testsavedregex -Compiled regex written to testsavedregex -Study data written to testsavedregex - - 0: abc - xyz\r\nabc\ - 0: abc - xyz\rabc\ - 0: abc - xyz\r\nabc\ - 0: abc - ** Failers -No match - xyz\nabc\ -No match - xyz\r\nabc\ -No match - xyz\nabc\ -No match - xyz\rabc\ -No match - xyz\rabc\ -No match - -/abc$/m - xyzabc - 0: abc - xyzabc\n - 0: abc - xyzabc\npqr - 0: abc - xyzabc\r\ - 0: abc - xyzabc\rpqr\ - 0: abc - xyzabc\r\n\ - 0: abc - xyzabc\r\npqr\ - 0: abc - ** Failers -No match - xyzabc\r -No match - xyzabc\rpqr -No match - xyzabc\r\n -No match - xyzabc\r\npqr -No match +/(\P{Yi}{0,3}\277)*/ + +/(\P{Yi}{0,3}?\277)*/ + +/(\p{Yi}{0,3}+\277)*/ + +/\p{Zl}{2,3}+/8BZ +------------------------------------------------------------------ + Bra + prop Zl {2} + prop Zl ?+ + Ket + End +------------------------------------------------------------------ + \xe2\x80\xa8\xe2\x80\xa8 + 0: \x{2028}\x{2028} + \x{2028}\x{2028}\x{2028} + 0: \x{2028}\x{2028}\x{2028} -/^abc/m - xyz\rabcdef - 0: abc - xyz\nabcdef\ - 0: abc - ** Failers -No match - xyz\nabcdef +/\p{Zl}/8BZ +------------------------------------------------------------------ + Bra + prop Zl + Ket + End +------------------------------------------------------------------ + +/\p{Lu}{3}+/8BZ +------------------------------------------------------------------ + Bra + prop Lu {3} + Ket + End +------------------------------------------------------------------ + +/\pL{2}+/8BZ +------------------------------------------------------------------ + Bra + prop L {2} + Ket + End +------------------------------------------------------------------ + +/\p{Cc}{2}+/8BZ +------------------------------------------------------------------ + Bra + prop Cc {2} + Ket + End +------------------------------------------------------------------ + +/^\p{Cs}/8 + \?\x{dfff} + 0: \x{dfff} + ** Failers No match - -/^abc/m - xyz\nabcdef - 0: abc - xyz\rabcdef\ - 0: abc - ** Failers + \x{09f} No match - xyz\rabcdef + +/^\p{Sc}+/8 + $\x{a2}\x{a3}\x{a4}\x{a5}\x{a6} + 0: $\x{a2}\x{a3}\x{a4}\x{a5} + \x{9f2} + 0: \x{9f2} + ** Failers No match - -/^abc/m - xyz\r\nabcdef - 0: abc - xyz\rabcdef\ - 0: abc - ** Failers + X No match - xyz\rabcdef + \x{2c2} No match - -/.*/ - abc\ndef - 0: abc - 1: ab - 2: a - 3: - abc\rdef - 0: abc\x0ddef - 1: abc\x0dde - 2: abc\x0dd - 3: abc\x0d - 4: abc - 5: ab - 6: a - 7: - abc\r\ndef - 0: abc\x0d - 1: abc - 2: ab - 3: a - 4: - \abc\ndef - 0: abc\x0adef - 1: abc\x0ade - 2: abc\x0ad - 3: abc\x0a - 4: abc - 5: ab - 6: a - 7: - \abc\rdef - 0: abc - 1: ab - 2: a - 3: - \abc\r\ndef - 0: abc - 1: ab - 2: a - 3: - \abc\ndef - 0: abc\x0adef - 1: abc\x0ade - 2: abc\x0ad - 3: abc\x0a - 4: abc - 5: ab - 6: a - 7: - \abc\rdef - 0: abc\x0ddef - 1: abc\x0dde - 2: abc\x0dd - 3: abc\x0d - 4: abc - 5: ab - 6: a - 7: - \abc\r\ndef - 0: abc - 1: ab - 2: a - 3: - -/\w+(.)(.)?def/s - abc\ndef - 0: abc\x0adef - abc\rdef - 0: abc\x0ddef - abc\r\ndef - 0: abc\x0d\x0adef - -/^\w+=.*(\\\n.*)*/ - abc=xyz\\\npqr - 0: abc=xyz\\x0apqr - 1: abc=xyz\\x0apq - 2: abc=xyz\\x0ap - 3: abc=xyz\\x0a - 4: abc=xyz\ - 5: abc=xyz - 6: abc=xy - 7: abc=x - 8: abc= - -/^(a()*)*/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/^(?:a(?:(?:))*)*/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - 4: - -/^(a()+)+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/^(?:a(?:(?:))+)+/ - aaaa - 0: aaaa - 1: aaa - 2: aa - 3: a - -/(a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?>a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/(?:a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - -/^a.b/ - a\rb - 0: a\x0db - a\nb\ - 0: a\x0ab + +/^\p{Zs}/8 + \ \ + 0: + \x{a0} + 0: \x{a0} + \x{1680} + 0: \x{1680} + \x{180e} + 0: \x{180e} + \x{2000} + 0: \x{2000} + \x{2001} + 0: \x{2001} ** Failers No match - a\nb -No match - a\nb\ + \x{2028} No match - a\rb\ + \x{200d} No match - a\rb\ -No match - -/^abc./mgx - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK - 0: abc1 - 0: abc2 - 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc7 - -/abc.$/mgx - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 - 0: abc1 - 0: abc2 - 0: abc3 - 0: abc4 - 0: abc5 - 0: abc6 - 0: abc9 - -/^a\Rb/ - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b + +/-- These four are here rather than in test 6 because Perl has problems with + the negative versions of the properties. --/ + +/\p{^Lu}/8i + 1234 + 0: 1 ** Failers -No match - a\n\rb + 0: * + ABC No match -/^a\R*b/ - ab - 0: ab - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b - a\n\rb - 0: a\x0a\x0db - a\n\r\x85\x0cb - 0: a\x0a\x0d\x85\x0cb - -/^a\R+b/ - a\nb - 0: a\x0ab - a\rb - 0: a\x0db - a\r\nb - 0: a\x0d\x0ab - a\x0bb - 0: a\x0bb - a\x0cb - 0: a\x0cb - a\x85b - 0: a\x85b - a\n\rb - 0: a\x0a\x0db - a\n\r\x85\x0cb - 0: a\x0a\x0d\x85\x0cb - ** Failers -No match - ab -No match - -/^a\R{1,3}b/ - a\nb - 0: a\x0ab - a\n\rb - 0: a\x0a\x0db - a\n\r\x85b - 0: a\x0a\x0d\x85b - a\r\n\r\nb - 0: a\x0d\x0a\x0d\x0ab - a\r\n\r\n\r\nb - 0: a\x0d\x0a\x0d\x0a\x0d\x0ab - a\n\r\n\rb - 0: a\x0a\x0d\x0a\x0db - a\n\n\r\nb - 0: a\x0a\x0a\x0d\x0ab +/\P{Lu}/8i + 1234 + 0: 1 ** Failers -No match - a\n\n\n\rb -No match - a\r + 0: * + ABC No match -/^a[\R]b/ - aRb - 0: aRb +/\p{Ll}/8i + a + 0: a + Az + 0: z ** Failers -No match - a\nb + 0: a + ABC No match -/.+foo/ - afoo - 0: afoo +/\p{Lu}/8i + A + 0: A + a\x{10a0}B + 0: \x{10a0} ** Failers + 0: F + a No match - \r\nfoo -No match - \nfoo + \x{1d00} No match -/.+foo/ - afoo - 0: afoo - \nfoo - 0: \x0afoo - ** Failers -No match - \r\nfoo -No match +/[\x{c0}\x{391}]/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/-- The next two are special cases where the lengths of the different cases of +the same character differ. The first went wrong with heap frame storage; the +second was broken in all cases. --/ + +/^\x{023a}+?(\x{0130}+)/8i + \x{023a}\x{2c65}\x{0130} + 0: \x{23a}\x{2c65}\x{130} + 1: \x{130} + +/^\x{023a}+([^X])/8i + \x{023a}\x{2c65}X + 0: \x{23a}\x{2c65} + 1: \x{2c65} + +/\x{c0}+\x{116}+/8i + \x{c0}\x{e0}\x{116}\x{117} + 0: \x{c0}\x{e0}\x{116}\x{117} + +/[\x{c0}\x{116}]+/8i + \x{c0}\x{e0}\x{116}\x{117} + 0: \x{c0}\x{e0}\x{116}\x{117} + +/(\x{de})\1/8i + \x{de}\x{de} + 0: \x{de}\x{de} + 1: \x{de} + \x{de}\x{fe} + 0: \x{de}\x{fe} + 1: \x{de} + \x{fe}\x{fe} + 0: \x{fe}\x{fe} + 1: \x{fe} + \x{fe}\x{de} + 0: \x{fe}\x{de} + 1: \x{fe} + +/^\x{c0}$/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/^\x{e0}$/8i + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} + +/-- The next two should be Perl-compatible, but it fails to match \x{e0}. PCRE +will match it only with UCP support, because without that it has no notion +of case for anything other than the ASCII letters. --/ + +/((?i)[\x{c0}])/8 + \x{c0} + 0: \x{c0} + 1: \x{c0} + \x{e0} + 0: \x{e0} + 1: \x{e0} + +/(?i:[\x{c0}])/8 + \x{c0} + 0: \x{c0} + \x{e0} + 0: \x{e0} -/.+foo/ - afoo - 0: afoo - ** Failers -No match - \nfoo -No match - \r\nfoo +/-- This should be Perl-compatible but Perl 5.11 gets \x{300} wrong. --/8 + +/^\X/8 + A + 0: A + A\x{300}BC + 0: A\x{300} + A\x{300}\x{301}\x{302}BC + 0: A\x{300}\x{301}\x{302} + *** Failers + 0: * + \x{300} No match + +/-- These are PCRE's extra properties to help with Unicodizing \d etc. --/ -/.+foo/s - afoo - 0: afoo - \r\nfoo - 0: \x0d\x0afoo - \nfoo - 0: \x0afoo - -/^$/mg - abc\r\rxyz - 0: - abc\n\rxyz - 0: - ** Failers +/^\p{Xan}/8 + ABCD + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + ** Failers No match - abc\r\nxyz + _ABC No match -/^X/m - XABC - 0: X - ** Failers +/^\p{Xan}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} + ** Failers No match - XABC\B + _ABC No match -/(?m)^$/g+ - abc\r\n\r\n - 0: - 0+ \x0d\x0a - -/(?m)^$|^\r\n/g+ - abc\r\n\r\n - 0: \x0d\x0a - 0+ - 1: - -/(?m)$/g+ - abc\r\n\r\n - 0: - 0+ \x0d\x0a\x0d\x0a - 0: - 0+ \x0d\x0a - 0: - 0+ - -/(?|(abc)|(xyz))/ - >abc< - 0: abc - >xyz< - 0: xyz +/^\p{Xan}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca} -/(x)(?|(abc)|(xyz))(x)/ - xabcx - 0: xabcx - xxyzx - 0: xxyzx - -/(x)(?|(abc)(pqr)|(xyz))(x)/ - xabcpqrx - 0: xabcpqrx - xxyzx - 0: xxyzx - -/(?|(abc)|(xyz))(?1)/ - abcabc - 0: abcabc - xyzabc - 0: xyzabc - ** Failers +/^\p{Xan}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} + +/^\p{Xan}{2,9}/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca} + +/^\p{Xan}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca}\x{a6c} + +/^[\p{Xan}]/8 + ABCD1234_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + ** Failers No match - xyzxyz + _ABC No match -/\H\h\V\v/ - X X\x0a - 0: X X\x0a - X\x09X\x0b - 0: X\x09X\x0b +/^[\p{Xan}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} ** Failers No match - \xa0 X\x0a -No match - -/\H*\h+\V?\v{3,4}/ - \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a - 0: \x09 \xa0X\x0a\x0b\x0c\x0d - 1: \x09 \xa0X\x0a\x0b\x0c - \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a - 0: \x09 \xa0\x0a\x0b\x0c\x0d - 1: \x09 \xa0\x0a\x0b\x0c - \x09\x20\xa0\x0a\x0b\x0c - 0: \x09 \xa0\x0a\x0b\x0c - ** Failers -No match - \x09\x20\xa0\x0a\x0b + _ABC No match - -/\H{3,4}/ - XY ABCDE - 0: ABCD - 1: ABC - XY PQR ST - 0: PQR - -/.\h{3,4}./ - XY AB PQRS - 0: B P - 1: B - -/\h*X\h?\H+Y\H?Z/ - >XNNNYZ - 0: XNNNYZ - > X NYQZ - 0: X NYQZ + +/^>\p{Xsp}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} ** Failers No match - >XYZ -No match - > X NY Z + \x{0b} No match -/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ - >XY\x0aZ\x0aA\x0bNN\x0c - 0: XY\x0aZ\x0aA\x0bNN\x0c - >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c - 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c +/^>\p{Xsp}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} -/.+A/ - \r\nA -No match +/^>\p{Xsp}+?/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + +/^>\p{Xsp}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + +/^>\p{Xsp}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} + +/^>\p{Xsp}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09} -/\nA/ - \r\nA - 0: \x0aA - -/[\r\n]A/ - \r\nA - 0: \x0aA - -/(\r|\n)A/ - \r\nA - 0: \x0aA +/^>[\p{Xsp}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\p{Xsp}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} -/a\Rb/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab +/^>\p{Xps}/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} + >\x{a0} + 0: >\x{a0} ** Failers No match - a\x85b -No match - a\x0bb + \x{0b} No match -/a\Rb/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - a\x85b - 0: a\x85b - a\x0bb - 0: a\x0bb - ** Failers -No match - a\x85b\ -No match - a\x0bb\ -No match - -/a\R?b/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - ** Failers -No match - a\x85b -No match - a\x0bb -No match +/^>\p{Xps}+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/a\R?b/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\rb - 0: a\x0db - a\nb - 0: a\x0ab - a\r\nb - 0: a\x0d\x0ab - a\x85b - 0: a\x85b - a\x0bb - 0: a\x0bb - ** Failers -No match - a\x85b\ -No match - a\x0bb\ -No match - -/a\R{2,4}b/I -Capturing subpattern count = 0 -Options: bsr_anycrlf -First char = 'a' -Need char = 'b' - a\r\n\nb - 0: a\x0d\x0a\x0ab - a\n\r\rb - 0: a\x0a\x0d\x0db - a\r\n\r\n\r\n\r\nb - 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab - ** Failers -No match - a\x85\85b -No match - a\x0b\0bb -No match +/^>\p{Xps}+?/8 + >\x{1680}\x{2028}\x{0b} + 0: >\x{1680} -/a\R{2,4}b/I -Capturing subpattern count = 0 -Options: bsr_unicode -First char = 'a' -Need char = 'b' - a\r\rb - 0: a\x0d\x0db - a\n\n\nb - 0: a\x0a\x0a\x0ab - a\r\n\n\r\rb - 0: a\x0d\x0a\x0a\x0d\x0db - a\x85\85b -No match - a\x0b\0bb -No match - ** Failers -No match - a\r\r\r\r\rb -No match - a\x85\85b\ -No match - a\x0b\0bb\ -No match +/^>\p{Xps}*/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/a(?!)|\wbc/ - abc - 0: abc +/^>\p{Xps}{2,9}/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + +/^>\p{Xps}{2,9}?/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09} + +/^>[\p{Xps}]/8 + >\x{2028}\x{0b} + 0: >\x{2028} + +/^>[\p{Xps}]+/8 + > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} + 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} -/a[]b/ +/^\p{Xwd}/8 + ABCD + 0: A + 1234 + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ ** Failers No match - ab + [] No match -/a[]+b/ - ** Failers -No match - ab -No match +/^\p{Xwd}+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ -/a[]*+b/ - ** Failers -No match - ab -No match +/^\p{Xwd}+?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca} -/a[^]b/ - aXb - 0: aXb - a\nb - 0: a\x0ab - ** Failers -No match - ab -No match +/^\p{Xwd}*/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/^\p{Xwd}{2,9}/8 + A_B12\x{6ca}\x{a6c}\x{10a7} + 0: A_B12\x{6ca}\x{a6c}\x{10a7} -/a[^]+b/ - aXb - 0: aXb - a\nX\nXb - 0: a\x0aX\x0aXb +/^\p{Xwd}{2,9}?/8 + \x{6ca}\x{a6c}\x{10a7}_ + 0: \x{6ca}\x{a6c} + +/^[\p{Xwd}]/8 + ABCD1234_ + 0: A + 1234abcd_ + 0: 1 + \x{6ca} + 0: \x{6ca} + \x{a6c} + 0: \x{a6c} + \x{10a7} + 0: \x{10a7} + _ABC + 0: _ ** Failers No match - ab -No match - -/X$/E - X - 0: X - ** Failers -No match - X\n + [] No match + +/^[\p{Xwd}]+/8 + ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ + +/-- A check not in UTF-8 mode --/ + +/^[\p{Xwd}]+/ + ABCD1234_ + 0: ABCD1234_ + +/-- Some negative checks --/ + +/^[\P{Xwd}]+/8 + !.+\x{019}\x{35a}AB + 0: !.+\x{19}\x{35a} + +/^[\p{^Xwd}]+/8 + !.+\x{019}\x{35a}AB + 0: !.+\x{19}\x{35a} + +/[\D]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Nd}] + Ket + End +------------------------------------------------------------------ + 1\x{3c8}2 + 0: \x{3c8} + +/[\d]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ + >\x{6f4}< + 0: \x{6f4} + +/[\S]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Xsp}] + Ket + End +------------------------------------------------------------------ + \x{1680}\x{6f4}\x{1680} + 0: \x{6f4} + +/[\s]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Xsp}] + Ket + End +------------------------------------------------------------------ + >\x{1680}< + 0: \x{1680} + +/[\W]/WBZ8 +------------------------------------------------------------------ + Bra + [\P{Xwd}] + Ket + End +------------------------------------------------------------------ + A\x{1712}B + 0: \x{1712} + +/[\w]/WBZ8 +------------------------------------------------------------------ + Bra + [\p{Xwd}] + Ket + End +------------------------------------------------------------------ + >\x{1723}< + 0: \x{1723} + +/\D/WBZ8 +------------------------------------------------------------------ + Bra + notprop Nd + Ket + End +------------------------------------------------------------------ + 1\x{3c8}2 + 0: \x{3c8} + +/\d/WBZ8 +------------------------------------------------------------------ + Bra + prop Nd + Ket + End +------------------------------------------------------------------ + >\x{6f4}< + 0: \x{6f4} + +/\S/WBZ8 +------------------------------------------------------------------ + Bra + notprop Xsp + Ket + End +------------------------------------------------------------------ + \x{1680}\x{6f4}\x{1680} + 0: \x{6f4} + +/\s/WBZ8 +------------------------------------------------------------------ + Bra + prop Xsp + Ket + End +------------------------------------------------------------------ + >\x{1680}> + 0: \x{1680} + +/\W/WBZ8 +------------------------------------------------------------------ + Bra + notprop Xwd + Ket + End +------------------------------------------------------------------ + A\x{1712}B + 0: \x{1712} + +/\w/WBZ8 +------------------------------------------------------------------ + Bra + prop Xwd + Ket + End +------------------------------------------------------------------ + >\x{1723}< + 0: \x{1723} + +/[[:alpha:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{L}] + Ket + End +------------------------------------------------------------------ + +/[[:lower:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Ll}] + Ket + End +------------------------------------------------------------------ + +/[[:upper:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Lu}] + Ket + End +------------------------------------------------------------------ + +/[[:alnum:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xan}] + Ket + End +------------------------------------------------------------------ + +/[[:ascii:]]/WBZ +------------------------------------------------------------------ + Bra + [\x00-\x7f] + Ket + End +------------------------------------------------------------------ + +/[[:cntrl:]]/WBZ +------------------------------------------------------------------ + Bra + [\x00-\x1f\x7f] + Ket + End +------------------------------------------------------------------ + +/[[:digit:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Nd}] + Ket + End +------------------------------------------------------------------ + +/[[:graph:]]/WBZ +------------------------------------------------------------------ + Bra + [!-~] + Ket + End +------------------------------------------------------------------ + +/[[:print:]]/WBZ +------------------------------------------------------------------ + Bra + [ -~] + Ket + End +------------------------------------------------------------------ + +/[[:punct:]]/WBZ +------------------------------------------------------------------ + Bra + [!-/:-@[-`{-~] + Ket + End +------------------------------------------------------------------ + +/[[:space:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xps}] + Ket + End +------------------------------------------------------------------ + +/[[:word:]]/WBZ +------------------------------------------------------------------ + Bra + [\p{Xwd}] + Ket + End +------------------------------------------------------------------ + +/[[:xdigit:]]/WBZ +------------------------------------------------------------------ + Bra + [0-9A-Fa-f] + Ket + End +------------------------------------------------------------------ + +/-- Unicode properties for \b abd \B --/ + +/\b...\B/8W + abc_ + 0: abc + \x{37e}abc\x{376} + 0: abc + \x{37e}\x{376}\x{371}\x{393}\x{394} + 0: \x{376}\x{371}\x{393} + !\x{c0}++\x{c1}\x{c2} + 0: ++\x{c1} + !\x{c0}+++++ + 0: \x{c0}++ -/X$/ - X - 0: X - X\n - 0: X - -/xyz/C - xyz ---->xyz - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - abcxyz ---->abcxyz - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - abcxyz\Y ---->abcxyz - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +3 ^ ^ - 0: xyz - ** Failers -No match - abc -No match - abc\Y ---->abc - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x -No match - abcxypqr -No match - abcxypqr\Y ---->abcxypqr - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +1 ^^ y - +2 ^ ^ z - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x - +0 ^ x -No match - -/(*NO_START_OPT)xyz/C - abcxyz ---->abcxyz -+15 ^ x -+15 ^ x -+15 ^ x -+15 ^ x -+16 ^^ y -+17 ^ ^ z -+18 ^ ^ - 0: xyz - -/(?C)ab/ - ab ---->ab - 0 ^ a - 0: ab - \C-ab - 0: ab - -/ab/C - ab ---->ab - +0 ^ a - +1 ^^ b - +2 ^ ^ - 0: ab - \C-ab - 0: ab - -/^"((?(?=[a])[^"])|b)*"$/C - "ab" ---->"ab" - +0 ^ ^ - +1 ^ " - +2 ^^ ((?(?=[a])[^"])|b)* -+21 ^^ " - +3 ^^ (?(?=[a])[^"]) -+18 ^^ b - +5 ^^ (?=[a]) - +8 ^ [a] -+11 ^^ ) -+12 ^^ [^"] -+16 ^ ^ ) -+17 ^ ^ | -+21 ^ ^ " - +3 ^ ^ (?(?=[a])[^"]) -+18 ^ ^ b - +5 ^ ^ (?=[a]) - +8 ^ [a] -+19 ^ ^ ) -+21 ^ ^ " - +3 ^ ^ (?(?=[a])[^"]) -+18 ^ ^ b - +5 ^ ^ (?=[a]) - +8 ^ [a] -+17 ^ ^ | -+22 ^ ^ $ -+23 ^ ^ - 0: "ab" - \C-"ab" - 0: "ab" - -/\d+X|9+Y/ - ++++123999\P -Partial match: 123999 - ++++123999Y\P - 0: 999Y +/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ -/Z(*F)/ - Z\P +/\b...\B/8 + abc_ + 0: abc + ** Failers + 0: Fai + \x{37e}abc\x{376} No match - ZA\P + \x{37e}\x{376}\x{371}\x{393}\x{394} No match - -/Z(?!)/ - Z\P + !\x{c0}++\x{c1}\x{c2} No match - ZA\P + !\x{c0}+++++ No match -/dog(sbody)?/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dog(sbody)??/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dog|dogsbody/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/dogsbody|dog/ - dogs\P - 0: dog - dogs\P\P -Partial match: dogs - -/Z(*F)Q|ZXY/ - Z\P -Partial match: Z - ZA\P -No match - X\P -No match - -/\bthe cat\b/ - the cat\P - 0: the cat - the cat\P\P -Partial match: the cat - -/dog(sbody)?/ - dogs\D\P - 0: dog - body\D\R - 0: body - -/dog(sbody)?/ - dogs\D\P\P -Partial match: dogs - body\D\R - 0: body +/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ -/abc/ - abc\P - 0: abc - abc\P\P +/\b...\B/W + abc_ 0: abc + !\x{c0}++\x{c1}\x{c2} + 0: ++\xc1 + !\x{c0}+++++ + 0: \xc0++ -/abc\K123/ - xyzabc123pqr -Error -16 - -/(?<=abc)123/ - xyzabc123pqr - 0: 123 - xyzabc12\P -Partial match: abc12 - xyzabc12\P\P -Partial match: abc12 +/-- Some of these are silly, but they check various combinations --/ -/\babc\b/ - +++abc+++ +/[[:^alpha:][:^cntrl:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc 0: abc - +++ab\P -Partial match: +ab - +++ab\P\P -Partial match: +ab - -/(?=C)/g+ - ABCDECBA - 0: - 0+ CDECBA - 0: - 0+ CBA -/(abc|def|xyz)/I -Capturing subpattern count = 1 -No options -No first char -No need char - terhjk;abcdaadsfe +/[[:^cntrl:][:^alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [ -~\x80-\xff\P{L}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc 0: abc - the quick xyz brown fox - 0: xyz - \Yterhjk;abcdaadsfe + +/[[:alpha:]]+/8WBZ +------------------------------------------------------------------ + Bra + [\p{L}]+ + Ket + End +------------------------------------------------------------------ + abc 0: abc - \Ythe quick xyz brown fox - 0: xyz - ** Failers -No match - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match -/(abc|def|xyz)/SI -Capturing subpattern count = 1 -No options -No first char -No need char -Subject length lower bound = 3 -Starting byte set: a d x - terhjk;abcdaadsfe +/[[:^alpha:]\S]+/8WBZ +------------------------------------------------------------------ + Bra + [\P{L}\P{Xsp}]+ + Ket + End +------------------------------------------------------------------ + 123 + 0: 123 + abc 0: abc - the quick xyz brown fox - 0: xyz - \Yterhjk;abcdaadsfe + +/[^\d]+/8WBZ +------------------------------------------------------------------ + Bra + [^\p{Nd}]+ + Ket + End +------------------------------------------------------------------ + abc123 0: abc - \Ythe quick xyz brown fox - 0: xyz - ** Failers + abc\x{123} + 0: abc\x{123} + \x{660}abc + 0: abc + +/\p{Lu}+9\p{Lu}+B\p{Lu}+b/BZ +------------------------------------------------------------------ + Bra + prop Lu ++ + 9 + prop Lu + + B + prop Lu ++ + b + Ket + End +------------------------------------------------------------------ + +/\p{^Lu}+9\p{^Lu}+B\p{^Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\P{Lu}+9\P{Lu}+B\P{Lu}+b/BZ +------------------------------------------------------------------ + Bra + notprop Lu + + 9 + notprop Lu ++ + B + notprop Lu + + b + Ket + End +------------------------------------------------------------------ + +/\p{Han}+X\p{Greek}+\x{370}/BZ8 +------------------------------------------------------------------ + Bra + prop Han ++ + X + prop Greek + + \x{370} + Ket + End +------------------------------------------------------------------ + +/\p{Xan}+!\p{Xan}+A/BZ +------------------------------------------------------------------ + Bra + prop Xan ++ + ! + prop Xan + + A + Ket + End +------------------------------------------------------------------ + +/\p{Xsp}+!\p{Xsp}\t/BZ +------------------------------------------------------------------ + Bra + prop Xsp ++ + ! + prop Xsp + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xps}+!\p{Xps}\t/BZ +------------------------------------------------------------------ + Bra + prop Xps ++ + ! + prop Xps + \x09 + Ket + End +------------------------------------------------------------------ + +/\p{Xwd}+!\p{Xwd}_/BZ +------------------------------------------------------------------ + Bra + prop Xwd ++ + ! + prop Xwd + _ + Ket + End +------------------------------------------------------------------ + +/A+\p{N}A+\dB+\p{N}*B+\d*/WBZ +------------------------------------------------------------------ + Bra + A++ + prop N + A++ + prop Nd + B+ + prop N *+ + B+ + prop Nd * + Ket + End +------------------------------------------------------------------ + +/-- These behaved oddly in Perl, so they are kept in this test --/ + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} +No match + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})?\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)?\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65} +No match + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥ +No match + +/(\x{23a}\x{23a}\x{23a})\1/8i + \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(ȺȺȺ)\1/8i + ȺȺȺⱥⱥⱥ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65} + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1/8i + \x{2c65}\x{2c65}\x{23a}\x{23a} + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(ⱥⱥ)\1/8i + ⱥⱥȺȺ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a} + 1: \x{2c65}\x{2c65} + +/(\x{23a}\x{23a}\x{23a})\1Y/8i + X\x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}YZ + 0: \x{23a}\x{23a}\x{23a}\x{2c65}\x{2c65}\x{2c65}Y + 1: \x{23a}\x{23a}\x{23a} + +/(\x{2c65}\x{2c65})\1Y/8i + X\x{2c65}\x{2c65}\x{23a}\x{23a}YZ + 0: \x{2c65}\x{2c65}\x{23a}\x{23a}Y + 1: \x{2c65}\x{2c65} + +/-- --/ + +/-- These scripts weren't yet in Perl when I added Unicode 6.0.0 to PCRE --/ + +/^[\p{Batak}]/8 + \x{1bc0} + 0: \x{1bc0} + \x{1bff} + 0: \x{1bff} + ** Failers +No match + \x{1bf4} +No match + +/^[\p{Brahmi}]/8 + \x{11000} + 0: \x{11000} + \x{1106f} + 0: \x{1106f} + ** Failers +No match + \x{1104e} +No match + +/^[\p{Mandaic}]/8 + \x{840} + 0: \x{840} + \x{85e} + 0: \x{85e} + ** Failers +No match + \x{85c} No match - thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd -No match - \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd + \x{85d} No match -/abcd*/+ - xxxxabcd\P - 0: abcd - 0+ - 1: abc - xxxxabcd\P\P -Partial match: abcd - dddxxx\R - 0: ddd - 0+ xxx - 1: dd - 2: d - 3: - xxxxabcd\P\P -Partial match: abcd - xxx\R - 0: - 0+ xxx - -/abcd*/i - xxxxabcd\P - 0: abcd - 1: abc - xxxxabcd\P\P -Partial match: abcd - XXXXABCD\P - 0: ABCD - 1: ABC - XXXXABCD\P\P -Partial match: ABCD - -/abc\d*/ - xxxxabc1\P - 0: abc1 - 1: abc - xxxxabc1\P\P -Partial match: abc1 - -/abc[de]*/ - xxxxabcde\P - 0: abcde - 1: abcd - 2: abc - xxxxabcde\P\P -Partial match: abcde +/-- --/ -/(?:(?1)|B)(A(*F)|C)/ - ABCD - 0: BC - CCD - 0: CC - ** Failers -No match - CAD -No match +/(\X*)(.)/s8 + A\x{300} + 0: A + 1: + 2: A -/^(?:(?1)|B)(A(*F)|C)/ - CCD - 0: CC - BCD - 0: BC - ** Failers -No match - ABCD -No match - CAD +/^S(\X*)e(\X*)$/8 + SteÌreÌo No match - BAD + +/^\X/8 + ÌreÌo No match -/^(?!a(*SKIP)b)/ - ac -Error -16 - -/^(?=a(*SKIP)b|ac)/ - ** Failers +/^a\X41z/ + aX41z + 0: aX41z + *** Failers No match - ac -Error -16 - -/^(?=a(*THEN)b|ac)/ - ac -Error -16 - -/^(?=a(*PRUNE)b)/ - ab -Error -16 - ** Failers + aAz No match - ac -Error -16 -/^(?(?!a(*SKIP)b))/ - ac -Error -16 - -/(?<=abc)def/ - abc\P\P -Partial match: abc +/(?<=ab\Cde)X/8 +Failed: \C not allowed in lookbehind assertion at offset 10 -/abc$/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc +/\X/ + a\P + 0: a + a\P\P +Partial match: a -/abc$/m - abc - 0: abc - abc\n - 0: abc - abc\P\P -Partial match: abc - abc\n\P\P - 0: abc - abc\P - 0: abc - abc\n\P - 0: abc +/\Xa/ + aa\P + 0: aa + aa\P\P + 0: aa -/abc\z/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc +/\X{2}/ + aa\P + 0: aa + aa\P\P +Partial match: aa -/abc\Z/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc +/\X+a/ + a\P +Partial match: a + aa\P + 0: aa + aa\P\P +Partial match: aa -/abc\b/ - abc - 0: abc - abc\P - 0: abc - abc\P\P -Partial match: abc +/\X+?a/ + a\P +Partial match: a + ab\P +Partial match: ab + aa\P + 0: aa + aa\P\P + 0: aa + aba\P + 0: aba + +/-- These Unicode 6.1.0 scripts are not known to Perl. --/ -/abc\B/ - abc -No match - abc\P -Partial match: abc - abc\P\P -Partial match: abc +/\p{Chakma}\d/8W + \x{11100}\x{1113c} + 0: \x{11100}\x{1113c} + +/\p{Takri}\d/8W + \x{11680}\x{116c0} + 0: \x{11680}\x{116c0} -/.+/ - abc\>0 - 0: abc - 1: ab - 2: a - abc\>1 - 0: bc - 1: b - abc\>2 - 0: c - abc\>3 -No match - abc\>4 -Error -24 - abc\>-4 -Error -24 +/^\X/8 + A\P + 0: A + A\P\P +Partial match: A + A\x{300}\x{301}\P + 0: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{301}\P + 0: A\x{301} + A\x{301}\P\P +Partial match: A\x{301} + +/^\X{2,3}/8 + A\P +Partial match: A + A\P\P +Partial match: A + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} + +/^\X{2}/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + A\x{300}\x{301}A\x{300}\x{301}\P + 0: A\x{300}\x{301}A\x{300}\x{301} + A\x{300}\x{301}A\x{300}\x{301}\P\P +Partial match: A\x{300}\x{301}A\x{300}\x{301} + +/^\X+/8 + AA\P + 0: AA + AA\P\P +Partial match: AA + +/^\X+?Z/8 + AA\P +Partial match: AA + AA\P\P +Partial match: AA /-- End of testinput7 --/ diff -Nru pcre3-8.12/testdata/testoutput8 pcre3-8.31/testdata/testoutput8 --- pcre3-8.12/testdata/testoutput8 2010-11-07 15:53:22.000000000 +0000 +++ pcre3-8.31/testdata/testoutput8 2012-06-17 19:07:04.000000000 +0000 @@ -1,531 +1,445 @@ -/-- This set of tests checks UTF-8 support with the DFA matching functionality - of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running - it. --/ - -/\x{100}ab/8 - \x{100}ab - 0: \x{100}ab - -/a\x{100}*b/8 - ab - 0: ab - a\x{100}b - 0: a\x{100}b - a\x{100}\x{100}b - 0: a\x{100}\x{100}b - -/a\x{100}+b/8 - a\x{100}b - 0: a\x{100}b - a\x{100}\x{100}b - 0: a\x{100}\x{100}b +/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(). + The -dfa flag must be used with pcretest when running it. --/ + +/abc/ + abc + 0: abc + +/ab*c/ + abc + 0: abc + abbbbc + 0: abbbbc + ac + 0: ac + +/ab+c/ + abc + 0: abc + abbbbbbc + 0: abbbbbbc *** Failers No match + ac +No match ab No match - -/\bX/8 - Xoanon - 0: X - +Xoanon - 0: X - \x{300}Xoanon - 0: X - *** Failers + +/a*/ + a + 0: a + 1: + aaaaaaaaaaaaaaaaa + 0: aaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaa + 4: aaaaaaaaaaaaa + 5: aaaaaaaaaaaa + 6: aaaaaaaaaaa + 7: aaaaaaaaaa + 8: aaaaaaaaa + 9: aaaaaaaa +10: aaaaaaa +11: aaaaaa +12: aaaaa +13: aaaa +14: aaa +15: aa +16: a +17: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Matched, but too many subsidiary matches + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa + 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa + 3: aaaaaaaaaaaaaaaaaaaaaaaaaaa + 4: aaaaaaaaaaaaaaaaaaaaaaaaaa + 5: aaaaaaaaaaaaaaaaaaaaaaaaa + 6: aaaaaaaaaaaaaaaaaaaaaaaa + 7: aaaaaaaaaaaaaaaaaaaaaaa + 8: aaaaaaaaaaaaaaaaaaaaaa + 9: aaaaaaaaaaaaaaaaaaaaa +10: aaaaaaaaaaaaaaaaaaaa +11: aaaaaaaaaaaaaaaaaaa +12: aaaaaaaaaaaaaaaaaa +13: aaaaaaaaaaaaaaaaa +14: aaaaaaaaaaaaaaaa +15: aaaaaaaaaaaaaaa +16: aaaaaaaaaaaaaa +17: aaaaaaaaaaaaa +18: aaaaaaaaaaaa +19: aaaaaaaaaaa +20: aaaaaaaaaa +21: aaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\F + 0: + +/(a|abcd|african)/ + a + 0: a + abcd + 0: abcd + 1: a + african + 0: african + 1: a + +/^abc/ + abcdef + 0: abc + *** Failers +No match + xyzabc No match - YXoanon + xyz\nabc No match -/\BX/8 - YXoanon - 0: X +/^abc/m + abcdef + 0: abc + xyz\nabc + 0: abc *** Failers No match - Xoanon + xyzabc No match - +Xoanon + +/\Aabc/ + abcdef + 0: abc + *** Failers No match - \x{300}Xoanon + xyzabc No match - -/X\b/8 - X+oanon - 0: X - ZX\x{300}oanon - 0: X - FAX - 0: X - *** Failers + xyz\nabc +No match + +/\Aabc/m + abcdef + 0: abc + *** Failers +No match + xyzabc No match - Xoanon + xyz\nabc No match -/X\B/8 - Xoanon - 0: X +/\Gabc/ + abcdef + 0: abc + xyzabc\>3 + 0: abc *** Failers No match - X+oanon + xyzabc +No match + xyzabc\>2 +No match + +/x\dy\Dz/ + x9yzz + 0: x9yzz + x0y+z + 0: x0y+z + *** Failers No match - ZX\x{300}oanon + xyz No match - FAX + xxy0z No match -/[^a]/8 - abcd - 0: b - a\x{100} - 0: \x{100} - -/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 - ab99 - 0: ab9 - \x{123}\x{123}45 - 0: \x{123}\x{123}4 - \x{400}\x{401}\x{402}6 - 0: \x{400}\x{401}\x{402}6 +/x\sy\Sz/ + x yzz + 0: x yzz + x y+z + 0: x y+z *** Failers No match - d99 + xyz No match - \x{123}\x{122}4 + xxyyz No match - \x{400}\x{403}6 + +/x\wy\Wz/ + xxy+z + 0: xxy+z + *** Failers No match - \x{400}\x{401}\x{402}\x{402}6 + xxy0z No match - -/abc/8 - Ã] -Error -10 - à -Error -10 - ÃÃà -Error -10 - ÃÃÃ\? + x+y+z No match - \xe1\x88 -Error -10 - \P\xe1\x88 -Error -10 - \P\P\xe1\x88 -Error -25 - -/a.b/8 - acb - 0: acb - a\x7fb - 0: a\x{7f}b - a\x{100}b - 0: a\x{100}b + +/x.y/ + x+y + 0: x+y + x-y + 0: x-y *** Failers No match - a\nb + x\ny +No match + +/x.y/s + x+y + 0: x+y + x-y + 0: x-y + x\ny + 0: x\x0ay + +/(a.b(?s)c.d|x.y)p.q/ + a+bc+dp+q + 0: a+bc+dp+q + a+bc\ndp+q + 0: a+bc\x0adp+q + x\nyp+q + 0: x\x0ayp+q + *** Failers +No match + a\nbc\ndp+q +No match + a+bc\ndp\nq +No match + x\nyp\nq No match -/a(.{3})b/8 - a\x{4000}xyb - 0: a\x{4000}xyb - a\x{4000}\x7fyb - 0: a\x{4000}\x{7f}yb - a\x{4000}\x{100}yb - 0: a\x{4000}\x{100}yb +/a\d\z/ + ba0 + 0: a0 *** Failers No match - a\x{4000}b + ba0\n No match - ac\ncb + ba0\ncd No match -/a(.*?)(.)/ - a\xc0\x88b - 0: a\xc0\x88b - 1: a\xc0\x88 - 2: a\xc0 - -/a(.*?)(.)/8 - a\x{100}b - 0: a\x{100}b - 1: a\x{100} - -/a(.*)(.)/ - a\xc0\x88b - 0: a\xc0\x88b - 1: a\xc0\x88 - 2: a\xc0 - -/a(.*)(.)/8 - a\x{100}b - 0: a\x{100}b - 1: a\x{100} - -/a(.)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - -/a(.)(.)/8 - a\x{240}bcd - 0: a\x{240}b - -/a(.?)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - 1: a\xc0 - -/a(.?)(.)/8 - a\x{240}bcd - 0: a\x{240}b - 1: a\x{240} - -/a(.??)(.)/ - a\xc0\x92bcd - 0: a\xc0\x92 - 1: a\xc0 - -/a(.??)(.)/8 - a\x{240}bcd - 0: a\x{240}b - 1: a\x{240} - -/a(.{3})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b +/a\d\z/m + ba0 + 0: a0 *** Failers No match - a\x{1234}b + ba0\n No match - ac\ncb + ba0\ncd No match -/a(.{3,})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxbcdefghijb - 1: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b +/a\d\Z/ + ba0 + 0: a0 + ba0\n + 0: a0 *** Failers No match - a\x{1234}b + ba0\ncd No match -/a(.{3,}?)b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxbcdefghijb - 1: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b +/a\d\Z/m + ba0 + 0: a0 + ba0\n + 0: a0 *** Failers No match - a\x{1234}b + ba0\ncd No match -/a(.{3,5})b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - 0: axbxxb - axxxxxbcdefghijb - 0: axxxxxb +/a\d$/ + ba0 + 0: a0 + ba0\n + 0: a0 *** Failers No match - a\x{1234}b + ba0\ncd No match - axxxxxxbcdefghijb + +/a\d$/m + ba0 + 0: a0 + ba0\n + 0: a0 + ba0\ncd + 0: a0 + *** Failers No match -/a(.{3,5}?)b/8 - a\x{1234}xyb - 0: a\x{1234}xyb - a\x{1234}\x{4321}yb - 0: a\x{1234}\x{4321}yb - a\x{1234}\x{4321}\x{3412}b - 0: a\x{1234}\x{4321}\x{3412}b - axxxxbcdefghijb - 0: axxxxb - a\x{1234}\x{4321}\x{3412}\x{3421}b - 0: a\x{1234}\x{4321}\x{3412}\x{3421}b - axbxxbcdefghijb - 0: axbxxb - axxxxxbcdefghijb - 0: axxxxxb +/abc/i + abc + 0: abc + aBc + 0: aBc + ABC + 0: ABC + +/[^a]/ + abcd + 0: b + +/ab?\w/ + abz + 0: abz + 1: ab + abbz + 0: abb + 1: ab + azz + 0: az + +/x{0,3}yz/ + ayzq + 0: yz + axyzq + 0: xyz + axxyz + 0: xxyz + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz *** Failers No match - a\x{1234}b + ax No match - axxxxxxbcdefghijb + axx No match - -/^[a\x{c0}]/8 + +/x{3}yz/ + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz *** Failers No match - \x{100} + ax No match - -/(?<=aXb)cd/8 - aXbcd - 0: cd - -/(?<=a\x{100}b)cd/8 - a\x{100}bcd - 0: cd - -/(?<=a\x{100000}b)cd/8 - a\x{100000}bcd - 0: cd - -/(?:\x{100}){3}b/8 - \x{100}\x{100}\x{100}b - 0: \x{100}\x{100}\x{100}b - *** Failers + axx No match - \x{100}\x{100}b + ayzq No match - -/\x{ab}/8 - \x{ab} - 0: \x{ab} - \xc2\xab - 0: \x{ab} - *** Failers + axyzq No match - \x00{ab} + axxyz No match - -/(?<=(.))X/8 - WXYZ - 0: X - \x{256}XYZ - 0: X + +/x{2,3}yz/ + axxyz + 0: xxyz + axxxyzq + 0: xxxyz + axxxxyzq + 0: xxxyz *** Failers No match - XYZ + ax +No match + axx +No match + ayzq +No match + axyzq +No match + +/[^a]+/ + bac + 0: b + bcdefax + 0: bcdef + 1: bcde + 2: bcd + 3: bc + 4: b + *** Failers + 0: *** F + 1: *** + 2: *** + 3: ** + 4: * + aaaaa No match -/[^a]+/8g - bcd - 0: bcd - 1: bc - 2: b - \x{100}aY\x{256}Z - 0: \x{100} - 0: Y\x{256}Z - 1: Y\x{256} - 2: Y - -/^[^a]{2}/8 - \x{100}bc - 0: \x{100}b - -/^[^a]{2,}/8 - \x{100}bcAa - 0: \x{100}bcA - 1: \x{100}bc - 2: \x{100}b - -/^[^a]{2,}?/8 - \x{100}bca - 0: \x{100}bc - 1: \x{100}b - -/[^a]+/8ig - bcd - 0: bcd - 1: bc - 2: b - \x{100}aY\x{256}Z - 0: \x{100} - 0: Y\x{256}Z - 1: Y\x{256} - 2: Y - -/^[^a]{2}/8i - \x{100}bc - 0: \x{100}b - -/^[^a]{2,}/8i - \x{100}bcAa - 0: \x{100}bc - 1: \x{100}b - -/^[^a]{2,}?/8i - \x{100}bca - 0: \x{100}bc - 1: \x{100}b - -/\x{100}{0,0}/8 - abcd - 0: - -/\x{100}?/8 - abcd - 0: - \x{100}\x{100} - 0: \x{100} +/[^a]*/ + bac + 0: b 1: - -/\x{100}{0,3}/8 - \x{100}\x{100} - 0: \x{100}\x{100} - 1: \x{100} - 2: - \x{100}\x{100}\x{100}\x{100} - 0: \x{100}\x{100}\x{100} - 1: \x{100}\x{100} - 2: \x{100} - 3: - -/\x{100}*/8 - abce + bcdefax + 0: bcdef + 1: bcde + 2: bcd + 3: bc + 4: b + 5: + *** Failers + 0: *** F + 1: *** + 2: *** + 3: ** + 4: * + 5: + aaaaa 0: - \x{100}\x{100}\x{100}\x{100} - 0: \x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100} - 2: \x{100}\x{100} - 3: \x{100} + +/[^a]{3,5}/ + xyz + 0: xyz + awxyza + 0: wxyz + 1: wxy + abcdefa + 0: bcdef + 1: bcde + 2: bcd + abcdefghijk + 0: bcdef + 1: bcde + 2: bcd + *** Failers + 0: *** F + 1: *** + 2: *** + axya +No match + axa +No match + aaaaa +No match + +/\d*/ + 1234b567 + 0: 1234 + 1: 123 + 2: 12 + 3: 1 4: - -/\x{100}{1,1}/8 - abcd\x{100}\x{100}\x{100}\x{100} - 0: \x{100} - -/\x{100}{1,3}/8 - abcd\x{100}\x{100}\x{100}\x{100} - 0: \x{100}\x{100}\x{100} - 1: \x{100}\x{100} - 2: \x{100} - -/\x{100}+/8 - abcd\x{100}\x{100}\x{100}\x{100} - 0: \x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100} - 2: \x{100}\x{100} - 3: \x{100} - -/\x{100}{3}/8 - abcd\x{100}\x{100}\x{100}XX - 0: \x{100}\x{100}\x{100} - -/\x{100}{3,5}/8 - abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX - 0: \x{100}\x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100}\x{100} - 2: \x{100}\x{100}\x{100} - -/\x{100}{3,}/8 - abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX - 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 2: \x{100}\x{100}\x{100}\x{100}\x{100} - 3: \x{100}\x{100}\x{100}\x{100} - 4: \x{100}\x{100}\x{100} - -/(?<=a\x{100}{2}b)X/8 - Xyyya\x{100}\x{100}bXzzz - 0: X - -/\D*/8 - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -Matched, but too many subsidiary matches - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 3: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 4: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 5: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 6: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 7: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 8: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - 9: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -10: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -11: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -12: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -13: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -14: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -15: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -16: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -17: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -18: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -19: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -/\D*/8 - \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -Matched, but too many subsidiary matches - 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 2: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 3: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 4: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 5: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 6: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 7: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 8: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - 9: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -10: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -11: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -12: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -13: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -14: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -15: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -16: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -17: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -18: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -19: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -20: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} -21: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} - -/\D/8 - 1X2 - 0: X - 1\x{100}2 - 0: \x{100} - -/>\S/8 - > >X Y - 0: >X - > >\x{100} Y - 0: >\x{100} - -/\d/8 - \x{100}3 - 0: 3 + xyz + 0: -/\s/8 - \x{100} X - 0: +/\D*/ + a1234b567 + 0: a + 1: + xyz + 0: xyz + 1: xy + 2: x + 3: + +/\d+/ + ab1234c56 + 0: 1234 + 1: 123 + 2: 12 + 3: 1 + *** Failers +No match + xyz +No match -/\D+/8 - 12abcd34 - 0: abcd - 1: abc - 2: ab - 3: a +/\D+/ + ab123c56 + 0: ab + 1: a *** Failers 0: *** Failers 1: *** Failer @@ -538,502 +452,6362 @@ 8: *** 9: ** 10: * - 1234 -No match - -/\D{2,3}/8 - 12abcd34 - 0: abc - 1: ab - 12ab34 - 0: ab - *** Failers - 0: *** - 1: ** - 1234 + 789 No match - 12a34 + +/\d?A/ + 045ABC + 0: 5A + ABC + 0: A + *** Failers No match - -/\D{2,3}?/8 - 12abcd34 - 0: abc - 1: ab - 12ab34 - 0: ab - *** Failers - 0: *** - 1: ** - 1234 + XYZ No match - 12a34 + +/\D?A/ + ABC + 0: A + BAC + 0: BA + 9ABC + 0: A + *** Failers No match -/\d+/8 - 12abcd34 - 0: 12 - 1: 1 +/a+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/^.*xyz/ + xyz + 0: xyz + ggggggggxyz + 0: ggggggggxyz + +/^.+xyz/ + abcdxyz + 0: abcdxyz + axyz + 0: axyz *** Failers No match - -/\d{2,3}/8 - 12abcd34 - 0: 12 - 1234abcd - 0: 123 - 1: 12 - *** Failers + xyz No match - 1.4 + +/^.?xyz/ + xyz + 0: xyz + cxyz + 0: cxyz + +/^\d{2,3}X/ + 12X + 0: 12X + 123X + 0: 123X + *** Failers No match - -/\d{2,3}?/8 - 12abcd34 - 0: 12 - 1234abcd - 0: 123 - 1: 12 - *** Failers + X No match - 1.4 + 1X +No match + 1234X No match -/\S+/8 - 12abcd34 - 0: 12abcd34 - 1: 12abcd3 - 2: 12abcd - 3: 12abc - 4: 12ab - 5: 12a - 6: 12 - 7: 1 - *** Failers - 0: *** - 1: ** - 2: * - \ \ -No match - -/\S{2,3}/8 - 12abcd34 - 0: 12a - 1: 12 - 1234abcd - 0: 123 - 1: 12 +/^[abcd]\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 *** Failers - 0: *** - 1: ** - \ \ +No match + e45 +No match + abcd +No match + abcd1234 +No match + 1234 No match -/\S{2,3}?/8 - 12abcd34 - 0: 12a - 1: 12 - 1234abcd - 0: 123 - 1: 12 +/^[abcd]*\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + abcd1234 + 0: abcd1 + 1234 + 0: 1 *** Failers - 0: *** - 1: ** - \ \ +No match + e45 +No match + abcd No match -/>\s+ <34 - 0: > < +/^[abcd]+\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + abcd1234 + 0: abcd1 *** Failers No match + 1234 +No match + e45 +No match + abcd +No match -/>\s{2,3} < - ab> < +/^a+X/ + aX + 0: aX + aaX + 0: aaX + +/^[abcd]?\d/ + a45 + 0: a4 + b93 + 0: b9 + c99z + 0: c9 + d04 + 0: d0 + 1234 + 0: 1 *** Failers No match - ab> \s{2,3}? < - ab> < +/^[abcd]{2,3}\d/ + ab45 + 0: ab4 + bcd93 + 0: bcd9 *** Failers No match - ab> abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3)a*)\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9 + *** Failers No match - X + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match -/(?<=[Q\x{100}\x{200}])X/8 - abc\x{200}X - 0: X - abc\x{100}X - 0: X - abQX - 0: X +/< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x + <> + 0: <> + + 0: + hij> + 0: hij> + hij> + 0: + def> + 0: def> + + 0: <> *** Failers No match - X + \xff< - 0: \xff - -/[\xff]/8 - >\x{ff}< - 0: \x{ff} +/(?abcxyz + 1 ^ ^ x + 0: abcxyz + 123abcxyz999 +--->123abcxyz999 + 1 ^ ^ x + 0: abcxyz + +/(ab|cd){3,4}/C + ababab +--->ababab + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + 0: ababab + abcdabcd +--->abcdabcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +2 ^ ^ b + +3 ^ ^ | ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdabcd + 1: abcdab + abcdcdcdcdcd +--->abcdcdcdcdcd + +0 ^ (ab|cd){3,4} + +1 ^ a + +4 ^ c + +2 ^^ b + +3 ^ ^ | + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + +1 ^ ^ a + +4 ^ ^ c + +5 ^ ^ d + +6 ^ ^ ) ++12 ^ ^ + 0: abcdcdcd + 1: abcdcd + +/^abc/ + abcdef + 0: abc + *** Failers +No match + abcdef\B +No match + +/^(a*|xyz)/ + bcd + 0: + aaabcd + 0: aaa + 1: aa + 2: a + 3: + xyz + 0: xyz + 1: + xyz\N + 0: xyz + *** Failers + 0: + bcd\N +No match + +/xyz$/ + xyz + 0: xyz + xyz\n + 0: xyz + *** Failers +No match + xyz\Z +No match + xyz\n\Z +No match + +/xyz$/m + xyz + 0: xyz + xyz\n + 0: xyz + abcxyz\npqr + 0: xyz + abcxyz\npqr\Z + 0: xyz + xyz\n\Z + 0: xyz + *** Failers +No match + xyz\Z +No match + +/\Gabc/ + abcdef + 0: abc + defabcxyz\>3 + 0: abc + *** Failers +No match + defabcxyz +No match + +/^abcdef/ + ab\P +Partial match: ab + abcde\P +Partial match: abcde + abcdef\P + 0: abcdef + *** Failers +No match + abx\P +No match + +/^a{2,4}\d+z/ + a\P +Partial match: a + aa\P +Partial match: aa + aa2\P +Partial match: aa2 + aaa\P +Partial match: aaa + aaa23\P +Partial match: aaa23 + aaaa12345\P +Partial match: aaaa12345 + aa0z\P + 0: aa0z + aaaa4444444444444z\P + 0: aaaa4444444444444z + *** Failers +No match + az\P +No match + aaaaa\P +No match + a56\P +No match + +/^abcdef/ + abc\P +Partial match: abc + def\R + 0: def + +/(?<=foo)bar/ + xyzfo\P +No match + foob\P\>2 +Partial match: foob + foobar...\R\P\>4 + 0: ar + xyzfo\P +No match + foobar\>2 + 0: bar + *** Failers +No match + xyzfo\P +No match + obar\R +No match + +/(ab*(cd|ef))+X/ + adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkj\P\Z +No match + lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefa\P\B\Z +Partial match: abbbbbbcdaefabbbbbbbefa + cdabbbbbbbb\P\R\B\Z +Partial match: cdabbbbbbbb + efabbbbbbbbbbbbbbbb\P\R\B\Z +Partial match: efabbbbbbbbbbbbbbbb + bbbbbbbbbbbbcdXyasdfadf\P\R\B\Z + 0: bbbbbbbbbbbbcdX + +/(a|b)/SF>testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex +>>aaabxyzpqrrrabbxyyyypqAzz + 0: aaabxyzpqrrrabbxyyyypqAzz + >aaaabxyzpqrrrabbxyyyypqAzz + 0: aaaabxyzpqrrrabbxyyyypqAzz + >>>>abcxyzpqrrrabbxyyyypqAzz + 0: abcxyzpqrrrabbxyyyypqAzz + *** Failers +No match + abxyzpqrrabbxyyyypqAzz +No match + abxyzpqrrrrabbxyyyypqAzz +No match + abxyzpqrrrabxyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz +No match + aaaabcxyzzzzpqrrrabbbxyyypqAzz +No match + aaabcxyzpqrrrabbxyyyypqqqqqqqAzz +No match + +/^(abc){1,2}zz/ + abczz + 0: abczz + abcabczz + 0: abcabczz + *** Failers +No match + zz +No match + abcabcabczz +No match + >>abczz +No match + +/^(b+?|a){1,2}?c/ + bc + 0: bc + bbc + 0: bbc + bbbc + 0: bbbc + bac + 0: bac + bbac + 0: bbac + aac + 0: aac + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}c/ + bc + 0: bc + bbc + 0: bbc + bbbc + 0: bbbc + bac + 0: bac + bbac + 0: bbac + aac + 0: aac + abbbbbbbbbbbc + 0: abbbbbbbbbbbc + bbbbbbbbbbbac + 0: bbbbbbbbbbbac + *** Failers +No match + aaac +No match + abbbbbbbbbbbac +No match + +/^(b+|a){1,2}?bc/ + bbc + 0: bbc + +/^(b*|ba){1,2}?bc/ + babc + 0: babc + bbabc + 0: bbabc + bababc + 0: bababc + *** Failers +No match + bababbc +No match + babababc +No match + +/^(ba|b*){1,2}?bc/ + babc + 0: babc + bbabc + 0: bbabc + bababc + 0: bababc + *** Failers +No match + bababbc +No match + babababc +No match + +/^\ca\cA\c[\c{\c:/ + \x01\x01\e;z + 0: \x01\x01\x1b;z + +/^[ab\]cde]/ + athing + 0: a + bthing + 0: b + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + fthing +No match + [thing +No match + \\thing +No match + +/^[]cde]/ + ]thing + 0: ] + cthing + 0: c + dthing + 0: d + ething + 0: e + *** Failers +No match + athing +No match + fthing +No match + +/^[^ab\]cde]/ + fthing + 0: f + [thing + 0: [ + \\thing + 0: \ + *** Failers + 0: * + athing +No match + bthing +No match + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^[^]cde]/ + athing + 0: a + fthing + 0: f + *** Failers + 0: * + ]thing +No match + cthing +No match + dthing +No match + ething +No match + +/^\/ + + 0: \x81 + +/^ÿ/ + ÿ + 0: \xff + +/^[0-9]+$/ + 0 + 0: 0 + 1 + 0: 1 + 2 + 0: 2 + 3 + 0: 3 + 4 + 0: 4 + 5 + 0: 5 + 6 + 0: 6 + 7 + 0: 7 + 8 + 0: 8 + 9 + 0: 9 + 10 + 0: 10 + 100 + 0: 100 + *** Failers +No match + abc +No match + +/^.*nter/ + enter + 0: enter + inter + 0: inter + uponter + 0: uponter + +/^xxx[0-9]+$/ + xxx0 + 0: xxx0 + xxx1234 + 0: xxx1234 + *** Failers +No match + xxx +No match + +/^.+[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^.+?[0-9][0-9][0-9]$/ + x123 + 0: x123 + xx123 + 0: xx123 + 123456 + 0: 123456 + *** Failers +No match + 123 +No match + x1234 + 0: x1234 + +/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ + abc!pqr=apquxz.ixr.zzz.ac.uk + 0: abc!pqr=apquxz.ixr.zzz.ac.uk + *** Failers +No match + !pqr=apquxz.ixr.zzz.ac.uk +No match + abc!=apquxz.ixr.zzz.ac.uk +No match + abc!pqr=apquxz:ixr.zzz.ac.uk +No match + abc!pqr=apquxz.ixr.zzz.ac.ukk +No match + +/:/ + Well, we need a colon: somewhere + 0: : + *** Fail if we don't +No match + +/([\da-f:]+)$/i + 0abc + 0: 0abc + abc + 0: abc + fed + 0: fed + E + 0: E + :: + 0: :: + 5f03:12C0::932e + 0: 5f03:12C0::932e + fed def + 0: def + Any old stuff + 0: ff + *** Failers +No match + 0zzz +No match + gzzz +No match + fed\x20 +No match + Any old rubbish +No match + +/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ + .1.2.3 + 0: .1.2.3 + A.12.123.0 + 0: A.12.123.0 + *** Failers +No match + .1.2.3333 +No match + 1.2.3 +No match + 1234.2.3 +No match + +/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ + 1 IN SOA non-sp1 non-sp2( + 0: 1 IN SOA non-sp1 non-sp2( + 1 IN SOA non-sp1 non-sp2 ( + 0: 1 IN SOA non-sp1 non-sp2 ( + *** Failers +No match + 1IN SOA non-sp1 non-sp2( +No match + +/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ + a. + 0: a. + Z. + 0: Z. + 2. + 0: 2. + ab-c.pq-r. + 0: ab-c.pq-r. + sxk.zzz.ac.uk. + 0: sxk.zzz.ac.uk. + x-.y-. + 0: x-.y-. + *** Failers +No match + -abc.peq. +No match + +/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ + *.a + 0: *.a + *.b0-a + 0: *.b0-a + *.c3-b.c + 0: *.c3-b.c + *.c-a.b-c + 0: *.c-a.b-c + *** Failers +No match + *.0 +No match + *.a- +No match + *.a-b.c- +No match + *.c-a.0-c +No match + +/^(?=ab(de))(abd)(e)/ + abde + 0: abde + +/^(?!(ab)de|x)(abd)(f)/ + abdf + 0: abdf + +/^(?=(ab(cd)))(ab)/ + abcd + 0: ab + +/^[\da-f](\.[\da-f])*$/i + a.b.c.d + 0: a.b.c.d + A.B.C.D + 0: A.B.C.D + a.b.c.1.2.3.C + 0: a.b.c.1.2.3.C + +/^\".*\"\s*(;.*)?$/ + \"1234\" + 0: "1234" + \"abcd\" ; + 0: "abcd" ; + \"\" ; rhubarb + 0: "" ; rhubarb + *** Failers +No match + \"1234\" : things +No match + +/^$/ + \ + 0: + *** Failers +No match + +/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ + ab c + 0: ab c + *** Failers +No match + abc +No match + ab cde +No match + +/^ a\ b[c ]d $/x + a bcd + 0: a bcd + a b d + 0: a b d + *** Failers +No match + abcd +No match + ab d +No match + +/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + +/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ + abcdefhijklm + 0: abcdefhijklm + +/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ + a+ Z0+\x08\n\x1d\x12 + 0: a+ Z0+\x08\x0a\x1d\x12 + +/^[.^$|()*+?{,}]+/ + .^\$(*+)|{?,?} + 0: .^$(*+)|{?,?} + 1: .^$(*+)|{?,? + 2: .^$(*+)|{?, + 3: .^$(*+)|{? + 4: .^$(*+)|{ + 5: .^$(*+)| + 6: .^$(*+) + 7: .^$(*+ + 8: .^$(* + 9: .^$( +10: .^$ +11: .^ +12: . + +/^a*\w/ + z + 0: z + az + 0: az + 1: a + aaaz + 0: aaaz + 1: aaa + 2: aa + 3: a + a + 0: a + aa + 0: aa + 1: a + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + a+ + 0: a + aa+ + 0: aa + 1: a + +/^a*?\w/ + z + 0: z + az + 0: az + 1: a + aaaz + 0: aaaz + 1: aaa + 2: aa + 3: a + a + 0: a + aa + 0: aa + 1: a + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + a+ + 0: a + aa+ + 0: aa + 1: a + +/^a+\w/ + az + 0: az + aaaz + 0: aaaz + 1: aaa + 2: aa + aa + 0: aa + aaaa + 0: aaaa + 1: aaa + 2: aa + aa+ + 0: aa + +/^a+?\w/ + az + 0: az + aaaz + 0: aaaz + 1: aaa + 2: aa + aa + 0: aa + aaaa + 0: aaaa + 1: aaa + 2: aa + aa+ + 0: aa + +/^\d{8}\w{2,}/ + 1234567890 + 0: 1234567890 + 12345678ab + 0: 12345678ab + 12345678__ + 0: 12345678__ + *** Failers +No match + 1234567 +No match + +/^[aeiou\d]{4,5}$/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + aaaaa + 0: aaaaa + *** Failers +No match + 123456 +No match + +/^[aeiou\d]{4,5}?/ + uoie + 0: uoie + 1234 + 0: 1234 + 12345 + 0: 12345 + 1: 1234 + aaaaa + 0: aaaaa + 1: aaaa + 123456 + 0: 12345 + 1: 1234 + +/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + +/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ + From abcd Mon Sep 01 12:33:02 1997 + 0: From abcd Mon Sep 01 12:33 + From abcd Mon Sep 1 12:33:02 1997 + 0: From abcd Mon Sep 1 12:33 + *** Failers +No match + From abcd Sep 01 12:33:02 1997 +No match + +/^12.34/s + 12\n34 + 0: 12\x0a34 + 12\r34 + 0: 12\x0d34 + +/\w+(?=\t)/ + the quick brown\t fox + 0: brown + +/foo(?!bar)(.*)/ + foobar is foolish see? + 0: foolish see? + 1: foolish see + 2: foolish se + 3: foolish s + 4: foolish + 5: foolish + 6: foolis + 7: fooli + 8: fool + 9: foo + +/(?:(?!foo)...|^.{0,2})bar(.*)/ + foobar crowbar etc + 0: rowbar etc + 1: rowbar et + 2: rowbar e + 3: rowbar + 4: rowbar + barrel + 0: barrel + 1: barre + 2: barr + 3: bar + 2barrel + 0: 2barrel + 1: 2barre + 2: 2barr + 3: 2bar + A barrel + 0: A barrel + 1: A barre + 2: A barr + 3: A bar + +/^(\D*)(?=\d)(?!123)/ + abc456 + 0: abc + *** Failers +No match + abc123 +No match + +/^1234(?# test newlines + inside)/ + 1234 + 0: 1234 + +/^1234 #comment in extended re + /x + 1234 + 0: 1234 + +/#rhubarb + abcd/x + abcd + 0: abcd + +/^abcd#rhubarb/x + abcd + 0: abcd + +/(?!^)abc/ + the abc + 0: abc + *** Failers +No match + abc +No match + +/(?=^)abc/ + abc + 0: abc + *** Failers +No match + the abc +No match + +/^[ab]{1,3}(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}?(ab*|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}?(ab*?|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/^[ab]{1,3}(ab*?|b)/ + aabbbbb + 0: aabbbbb + 1: aabbbb + 2: aabbb + 3: aabb + 4: aab + 5: aa + +/ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional leading comment +(?: (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # one word, optionally followed by.... +(?: +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... +\( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) | # comments, or... + +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +# quoted strings +)* +< (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # leading < +(?: @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* + +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* , (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +)* # further okay, if led by comma +: # closing colon +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* )? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) # initial word +(?: (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +" (?: # opening quote... +[^\\\x80-\xff\n\015"] # Anything except backslash and quote +| # or +\\ [^\x80-\xff] # Escaped something (something != CR) +)* " # closing quote +) )* # further okay, if led by a period +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* @ (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # initial subdomain +(?: # +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* \. # if led by a period... +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* (?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| \[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) # ...further okay +)* +# address spec +(?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* > # trailing > +# name and address +) (?: [\040\t] | \( +(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* +\) )* # optional trailing comment +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + 1: user@dom + user\@dom.ain + 0: user@dom.ain + 1: user@dom + \"A. Other\" (a comment) + 0: "A. Other" (a comment) + 1: "A. Other" + 2: "A. Other" + A. Other (a comment) + 0: Other (a comment) + 1: Other + 2: Other + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re + A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address +| # or +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +# leading word +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces +(?: +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +| +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +) # "special" comment or quoted string +[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" +)* +< +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# < +(?: +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +(?: , +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +)* # additional domains +: +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)? # optional route +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +# Atom +| # or +" # " +[^\\\x80-\xff\n\015"] * # normal +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* +" # " +# Quoted string +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# additional words +)* +@ +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +(?: +\. +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +(?: +[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... +(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom +| +\[ # [ +(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff +\] # ] +) +[\040\t]* # Nab whitespace. +(?: +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: # ( +(?: \\ [^\x80-\xff] | +\( # ( +[^\\\x80-\xff\n\015()] * # normal* +(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* +\) # ) +) # special +[^\\\x80-\xff\n\015()] * # normal* +)* # )* +\) # ) +[\040\t]* )* # If comment found, allow more spaces. +# optional trailing comments +)* +# address spec +> # > +# name and address +) +/x + Alan Other + 0: Alan Other + + 0: user@dom.ain + 1: user@dom + user\@dom.ain + 0: user@dom.ain + 1: user@dom + \"A. Other\" (a comment) + 0: "A. Other" + A. Other (a comment) + 0: Other + \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay + 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay + 1: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re + A missing angle + a\rb + 0: a\x0db + *** Failers +No match + a\nb +No match + +/abc$/ + abc + 0: abc + abc\n + 0: abc + *** Failers +No match + abc\ndef +No match + +/(abc)\123/ + abc\x53 + 0: abcS + +/(abc)\223/ + abc\x93 + 0: abc\x93 + +/(abc)\323/ + abc\xd3 + 0: abc\xd3 + +/(abc)\100/ + abc\x40 + 0: abc@ + abc\100 + 0: abc@ + +/(abc)\1000/ + abc\x400 + 0: abc@0 + abc\x40\x30 + 0: abc@0 + abc\1000 + 0: abc@0 + abc\100\x30 + 0: abc@0 + abc\100\060 + 0: abc@0 + abc\100\60 + 0: abc@0 + +/abc\81/ + abc\081 + 0: abc\x0081 + abc\0\x38\x31 + 0: abc\x0081 + +/abc\91/ + abc\091 + 0: abc\x0091 + abc\0\x39\x31 + 0: abc\x0091 + +/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/ + abcdefghijk\12S + 0: abcdefghijk\x0aS + +/ab\idef/ + abidef + 0: abidef + +/a{0}bc/ + bc + 0: bc + +/(a|(bc)){0,0}?xyz/ + xyz + 0: xyz + +/abc[\10]de/ + abc\010de + 0: abc\x08de + +/abc[\1]de/ + abc\1de + 0: abc\x01de + +/(abc)[\1]de/ + abc\1de + 0: abc\x01de + +/(?s)a.b/ + a\nb + 0: a\x0ab + +/^([^a])([^\b])([^c]*)([^d]{3,4})/ + baNOTccccd + 0: baNOTcccc + 1: baNOTccc + 2: baNOTcc + 3: baNOTc + 4: baNOT + baNOTcccd + 0: baNOTccc + 1: baNOTcc + 2: baNOTc + 3: baNOT + baNOTccd + 0: baNOTcc + 1: baNOTc + 2: baNOT + bacccd + 0: baccc + *** Failers + 0: *** Failers + 1: *** Failer + 2: *** Faile + 3: *** Fail + 4: *** Fai + 5: *** Fa + 6: *** F + anything +No match + b\bc +No match + baccd +No match + +/[^a]/ + Abc + 0: A + +/[^a]/i + Abc + 0: b + +/[^a]+/ + AAAaAbc + 0: AAA + 1: AA + 2: A + +/[^a]+/i + AAAaAbc + 0: bc + 1: b + +/[^a]+/ + bbb\nccc + 0: bbb\x0accc + 1: bbb\x0acc + 2: bbb\x0ac + 3: bbb\x0a + 4: bbb + 5: bb + 6: b + +/[^k]$/ + abc + 0: c + *** Failers + 0: s + abk +No match + +/[^k]{2,3}$/ + abc + 0: abc + kbc + 0: bc + kabc + 0: abc + *** Failers + 0: ers + abk +No match + akb +No match + akk +No match + +/^\d{8,}\@.+[^k]$/ + 12345678\@a.b.c.d + 0: 12345678@a.b.c.d + 123456789\@x.y.z + 0: 123456789@x.y.z + *** Failers +No match + 12345678\@x.y.uk +No match + 1234567\@a.b.c.d +No match + +/[^a]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^a]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/[^az]/ + aaaabcd + 0: b + aaAabcd + 0: A + +/[^az]/i + aaaabcd + 0: b + aaAabcd + 0: b + +/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/ + \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377 + 0: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff + +/P[^*]TAIRE[^*]{1,6}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/P[^*]TAIRE[^*]{1,}?LL/ + xxxxxxxxxxxPSTAIREISLLxxxxxxxxx + 0: PSTAIREISLL + +/(\.\d\d[1-9]?)\d+/ + 1.230003938 + 0: .230003938 + 1: .23000393 + 2: .2300039 + 3: .230003 + 4: .23000 + 5: .2300 + 6: .230 + 1.875000282 + 0: .875000282 + 1: .87500028 + 2: .8750002 + 3: .875000 + 4: .87500 + 5: .8750 + 6: .875 + 1.235 + 0: .235 + +/(\.\d\d((?=0)|\d(?=\d)))/ + 1.230003938 + 0: .230 + 1: .23 + 1.875000282 + 0: .875 + *** Failers +No match + 1.235 +No match + +/a(?)b/ + ab + 0: ab + +/\b(foo)\s+(\w+)/i + Food is on the foo table + 0: foo table + 1: foo tabl + 2: foo tab + 3: foo ta + 4: foo t + +/foo(.*)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: food is under the bar + +/foo(.*?)bar/ + The food is under the bar in the barn. + 0: food is under the bar in the bar + 1: food is under the bar + +/(.*)(\d*)/ + I have 2 numbers: 53147 +Matched, but too many subsidiary matches + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: I have 2 numbers: 531 + 3: I have 2 numbers: 53 + 4: I have 2 numbers: 5 + 5: I have 2 numbers: + 6: I have 2 numbers: + 7: I have 2 numbers + 8: I have 2 number + 9: I have 2 numbe +10: I have 2 numb +11: I have 2 num +12: I have 2 nu +13: I have 2 n +14: I have 2 +15: I have 2 +16: I have +17: I have +18: I hav +19: I ha +20: I h +21: I + +/(.*)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: I have 2 numbers: 531 + 3: I have 2 numbers: 53 + 4: I have 2 numbers: 5 + 5: I have 2 + +/(.*?)(\d*)/ + I have 2 numbers: 53147 +Matched, but too many subsidiary matches + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: I have 2 numbers: 531 + 3: I have 2 numbers: 53 + 4: I have 2 numbers: 5 + 5: I have 2 numbers: + 6: I have 2 numbers: + 7: I have 2 numbers + 8: I have 2 number + 9: I have 2 numbe +10: I have 2 numb +11: I have 2 num +12: I have 2 nu +13: I have 2 n +14: I have 2 +15: I have 2 +16: I have +17: I have +18: I hav +19: I ha +20: I h +21: I + +/(.*?)(\d+)/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + 1: I have 2 numbers: 5314 + 2: I have 2 numbers: 531 + 3: I have 2 numbers: 53 + 4: I have 2 numbers: 5 + 5: I have 2 + +/(.*)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*?)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*)\b(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/(.*\D)(\d+)$/ + I have 2 numbers: 53147 + 0: I have 2 numbers: 53147 + +/^\D*(?!123)/ + ABC123 + 0: AB + 1: A + 2: + +/^(\D*)(?=\d)(?!123)/ + ABC445 + 0: ABC + *** Failers +No match + ABC123 +No match + +/^[W-]46]/ + W46]789 + 0: W46] + -46]789 + 0: -46] + *** Failers +No match + Wall +No match + Zebra +No match + 42 +No match + [abcd] +No match + ]abcd[ +No match + +/^[W-\]46]/ + W46]789 + 0: W + Wall + 0: W + Zebra + 0: Z + Xylophone + 0: X + 42 + 0: 4 + [abcd] + 0: [ + ]abcd[ + 0: ] + \\backslash + 0: \ + *** Failers +No match + -46]789 +No match + well +No match + +/\d\d\/\d\d\/\d\d\d\d/ + 01/01/2000 + 0: 01/01/2000 + +/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope +No match + +/^(a){0,0}/ + bcd + 0: + abc + 0: + aab + 0: + +/^(a){0,1}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: a + 1: + +/^(a){0,2}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + +/^(a){0,3}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + aaa + 0: aaa + 1: aa + 2: a + 3: + +/^(a){0,}/ + bcd + 0: + abc + 0: a + 1: + aab + 0: aa + 1: a + 2: + aaa + 0: aaa + 1: aa + 2: a + 3: + aaaaaaaa + 0: aaaaaaaa + 1: aaaaaaa + 2: aaaaaa + 3: aaaaa + 4: aaaa + 5: aaa + 6: aa + 7: a + 8: + +/^(a){1,1}/ + bcd +No match + abc + 0: a + aab + 0: a + +/^(a){1,2}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + +/^(a){1,3}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: aa + 2: a + +/^(a){1,}/ + bcd +No match + abc + 0: a + aab + 0: aa + 1: a + aaa + 0: aaa + 1: aa + 2: a + aaaaaaaa + 0: aaaaaaaa + 1: aaaaaaa + 2: aaaaaa + 3: aaaaa + 4: aaaa + 5: aaa + 6: aa + 7: a + +/.*\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.{0,}\.gif/ + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/m + borfle\nbib.gif\nno + 0: bib.gif + +/.*\.gif/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*\.gif/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif + +/.*$/ + borfle\nbib.gif\nno + 0: no + +/.*$/m + borfle\nbib.gif\nno + 0: borfle + +/.*$/s + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + +/.*$/ms + borfle\nbib.gif\nno + 0: borfle\x0abib.gif\x0ano + 1: borfle\x0abib.gif + 2: borfle + +/.*$/ + borfle\nbib.gif\nno\n + 0: no + +/.*$/m + borfle\nbib.gif\nno\n + 0: borfle + +/.*$/s + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + 1: borfle\x0abib.gif\x0ano + +/.*$/ms + borfle\nbib.gif\nno\n + 0: borfle\x0abib.gif\x0ano\x0a + 1: borfle\x0abib.gif\x0ano + 2: borfle\x0abib.gif + 3: borfle + +/(.*X|^B)/ + abcde\n1234Xyz + 0: 1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/m + abcde\n1234Xyz + 0: 1234X + BarFoo + 0: B + abcde\nBar + 0: B + +/(.*X|^B)/s + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/(.*X|^B)/ms + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + abcde\nBar + 0: B + +/(?s)(.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/(?s:.*X|^B)/ + abcde\n1234Xyz + 0: abcde\x0a1234X + BarFoo + 0: B + *** Failers +No match + abcde\nBar +No match + +/^.*B/ + **** Failers +No match + abc\nB +No match + +/(?s)^.*B/ + abc\nB + 0: abc\x0aB + +/(?m)^.*B/ + abc\nB + 0: B + +/(?ms)^.*B/ + abc\nB + 0: abc\x0aB + +/(?ms)^B/ + abc\nB + 0: B + +/(?s)B$/ + B\n + 0: B + +/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ + 123456654321 + 0: 123456654321 + +/^\d\d\d\d\d\d\d\d\d\d\d\d/ + 123456654321 + 0: 123456654321 + +/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ + 123456654321 + 0: 123456654321 + +/^[abc]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[a-c]{12}/ + abcabcabcabc + 0: abcabcabcabc + +/^(a|b|c){12}/ + abcabcabcabc + 0: abcabcabcabc + +/^[abcdefghijklmnopqrstuvwxy0123456789]/ + n + 0: n + *** Failers +No match + z +No match + +/abcde{0,0}/ + abcd + 0: abcd + *** Failers +No match + abce +No match + +/ab[cd]{0,0}e/ + abe + 0: abe + *** Failers +No match + abcde +No match + +/ab(c){0,0}d/ + abd + 0: abd + *** Failers +No match + abcd +No match + +/a(b*)/ + a + 0: a + ab + 0: ab + 1: a + abbbb + 0: abbbb + 1: abbb + 2: abb + 3: ab + 4: a + *** Failers + 0: a + bbbbb +No match + +/ab\d{0}e/ + abe + 0: abe + *** Failers +No match + ab1e +No match + +/"([^\\"]+|\\.)*"/ + the \"quick\" brown fox + 0: "quick" + \"the \\\"quick\\\" brown fox\" + 0: "the \"quick\" brown fox" + +/.*?/g+ + abc + 0: abc + 0+ + 1: ab + 2: a + 3: + 0: + 0+ + +/\b/g+ + abc + 0: + 0+ abc + 0: + 0+ + +/\b/+g + abc + 0: + 0+ abc + 0: + 0+ + +//g + abc + 0: + 0: + 0: + 0: + +/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
    ([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is + 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + 0: 43.Word Processor
    (N-1286)
    Lega lstaff.comCA - Statewide + +/a[^a]b/ + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/ + acb + 0: acb + *** Failers +No match + a\nb +No match + +/a[^a]b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/a.b/s + acb + 0: acb + a\nb + 0: a\x0ab + +/^(b+?|a){1,2}?c/ + bac + 0: bac + bbac + 0: bbac + bbbac + 0: bbbac + bbbbac + 0: bbbbac + bbbbbac + 0: bbbbbac + +/^(b+|a){1,2}?c/ + bac + 0: bac + bbac + 0: bbac + bbbac + 0: bbbac + bbbbac + 0: bbbbac + bbbbbac + 0: bbbbbac + +/(?!\A)x/m + x\nb\n +No match + a\bx\n + 0: x + +/\x0{ab}/ + \0{ab} + 0: \x00{ab} + +/(A|B)*?CD/ + CD + 0: CD + +/(A|B)*CD/ + CD + 0: CD + +/(?.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ +No match + +"(?>.*/)foo" + /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo + +/(?>(\.\d\d[1-9]?))\d+/ + 1.230003938 + 0: .230003938 + 1: .23000393 + 2: .2300039 + 3: .230003 + 4: .23000 + 5: .2300 + 6: .230 + 1.875000282 + 0: .875000282 + 1: .87500028 + 2: .8750002 + 3: .875000 + 4: .87500 + 5: .8750 + *** Failers +No match + 1.235 +No match + +/^((?>\w+)|(?>\s+))*$/ + now is the time for all good men to come to the aid of the party + 0: now is the time for all good men to come to the aid of the party + *** Failers +No match + this is not a line with only words and spaces! +No match + +/(\d+)(\w)/ + 12345a + 0: 12345a + 1: 12345 + 2: 1234 + 3: 123 + 4: 12 + 12345+ + 0: 12345 + 1: 1234 + 2: 123 + 3: 12 + +/((?>\d+))(\w)/ + 12345a + 0: 12345a + *** Failers +No match + 12345+ +No match + +/(?>a+)b/ + aaab + 0: aaab + +/((?>a+)b)/ + aaab + 0: aaab + +/(?>(a+))b/ + aaab + 0: aaab + +/(?>b)+/ + aaabbbccc + 0: bbb + 1: bb + 2: b + +/(?>a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbcccc + 1: aaabbbbc + +/(a+|b+|c+)*c/ + aaabbbbccccd + 0: aaabbbbcccc + 1: aaabbbbccc + 2: aaabbbbcc + 3: aaabbbbc + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: abc(ade)ufh()() + 2: abc(ade)ufh() + 3: abc(ade)ufh + 4: abc(ade) + 5: abc + +/\(((?>[^()]+)|\([^()]+\))+\)/ + (abc) + 0: (abc) + (abc(def)xyz) + 0: (abc(def)xyz) + *** Failers +No match + ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/a(?-i)b/i + ab + 0: ab + Ab + 0: Ab + *** Failers +No match + aB +No match + AB +No match + +/(a (?x)b c)d e/ + a bcd e + 0: a bcd e + *** Failers +No match + a b cd e +No match + abcd e +No match + a bcde +No match + +/(a b(?x)c d (?-x)e f)/ + a bcde f + 0: a bcde f + *** Failers +No match + abcdef +No match + +/(a(?i)b)c/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + abC +No match + aBC +No match + Abc +No match + ABc +No match + ABC +No match + AbC +No match + +/a(?i:b)c/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + ABC +No match + abC +No match + aBC +No match + +/a(?i:b)*c/ + aBc + 0: aBc + aBBc + 0: aBBc + *** Failers +No match + aBC +No match + aBBC +No match + +/a(?=b(?i)c)\w\wd/ + abcd + 0: abcd + abCd + 0: abCd + *** Failers +No match + aBCd +No match + abcD +No match + +/(?s-i:more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?:(?s-i)more.*than).*million/i + more than million + 0: more than million + more than MILLION + 0: more than MILLION + more \n than Million + 0: more \x0a than Million + *** Failers +No match + MORE THAN MILLION +No match + more \n than \n million +No match + +/(?>a(?i)b+)+c/ + abc + 0: abc + aBbc + 0: aBbc + aBBc + 0: aBBc + *** Failers +No match + Abc +No match + abAb +No match + abbC +No match + +/(?=a(?i)b)\w\wc/ + abc + 0: abc + aBc + 0: aBc + *** Failers +No match + Ab +No match + abC +No match + aBC +No match + +/(?<=a(?i)b)(\w\w)c/ + abxxc + 0: xxc + aBxxc + 0: xxc + *** Failers +No match + Abxxc +No match + ABxxc +No match + abxxC +No match + +/^(?(?=abc)\w{3}:|\d\d)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/^(?(?!abc)\d\d|\w{3}:)$/ + abc: + 0: abc: + 12 + 0: 12 + *** Failers +No match + 123 +No match + xyz +No match + +/(?(?<=foo)bar|cat)/ + foobar + 0: bar + cat + 0: cat + fcat + 0: cat + focat + 0: cat + *** Failers +No match + foocat +No match + +/(?(?a*)*/ + a + 0: a + 1: + aa + 0: aa + 1: + aaaa + 0: aaaa + 1: + +/(abc|)+/ + abc + 0: abc + 1: + abcabc + 0: abcabc + 1: abc + 2: + abcabcabc + 0: abcabcabc + 1: abcabc + 2: abc + 3: + xyz + 0: + +/([a]*)*/ + a + 0: a + 1: + aaaaa + 0: aaaaa + 1: aaaa + 2: aaa + 3: aa + 4: a + 5: + +/([ab]*)*/ + a + 0: a + 1: + b + 0: b + 1: + ababab + 0: ababab + 1: ababa + 2: abab + 3: aba + 4: ab + 5: a + 6: + aaaabcde + 0: aaaab + 1: aaaa + 2: aaa + 3: aa + 4: a + 5: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + +/([^a]*)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + aaa + 0: + +/([^ab]*)*/ + cccc + 0: cccc + 1: ccc + 2: cc + 3: c + 4: + abab + 0: + +/([a]*?)*/ + a + 0: a + 1: + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/([ab]*?)*/ + a + 0: a + 1: + b + 0: b + 1: + abab + 0: abab + 1: aba + 2: ab + 3: a + 4: + baba + 0: baba + 1: bab + 2: ba + 3: b + 4: + +/([^a]*?)*/ + b + 0: b + 1: + bbbb + 0: bbbb + 1: bbb + 2: bb + 3: b + 4: + aaa + 0: + +/([^ab]*?)*/ + c + 0: c + 1: + cccc + 0: cccc + 1: ccc + 2: cc + 3: c + 4: + baba + 0: + +/(?>a*)*/ + a + 0: a + 1: + aaabcde + 0: aaa + 1: + +/((?>a*))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/((?>a*?))*/ + aaaaa + 0: aaaaa + 1: + aabbaa + 0: aa + 1: + +/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x + 12-sep-98 + 0: 12-sep-98 + 12-09-98 + 0: 12-09-98 + *** Failers +No match + sep-12-98 +No match + +/(?i:saturday|sunday)/ + saturday + 0: saturday + sunday + 0: sunday + Saturday + 0: Saturday + Sunday + 0: Sunday + SATURDAY + 0: SATURDAY + SUNDAY + 0: SUNDAY + SunDay + 0: SunDay + +/(a(?i)bc|BB)x/ + abcx + 0: abcx + aBCx + 0: aBCx + bbx + 0: bbx + BBx + 0: BBx + *** Failers +No match + abcX +No match + aBCX +No match + bbX +No match + BBX +No match + +/^([ab](?i)[cd]|[ef])/ + ac + 0: ac + aC + 0: aC + bD + 0: bD + elephant + 0: e + Europe + 0: E + frog + 0: f + France + 0: F + *** Failers +No match + Africa +No match + +/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ + ab + 0: ab + aBd + 0: aBd + xy + 0: xy + xY + 0: xY + zebra + 0: z + Zambesi + 0: Z + *** Failers +No match + aCD +No match + XY +No match + +/(?<=foo\n)^bar/m + foo\nbar + 0: bar + *** Failers +No match + bar +No match + baz\nbar +No match + +/(?<=(?]&/ + <&OUT + 0: <& + +/(?:(f)(o)(o)|(b)(a)(r))*/ + foobar + 0: foobar + 1: foo + 2: + +/(?<=a)b/ + ab + 0: b + *** Failers +No match + cb +No match + b +No match + +/(?a+)ab/ + +/(?>a+)b/ + aaab + 0: aaab + +/([[:]+)/ + a:[b]: + 0: :[ + 1: : + +/([[=]+)/ + a=[b]= + 0: =[ + 1: = + +/([[.]+)/ + a.[b]. + 0: .[ + 1: . + +/((?>a+)b)/ + aaab + 0: aaab + +/(?>(a+))b/ + aaab + 0: aaab + +/((?>[^()]+)|\([^()]*\))+/ + ((abc(ade)ufh()()x + 0: abc(ade)ufh()()x + 1: abc(ade)ufh()() + 2: abc(ade)ufh() + 3: abc(ade)ufh + 4: abc(ade) + 5: abc + +/a\Z/ + *** Failers +No match + aaab +No match + a\nb\n +No match + +/b\Z/ + a\nb\n + 0: b -/[^\xff]/8 - XYZ - 0: X - \x{123} - 0: \x{123} +/b\z/ + +/b\Z/ + a\nb + 0: b -/^[ac]*b/8 - xb +/b\z/ + a\nb + 0: b + *** Failers +No match + +/(?>.*)(?<=(abcd|wxyz))/ + alphabetabcd + 0: alphabetabcd + endingwxyz + 0: endingwxyz + *** Failers +No match + a rather long string that doesn't end with one of them No match -/^[ac\x{100}]*b/8 - xb +/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark otherword + 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword + word cat dog elephant mussel cow horse canary baboon snake shark +No match + +/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ + word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match -/^[^x]*b/8i - xb +/(?<=\d{3}(?!999))foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo +No match + +/(?<=(?!...999)\d{3})foo/ + 999foo + 0: foo + 123999foo + 0: foo + *** Failers +No match + 123abcfoo No match -/^[^x]*b/8 - xb +/(?<=\d{3}(?!999)...)foo/ + 123abcfoo + 0: foo + 123456foo + 0: foo + *** Failers No match - -/^\d*b/8 - xb + 123999foo +No match + +/(?<=\d{3}...)(?Z)+|A)*/ + ZABCDEFG + 0: ZA + 1: Z + 2: + +/((?>)+|A)*/ + ZABCDEFG 0: + +/a*/g + abbab 0: a 1: 0: + 0: 0: a 1: 0: 0: - a\x{256}a + +/^[a-\d]/ + abcde 0: a - 1: - 0: + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/^[\d-a]/ + abcde 0: a - 1: + -things + 0: - + 0digit + 0: 0 + *** Failers +No match + bcdef +No match + +/[[:space:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d\x0b + 1: \x09\x0a\x0c\x0d + 2: \x09\x0a\x0c + 3: \x09\x0a + 4: \x09 + 5: + +/[[:blank:]]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09 + 1: + +/[\s]+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + 1: \x09\x0a\x0c + 2: \x09\x0a + 3: \x09 + 4: + +/\s+/ + > \x09\x0a\x0c\x0d\x0b< + 0: \x09\x0a\x0c\x0d + 1: \x09\x0a\x0c + 2: \x09\x0a + 3: \x09 + 4: + +/a b/x + ab +No match + +/(?!\A)x/m + a\nxb\n + 0: x + +/(?!^)x/m + a\nxb\n +No match + +/abc\Qabc\Eabc/ + abcabcabc + 0: abcabcabc + +/abc\Q(*+|\Eabc/ + abc(*+|abc + 0: abc(*+|abc + +/ abc\Q abc\Eabc/x + abc abcabc + 0: abc abcabc + *** Failers +No match + abcabcabc +No match + +/abc#comment + \Q#not comment + literal\E/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment + /x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/abc#comment + \Q#not comment + literal\E #more comment/x + abc#not comment\n literal + 0: abc#not comment\x0a literal + +/\Qabc\$xyz\E/ + abc\\\$xyz + 0: abc\$xyz + +/\Qabc\E\$\Qxyz\E/ + abc\$xyz + 0: abc$xyz + +/\Gabc/ + abc + 0: abc + *** Failers +No match + xyzabc +No match + +/\Gabc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + +/abc./g + abc1abc2xyzabc3 + 0: abc1 + 0: abc2 + 0: abc3 + +/a(?x: b c )d/ + XabcdY + 0: abcd + *** Failers +No match + Xa b c d Y +No match + +/((?x)x y z | a b c)/ + XabcY + 0: abc + AxyzB + 0: xyz + +/(?i)AB(?-i)C/ + XabCY + 0: abC + *** Failers +No match + XabcY +No match + +/((?i)AB(?-i)C|D)E/ + abCE + 0: abCE + DE + 0: DE + *** Failers +No match + abcE +No match + abCe +No match + dE +No match + De +No match + +/[z\Qa-d]\E]/ + z + 0: z + a + 0: a + - + 0: - + d + 0: d + ] + 0: ] + *** Failers + 0: a + b +No match + +/[\z\C]/ + z + 0: z + C + 0: C + +/\M/ + M + 0: M + +/(a+)*b/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + +/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ + REGular + 0: REGular + regulaer + 0: regulaer + Regex + 0: Regex + regulär + 0: regul\xe4r + +/Åæåä[à-ÿÀ-ß]+/ + Åæåäà + 0: \xc5\xe6\xe5\xe4\xe0 + Åæåäÿ + 0: \xc5\xe6\xe5\xe4\xff + ÅæåäÀ + 0: \xc5\xe6\xe5\xe4\xc0 + Åæåäß + 0: \xc5\xe6\xe5\xe4\xdf + +/(?<=Z)X./ + \x84XAZXB + 0: XB + +/^(?(2)a|(1)(2))+$/ + 123a +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?<=a|bbbb)c/ + ac + 0: c + bbbbc + 0: c + +/abc/SS>testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex +testsavedregex +Compiled pattern written to testsavedregex +Study data written to testsavedregex + + 0: abc + xyz\r\nabc\ + 0: abc + xyz\rabc\ + 0: abc + xyz\r\nabc\ + 0: abc + ** Failers +No match + xyz\nabc\ +No match + xyz\r\nabc\ +No match + xyz\nabc\ +No match + xyz\rabc\ +No match + xyz\rabc\ +No match + +/abc$/m + xyzabc + 0: abc + xyzabc\n + 0: abc + xyzabc\npqr + 0: abc + xyzabc\r\ + 0: abc + xyzabc\rpqr\ + 0: abc + xyzabc\r\n\ + 0: abc + xyzabc\r\npqr\ + 0: abc + ** Failers +No match + xyzabc\r +No match + xyzabc\rpqr +No match + xyzabc\r\n +No match + xyzabc\r\npqr +No match + +/^abc/m + xyz\rabcdef + 0: abc + xyz\nabcdef\ + 0: abc + ** Failers +No match + xyz\nabcdef +No match + +/^abc/m + xyz\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/^abc/m + xyz\r\nabcdef + 0: abc + xyz\rabcdef\ + 0: abc + ** Failers +No match + xyz\rabcdef +No match + +/.*/ + abc\ndef + 0: abc + 1: ab + 2: a + 3: + abc\rdef + 0: abc\x0ddef + 1: abc\x0dde + 2: abc\x0dd + 3: abc\x0d + 4: abc + 5: ab + 6: a + 7: + abc\r\ndef + 0: abc\x0d + 1: abc + 2: ab + 3: a + 4: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \abc\rdef + 0: abc + 1: ab + 2: a + 3: + \abc\r\ndef + 0: abc + 1: ab + 2: a + 3: + \abc\ndef + 0: abc\x0adef + 1: abc\x0ade + 2: abc\x0ad + 3: abc\x0a + 4: abc + 5: ab + 6: a + 7: + \abc\rdef + 0: abc\x0ddef + 1: abc\x0dde + 2: abc\x0dd + 3: abc\x0d + 4: abc + 5: ab + 6: a + 7: + \abc\r\ndef + 0: abc + 1: ab + 2: a + 3: + +/\w+(.)(.)?def/s + abc\ndef + 0: abc\x0adef + abc\rdef + 0: abc\x0ddef + abc\r\ndef + 0: abc\x0d\x0adef + +/^\w+=.*(\\\n.*)*/ + abc=xyz\\\npqr + 0: abc=xyz\\x0apqr + 1: abc=xyz\\x0apq + 2: abc=xyz\\x0ap + 3: abc=xyz\\x0a + 4: abc=xyz\ + 5: abc=xyz + 6: abc=xy + 7: abc=x + 8: abc= + +/^(a()*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(?:a(?:(?:))*)*/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + 4: + +/^(a()+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/^(?:a(?:(?:))+)+/ + aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/(a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?>a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + +/(?:a|)*\d/ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +No match + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -/^\x{85}$/8i - \x{85} - 0: \x{85} +/^a.b/ + a\rb + 0: a\x0db + a\nb\ + 0: a\x0ab + ** Failers +No match + a\nb +No match + a\nb\ +No match + a\rb\ +No match + a\rb\ +No match -/^abc./mgx8 - abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK +/^abc./mgx + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x85abc7 JUNK 0: abc1 0: abc2 0: abc3 @@ -1041,265 +6815,738 @@ 0: abc5 0: abc6 0: abc7 - 0: abc8 - 0: abc9 -/abc.$/mgx8 - abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 +/abc.$/mgx + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x85 abc9 0: abc1 0: abc2 0: abc3 0: abc4 0: abc5 0: abc6 - 0: abc7 - 0: abc8 0: abc9 -/^a\Rb/8 +/^a\Rb/ a\nb - 0: a\x{0a}b + 0: a\x0ab a\rb - 0: a\x{0d}b + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b + 0: a\x0bb a\x0cb - 0: a\x{0c}b - a\x{85}b - 0: a\x{85}b - a\x{2028}b - 0: a\x{2028}b - a\x{2029}b - 0: a\x{2029}b + 0: a\x0cb + a\x85b + 0: a\x85b ** Failers No match a\n\rb No match -/^a\R*b/8 +/^a\R*b/ ab 0: ab a\nb - 0: a\x{0a}b + 0: a\x0ab a\rb - 0: a\x{0d}b + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b - a\x0c\x{2028}\x{2029}b - 0: a\x{0c}\x{2028}\x{2029}b - a\x{85}b - 0: a\x{85}b + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}\x0cb - 0: a\x{0a}\x{0d}\x{85}\x{0c}b + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb -/^a\R+b/8 +/^a\R+b/ a\nb - 0: a\x{0a}b + 0: a\x0ab a\rb - 0: a\x{0d}b + 0: a\x0db a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab a\x0bb - 0: a\x{0b}b - a\x0c\x{2028}\x{2029}b - 0: a\x{0c}\x{2028}\x{2029}b - a\x{85}b - 0: a\x{85}b + 0: a\x0bb + a\x0cb + 0: a\x0cb + a\x85b + 0: a\x85b a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}\x0cb - 0: a\x{0a}\x{0d}\x{85}\x{0c}b + 0: a\x0a\x0db + a\n\r\x85\x0cb + 0: a\x0a\x0d\x85\x0cb + ** Failers +No match + ab +No match + +/^a\R{1,3}b/ + a\nb + 0: a\x0ab + a\n\rb + 0: a\x0a\x0db + a\n\r\x85b + 0: a\x0a\x0d\x85b + a\r\n\r\nb + 0: a\x0d\x0a\x0d\x0ab + a\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0ab + a\n\r\n\rb + 0: a\x0a\x0d\x0a\x0db + a\n\n\r\nb + 0: a\x0a\x0a\x0d\x0ab ** Failers No match - ab + a\n\n\n\rb +No match + a\r +No match + +/^a[\R]b/ + aRb + 0: aRb + ** Failers +No match + a\nb +No match + +/.+foo/ + afoo + 0: afoo + ** Failers +No match + \r\nfoo +No match + \nfoo +No match + +/.+foo/ + afoo + 0: afoo + \nfoo + 0: \x0afoo + ** Failers +No match + \r\nfoo No match -/^a\R{1,3}b/8 - a\nb - 0: a\x{0a}b - a\n\rb - 0: a\x{0a}\x{0d}b - a\n\r\x{85}b - 0: a\x{0a}\x{0d}\x{85}b - a\r\n\r\nb - 0: a\x{0d}\x{0a}\x{0d}\x{0a}b - a\r\n\r\n\r\nb - 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b - a\n\r\n\rb - 0: a\x{0a}\x{0d}\x{0a}\x{0d}b - a\n\n\r\nb - 0: a\x{0a}\x{0a}\x{0d}\x{0a}b - ** Failers +/.+foo/ + afoo + 0: afoo + ** Failers No match - a\n\n\n\rb + \nfoo No match - a\r + \r\nfoo +No match + +/.+foo/s + afoo + 0: afoo + \r\nfoo + 0: \x0d\x0afoo + \nfoo + 0: \x0afoo + +/^$/mg + abc\r\rxyz + 0: + abc\n\rxyz + 0: + ** Failers +No match + abc\r\nxyz +No match + +/^X/m + XABC + 0: X + ** Failers +No match + XABC\B No match -/\h+\V?\v{3,4}/8 - \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a - 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} - 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} - -/\V?\v{3,4}/8 - \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a - 0: X\x{0a}\x{0b}\x{0c}\x{0d} - 1: X\x{0a}\x{0b}\x{0c} - -/\h+\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< - 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a} - -/\V?\v{3,4}/8 - >\x09\x20\x{a0}X\x0a\x0a\x0a< - 0: X\x{0a}\x{0a}\x{0a} +/(?m)^$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a + +/(?m)^$|^\r\n/g+ + abc\r\n\r\n + 0: \x0d\x0a + 0+ + 1: + +/(?m)$/g+ + abc\r\n\r\n + 0: + 0+ \x0d\x0a\x0d\x0a + 0: + 0+ \x0d\x0a + 0: + 0+ + +/(?|(abc)|(xyz))/ + >abc< + 0: abc + >xyz< + 0: xyz -/\H\h\V\v/8 +/(x)(?|(abc)|(xyz))(x)/ + xabcx + 0: xabcx + xxyzx + 0: xxyzx + +/(x)(?|(abc)(pqr)|(xyz))(x)/ + xabcpqrx + 0: xabcpqrx + xxyzx + 0: xxyzx + +/(?|(abc)|(xyz))(?1)/ + abcabc + 0: abcabc + xyzabc + 0: xyzabc + ** Failers +No match + xyzxyz +No match + +/\H\h\V\v/ X X\x0a - 0: X X\x{0a} + 0: X X\x0a X\x09X\x0b - 0: X\x{09}X\x{0b} + 0: X\x09X\x0b ** Failers No match - \x{a0} X\x0a + \xa0 X\x0a No match -/\H*\h+\V?\v{3,4}/8 - \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a - 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} - 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} - \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a - 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} - 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} - \x09\x20\x{a0}\x0a\x0b\x0c - 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} +/\H*\h+\V?\v{3,4}/ + \x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a + 0: \x09 \xa0X\x0a\x0b\x0c\x0d + 1: \x09 \xa0X\x0a\x0b\x0c + \x09\x20\xa0\x0a\x0b\x0c\x0d\x0a + 0: \x09 \xa0\x0a\x0b\x0c\x0d + 1: \x09 \xa0\x0a\x0b\x0c + \x09\x20\xa0\x0a\x0b\x0c + 0: \x09 \xa0\x0a\x0b\x0c ** Failers No match - \x09\x20\x{a0}\x0a\x0b + \x09\x20\xa0\x0a\x0b No match -/\H\h\V\v/8 - \x{3001}\x{3000}\x{2030}\x{2028} - 0: \x{3001}\x{3000}\x{2030}\x{2028} - X\x{180e}X\x{85} - 0: X\x{180e}X\x{85} - ** Failers -No match - \x{2009} X\x0a -No match - -/\H*\h+\V?\v{3,4}/8 - \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a - 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} - 1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c} - \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a - 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} - 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} - \x09\x20\x{202f}\x0a\x0b\x0c - 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} - ** Failers +/\H{3,4}/ + XY ABCDE + 0: ABCD + 1: ABC + XY PQR ST + 0: PQR + +/.\h{3,4}./ + XY AB PQRS + 0: B P + 1: B + +/\h*X\h?\H+Y\H?Z/ + >XNNNYZ + 0: XNNNYZ + > X NYQZ + 0: X NYQZ + ** Failers No match - \x09\x{200a}\x{a0}\x{2028}\x0b + >XYZ No match - -/a\Rb/I8 + > X NY Z +No match + +/\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c/ + >XY\x0aZ\x0aA\x0bNN\x0c + 0: XY\x0aZ\x0aA\x0bNN\x0c + >\x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + 0: \x0a\x0dX\x0aY\x0a\x0bZZZ\x0aAAA\x0bNNN\x0c + +/.+A/ + \r\nA +No match + +/\nA/ + \r\nA + 0: \x0aA + +/[\r\n]A/ + \r\nA + 0: \x0aA + +/(\r|\n)A/ + \r\nA + 0: \x0aA + +/a\Rb/I Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb - 0: a\x{0d}b + 0: a\x0db a\nb - 0: a\x{0a}b + 0: a\x0ab a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab ** Failers No match - a\x{85}b + a\x85b No match a\x0bb No match -/a\Rb/I8 +/a\Rb/I Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode First char = 'a' Need char = 'b' a\rb - 0: a\x{0d}b + 0: a\x0db a\nb - 0: a\x{0a}b + 0: a\x0ab a\r\nb - 0: a\x{0d}\x{0a}b - a\x{85}b - 0: a\x{85}b + 0: a\x0d\x0ab + a\x85b + 0: a\x85b a\x0bb - 0: a\x{0b}b + 0: a\x0bb ** Failers No match - a\x{85}b\ + a\x85b\ No match a\x0bb\ No match -/a\R?b/I8 +/a\R?b/I Capturing subpattern count = 0 -Options: bsr_anycrlf utf8 +Options: bsr_anycrlf First char = 'a' Need char = 'b' a\rb - 0: a\x{0d}b + 0: a\x0db a\nb - 0: a\x{0a}b + 0: a\x0ab a\r\nb - 0: a\x{0d}\x{0a}b + 0: a\x0d\x0ab ** Failers No match - a\x{85}b + a\x85b No match a\x0bb No match -/a\R?b/I8 +/a\R?b/I Capturing subpattern count = 0 -Options: bsr_unicode utf8 +Options: bsr_unicode First char = 'a' Need char = 'b' a\rb - 0: a\x{0d}b + 0: a\x0db a\nb - 0: a\x{0a}b + 0: a\x0ab a\r\nb - 0: a\x{0d}\x{0a}b - a\x{85}b - 0: a\x{85}b + 0: a\x0d\x0ab + a\x85b + 0: a\x85b a\x0bb - 0: a\x{0b}b + 0: a\x0bb ** Failers No match - a\x{85}b\ + a\x85b\ No match a\x0bb\ No match - -/X/8f - A\x{1ec5}ABCXYZ + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_anycrlf +First char = 'a' +Need char = 'b' + a\r\n\nb + 0: a\x0d\x0a\x0ab + a\n\r\rb + 0: a\x0a\x0d\x0db + a\r\n\r\n\r\n\r\nb + 0: a\x0d\x0a\x0d\x0a\x0d\x0a\x0d\x0ab + ** Failers +No match + a\x85\85b +No match + a\x0b\0bb +No match + +/a\R{2,4}b/I +Capturing subpattern count = 0 +Options: bsr_unicode +First char = 'a' +Need char = 'b' + a\r\rb + 0: a\x0d\x0db + a\n\n\nb + 0: a\x0a\x0a\x0ab + a\r\n\n\r\rb + 0: a\x0d\x0a\x0a\x0d\x0db + a\x85\85b +No match + a\x0b\0bb +No match + ** Failers +No match + a\r\r\r\r\rb +No match + a\x85\85b\ +No match + a\x0b\0bb\ +No match + +/a(?!)|\wbc/ + abc + 0: abc + +/a[]b/ + ** Failers +No match + ab +No match + +/a[]+b/ + ** Failers +No match + ab +No match + +/a[]*+b/ + ** Failers +No match + ab +No match + +/a[^]b/ + aXb + 0: aXb + a\nb + 0: a\x0ab + ** Failers +No match + ab +No match + +/a[^]+b/ + aXb + 0: aXb + a\nX\nXb + 0: a\x0aX\x0aXb + ** Failers +No match + ab +No match + +/X$/E + X + 0: X + ** Failers +No match + X\n +No match + +/X$/ + X 0: X + X\n + 0: X + +/xyz/C + xyz +--->xyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz +--->abcxyz + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + abcxyz\Y +--->abcxyz + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +3 ^ ^ + 0: xyz + ** Failers +No match + abc +No match + abc\Y +--->abc + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + abcxypqr +No match + abcxypqr\Y +--->abcxypqr + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +1 ^^ y + +2 ^ ^ z + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x + +0 ^ x +No match + +/(*NO_START_OPT)xyz/C + abcxyz +--->abcxyz ++15 ^ x ++15 ^ x ++15 ^ x ++15 ^ x ++16 ^^ y ++17 ^ ^ z ++18 ^ ^ + 0: xyz + +/(?C)ab/ + ab +--->ab + 0 ^ a + 0: ab + \C-ab + 0: ab + +/ab/C + ab +--->ab + +0 ^ a + +1 ^^ b + +2 ^ ^ + 0: ab + \C-ab + 0: ab + +/^"((?(?=[a])[^"])|b)*"$/C + "ab" +--->"ab" + +0 ^ ^ + +1 ^ " + +2 ^^ ((?(?=[a])[^"])|b)* ++21 ^^ " + +3 ^^ (?(?=[a])[^"]) ++18 ^^ b + +5 ^^ (?=[a]) + +8 ^ [a] ++11 ^^ ) ++12 ^^ [^"] ++16 ^ ^ ) ++17 ^ ^ | ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++19 ^ ^ ) ++21 ^ ^ " + +3 ^ ^ (?(?=[a])[^"]) ++18 ^ ^ b + +5 ^ ^ (?=[a]) + +8 ^ [a] ++17 ^ ^ | ++22 ^ ^ $ ++23 ^ ^ + 0: "ab" + \C-"ab" + 0: "ab" + +/\d+X|9+Y/ + ++++123999\P +Partial match: 123999 + ++++123999Y\P + 0: 999Y + +/Z(*F)/ + Z\P +No match + ZA\P +No match + +/Z(?!)/ + Z\P +No match + ZA\P +No match + +/dog(sbody)?/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog(sbody)??/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dog|dogsbody/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/dogsbody|dog/ + dogs\P + 0: dog + dogs\P\P +Partial match: dogs + +/Z(*F)Q|ZXY/ + Z\P +Partial match: Z + ZA\P +No match + X\P +No match + +/\bthe cat\b/ + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/dog(sbody)?/ + dogs\D\P + 0: dog + body\D\R + 0: body + +/dog(sbody)?/ + dogs\D\P\P +Partial match: dogs + body\D\R + 0: body + +/abc/ + abc\P + 0: abc + abc\P\P + 0: abc + +/abc\K123/ + xyzabc123pqr +Error -16 (item unsupported for DFA matching) + +/(?<=abc)123/ + xyzabc123pqr + 0: 123 + xyzabc12\P +Partial match: abc12 + xyzabc12\P\P +Partial match: abc12 + +/\babc\b/ + +++abc+++ + 0: abc + +++ab\P +Partial match: +ab + +++ab\P\P +Partial match: +ab + +/(?=C)/g+ + ABCDECBA + 0: + 0+ CDECBA + 0: + 0+ CBA + +/(abc|def|xyz)/I +Capturing subpattern count = 1 +No options +No first char +No need char + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + +/(abc|def|xyz)/SI +Capturing subpattern count = 1 +No options +No first char +No need char +Subject length lower bound = 3 +Starting byte set: a d x + terhjk;abcdaadsfe + 0: abc + the quick xyz brown fox + 0: xyz + \Yterhjk;abcdaadsfe + 0: abc + \Ythe quick xyz brown fox + 0: xyz + ** Failers +No match + thejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match + \Ythejk;adlfj aenjl;fda asdfasd ehj;kjxyasiupd +No match -/abcd*/8 +/abcd*/+ xxxxabcd\P 0: abcd + 0+ 1: abc xxxxabcd\P\P Partial match: abcd + dddxxx\R + 0: ddd + 0+ xxx + 1: dd + 2: d + 3: + xxxxabcd\P\P +Partial match: abcd + xxx\R + 0: + 0+ xxx -/abcd*/i8 +/abcd*/i xxxxabcd\P 0: abcd 1: abc @@ -1311,14 +7558,14 @@ XXXXABCD\P\P Partial match: ABCD -/abc\d*/8 +/abc\d*/ xxxxabc1\P 0: abc1 1: abc xxxxabc1\P\P Partial match: abc1 -/abc[de]*/8 +/abc[de]*/ xxxxabcde\P 0: abcde 1: abcd @@ -1326,26 +7573,447 @@ xxxxabcde\P\P Partial match: abcde -/\bthe cat\b/8 - the cat\P - 0: the cat - the cat\P\P -Partial match: the cat +/(?:(?1)|B)(A(*F)|C)/ + ABCD + 0: BC + CCD + 0: CC + ** Failers +No match + CAD +No match -/a+/8 - a\x{123}aa\>1 - 0: aa - 1: a - a\x{123}aa\>2 -Error -11 - a\x{123}aa\>3 +/^(?:(?1)|B)(A(*F)|C)/ + CCD + 0: CC + BCD + 0: BC + ** Failers +No match + ABCD +No match + CAD +No match + BAD +No match + +/^(?!a(*SKIP)b)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*THEN)b|ac)/ + ac +Error -16 (item unsupported for DFA matching) + +/^(?=a(*PRUNE)b)/ + ab +Error -16 (item unsupported for DFA matching) + ** Failers +No match + ac +Error -16 (item unsupported for DFA matching) + +/^(?(?!a(*SKIP)b))/ + ac +Error -16 (item unsupported for DFA matching) + +/(?<=abc)def/ + abc\P\P +Partial match: abc + +/abc$/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc$/m + abc + 0: abc + abc\n + 0: abc + abc\P\P +Partial match: abc + abc\n\P\P + 0: abc + abc\P + 0: abc + abc\n\P + 0: abc + +/abc\z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\Z/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\b/ + abc + 0: abc + abc\P + 0: abc + abc\P\P +Partial match: abc + +/abc\B/ + abc +No match + abc\P +Partial match: abc + abc\P\P +Partial match: abc + +/.+/ + abc\>0 + 0: abc + 1: ab + 2: a + abc\>1 + 0: bc + 1: b + abc\>2 + 0: c + abc\>3 +No match + abc\>4 +Error -24 (bad offset value) + abc\>-4 +Error -24 (bad offset value) + +/^(?:a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(?:aa|(?:a)++\w)/ + aaaab + 0: aaaab + 1: aa + aaaa 0: aa - 1: a - a\x{123}aa\>4 - 0: a - a\x{123}aa\>5 + ** Failers +No match + bbb +No match + +/^(?:a)*+\w/ + aaaab + 0: aaaab + bbb + 0: b + ** Failers +No match + aaaa +No match + +/^(a)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/^(a|)++\w/ + aaaab + 0: aaaab + ** Failers +No match + aaaa +No match + bbb +No match + +/(?=abc){3}abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)+abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers +No match + xyz +No match + +/(?=abc)++abc/+ + abcabcabc + 0: abc + 0+ abcabc + ** Failers No match - a\x{123}aa\>6 -Error -24 + xyz +No match + +/(?=abc){0}xyz/ + xyz + 0: xyz + +/(?=abc){1}xyz/ + ** Failers +No match + xyz +No match + +/(?=(a))?./ + ab + 0: a + bc + 0: b + +/(?=(a))??./ + ab + 0: a + bc + 0: b + +/^(?=(a)){0}b(?1)/ + backgammon + 0: ba + +/^(?=(?1))?[az]([abc])d/ + abd + 0: abd + zcdxx + 0: zcd + +/^(?!a){0}\w+/ + aaaaa + 0: aaaaa + 1: aaaa + 2: aaa + 3: aa + 4: a + +/(?<=(abc))?xyz/ + abcxyz + 0: xyz + pqrxyz + 0: xyz + +/((?2))((?1))/ + abc +Error -26 (nested recursion at the same subject position) + +/(?(R)a+|(?R)b)/ + aaaabcde + 0: aaaab + +/(?(R)a+|((?R))b)/ + aaaabcde + 0: aaaab + +/((?(R)a+|(?1)b))/ + aaaabcde + 0: aaaab + +/((?(R2)a+|(?1)b))/ + aaaabcde +Error -17 (backreference condition or recursion test not supported for DFA matching) + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde +Error -26 (nested recursion at the same subject position) + +/(a+)/ + \O6aaaa +Matched, but too many subsidiary matches + 0: aaaa + 1: aaa + 2: aa + \O8aaaa + 0: aaaa + 1: aaa + 2: aa + 3: a + +/ab\Cde/ + abXde + 0: abXde + +/(?<=ab\Cde)X/ + abZdeX + 0: X + +/^\R/ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/^\R{2,3}x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R{2,3}?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P +Partial match: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P +Partial match: \x0d\x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + \r\rx + 0: \x0d\x0dx + \r\r\rx + 0: \x0d\x0d\x0dx + +/^\R?x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + x + 0: x + \rx + 0: \x0dx + +/^\R+x/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\n\P +Partial match: \x0d\x0a + \r\n\P\P +Partial match: \x0d\x0a + \rx + 0: \x0dx + +/^a$/ + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^a$/m + a\r\P +Partial match: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/ + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/^(a$|a\r)/m + a\r\P + 0: a\x0d + a\r\P\P +Partial match: a\x0d + +/./ + \r\P + 0: \x0d + \r\P\P +Partial match: \x0d + +/.{2,3}/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + 1: \x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/.{2,3}?/ + \r\P +Partial match: \x0d + \r\P\P +Partial match: \x0d + \r\r\P + 0: \x0d\x0d + \r\r\P\P +Partial match: \x0d\x0d + \r\r\r\P + 0: \x0d\x0d\x0d + 1: \x0d\x0d + \r\r\r\P\P +Partial match: \x0d\x0d\x0d + +/-- Test simple validity check for restarts --/ + +/abcdef/ + abc\R +Error -30 (invalid data in workspace for DFA restart) + +/)(.)|(?R))++)*F>/ + text text xxxxx text F> text2 more text. + 0: text xxxxx text F> + +/^(?>.{4})abc|^\w\w.xabcd/ + xxxxabcd + 0: xxxxabcd + 1: xxxxabc + xx\xa0xabcd + 0: xx\xa0xabcd + 1: xx\xa0xabc + +/^(.{4}){2}+abc|^\w\w.x\w\w\w\wabcd/ + xxxxxxxxabcd + 0: xxxxxxxxabcd + 1: xxxxxxxxabc + xx\xa0xxxxxabcd + 0: xx\xa0xxxxxabcd + 1: xx\xa0xxxxxabc -/-- End of testinput8 --/ +/-- End of testinput8 --/ diff -Nru pcre3-8.12/testdata/testoutput9 pcre3-8.31/testdata/testoutput9 --- pcre3-8.12/testdata/testoutput9 2010-05-08 11:37:22.000000000 +0000 +++ pcre3-8.31/testdata/testoutput9 2012-06-01 18:32:31.000000000 +0000 @@ -1,2037 +1,1371 @@ -/-- This set of tests check Unicode property support with the DFA matching - functionality of pcre_dfa_exec(). The -dfa flag must be used with pcretest - when running it. --/ - -/\pL\P{Nd}/8 - AB - 0: AB - *** Failers - 0: Fa - A0 +/-- This set of tests checks UTF-8 support with the DFA matching functionality + of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running + it. --/ + +/\x{100}ab/8 + \x{100}ab + 0: \x{100}ab + +/a\x{100}*b/8 + ab + 0: ab + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + +/a\x{100}+b/8 + a\x{100}b + 0: a\x{100}b + a\x{100}\x{100}b + 0: a\x{100}\x{100}b + *** Failers No match - 00 + ab No match - -/\X./8 - AB - 0: AB - A\x{300}BC - 0: A\x{300}B - A\x{300}\x{301}\x{302}BC - 0: A\x{300}\x{301}\x{302}B - *** Failers - 0: ** - \x{300} + +/\bX/8 + Xoanon + 0: X + +Xoanon + 0: X + \x{300}Xoanon + 0: X + *** Failers No match - -/\X\X/8 - ABC - 0: AB - A\x{300}B\x{300}\x{301}C - 0: A\x{300}B\x{300}\x{301} - A\x{300}\x{301}\x{302}BC - 0: A\x{300}\x{301}\x{302}B + YXoanon +No match + +/\BX/8 + YXoanon + 0: X *** Failers - 0: ** - \x{300} No match - -/^\pL+/8 - abcd - 0: abcd - 1: abc - 2: ab - 3: a - a - 0: a - *** Failers + Xoanon No match - -/^\PL+/8 - 1234 - 0: 1234 - 1: 123 - 2: 12 - 3: 1 - = - 0: = - *** Failers - 0: *** - 1: *** - 2: ** - 3: * - abcd + +Xoanon +No match + \x{300}Xoanon No match -/^\X+/8 - abcdA\x{300}\x{301}\x{302} - 0: abcdA\x{300}\x{301}\x{302} - 1: abcd - 2: abc - 3: ab - 4: a - A\x{300}\x{301}\x{302} - 0: A\x{300}\x{301}\x{302} - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} - 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302} - 1: A\x{300}\x{301}\x{302} - a - 0: a +/X\b/8 + X+oanon + 0: X + ZX\x{300}oanon + 0: X + FAX + 0: X *** Failers - 0: *** Failers - 1: *** Failer - 2: *** Faile - 3: *** Fail - 4: *** Fai - 5: *** Fa - 6: *** F - 7: *** - 8: *** - 9: ** -10: * - \x{300}\x{301}\x{302} No match - -/\X?abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}abc - \x{300}abc - 0: abc - *** Failers + Xoanon No match - -/^\X?abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc + +/X\B/8 + Xoanon + 0: X *** Failers No match - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz + X+oanon No match - \x{300}abc + ZX\x{300}oanon No match - -/\X*abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc - \x{300}abc - 0: abc - *** Failers + FAX No match + +/[^a]/8 + abcd + 0: b + a\x{100} + 0: \x{100} -/^\X*abc/8 - abc - 0: abc - A\x{300}abc - 0: A\x{300}abc - A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abcxyz - 0: A\x{300}\x{301}\x{302}A\x{300}A\x{300}A\x{300}abc +/^[abc\x{123}\x{400}-\x{402}]{2,3}\d/8 + ab99 + 0: ab9 + \x{123}\x{123}45 + 0: \x{123}\x{123}4 + \x{400}\x{401}\x{402}6 + 0: \x{400}\x{401}\x{402}6 *** Failers No match - \x{300}abc + d99 No match - -/^\pL?=./8 - A=b - 0: A=b - =c - 0: =c - *** Failers + \x{123}\x{122}4 No match - 1=2 + \x{400}\x{403}6 No match - AAAA=b + \x{400}\x{401}\x{402}\x{402}6 No match -/^\pL*=./8 - AAAA=b - 0: AAAA=b - =c - 0: =c +/a.b/8 + acb + 0: acb + a\x7fb + 0: a\x{7f}b + a\x{100}b + 0: a\x{100}b *** Failers No match - 1=2 + a\nb No match -/^\X{2,3}X/8 - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X - 0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X +/a(.{3})b/8 + a\x{4000}xyb + 0: a\x{4000}xyb + a\x{4000}\x7fyb + 0: a\x{4000}\x{7f}yb + a\x{4000}\x{100}yb + 0: a\x{4000}\x{100}yb *** Failers No match - X -No match - A\x{300}\x{301}\x{302}X + a\x{4000}b No match - A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}X + ac\ncb No match -/^\pC\pL\pM\pN\pP\pS\pZ\S/8 + > >X Y + 0: >X + > >\x{100} Y + 0: >\x{100} + +/\d/8 + \x{100}3 + 0: 3 -/^\p{Han}+/8 - \x{2e81}\x{3007}\x{2f804}\x{31a0} - 0: \x{2e81}\x{3007}\x{2f804} - 1: \x{2e81}\x{3007} - 2: \x{2e81} - ** Failers -No match - \x{2e7f} +/\s/8 + \x{100} X + 0: + +/\D+/8 + 12abcd34 + 0: abcd + 1: abc + 2: ab + 3: a + *** Failers + 0: *** Failers + 1: *** Failer + 2: *** Faile + 3: *** Fail + 4: *** Fai + 5: *** Fa + 6: *** F + 7: *** + 8: *** + 9: ** +10: * + 1234 No match -/^\P{Katakana}+/8 - \x{3105} - 0: \x{3105} - ** Failers - 0: ** Failers - 1: ** Failer - 2: ** Faile - 3: ** Fail - 4: ** Fai - 5: ** Fa - 6: ** F - 7: ** - 8: ** - 9: * - \x{30ff} -No match - -/^[\p{Arabic}]/8 - \x{06e9} - 0: \x{6e9} - \x{060b} - 0: \x{60b} - ** Failers +/\D{2,3}/8 + 12abcd34 + 0: abc + 1: ab + 12ab34 + 0: ab + *** Failers + 0: *** + 1: ** + 1234 No match - X\x{06e9} + 12a34 No match -/^[\P{Yi}]/8 - \x{2f800} - 0: \x{2f800} - ** Failers - 0: * - \x{a014} +/\D{2,3}?/8 + 12abcd34 + 0: abc + 1: ab + 12ab34 + 0: ab + *** Failers + 0: *** + 1: ** + 1234 No match - \x{a4c6} + 12a34 No match -/^\p{Any}X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - X -No match - -/^\P{Any}X/8 - ** Failers -No match - AX -No match - -/^\p{Any}?X/8 - XYZ - 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - ** Failers -No match - ABXYZ +/\d+/8 + 12abcd34 + 0: 12 + 1: 1 + *** Failers No match -/^\P{Any}?X/8 - XYZ - 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - ABXYZ +/\d{2,3}/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers +No match + 1.4 +No match + +/\d{2,3}?/8 + 12abcd34 + 0: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers +No match + 1.4 +No match + +/\S+/8 + 12abcd34 + 0: 12abcd34 + 1: 12abcd3 + 2: 12abcd + 3: 12abc + 4: 12ab + 5: 12a + 6: 12 + 7: 1 + *** Failers + 0: *** + 1: ** + 2: * + \ \ No match -/^\p{Any}+X/8 - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers -No match - XYZ +/\S{2,3}/8 + 12abcd34 + 0: 12a + 1: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers + 0: *** + 1: ** + \ \ No match -/^\P{Any}+X/8 - ** Failers -No match - AXYZ -No match - \x{1234}XYZ -No match - A\x{1234}XYZ -No match - XYZ +/\S{2,3}?/8 + 12abcd34 + 0: 12a + 1: 12 + 1234abcd + 0: 123 + 1: 12 + *** Failers + 0: *** + 1: ** + \ \ No match -/^\p{Any}*X/8 - XYZ - 0: X - AXYZ - 0: AX - \x{1234}XYZ - 0: \x{1234}X - A\x{1234}XYZ - 0: A\x{1234}X - ** Failers +/>\s+ <34 + 0: > < + *** Failers No match -/^\P{Any}*X/8 - XYZ - 0: X - ** Failers -No match - AXYZ -No match - \x{1234}XYZ +/>\s{2,3} < + ab> < + *** Failers No match - A\x{1234}XYZ + ab> \s{2,3}? < + ab> < + *** Failers No match - ABXYZ + ab> \xff< + 0: \xff -/^\x{023a}+?(\x{0130}+)/8i - \x{023a}\x{2c65}\x{0130} - 0: \x{23a}\x{2c65}\x{130} - -/^\x{023a}+([^X])/8i - \x{023a}\x{2c65}X - 0: \x{23a}\x{2c65} - -/\x{c0}+\x{116}+/8i - \x{c0}\x{e0}\x{116}\x{117} - 0: \x{c0}\x{e0}\x{116}\x{117} - 1: \x{c0}\x{e0}\x{116} - -/[\x{c0}\x{116}]+/8i - \x{c0}\x{e0}\x{116}\x{117} - 0: \x{c0}\x{e0}\x{116}\x{117} - 1: \x{c0}\x{e0}\x{116} - 2: \x{c0}\x{e0} - 3: \x{c0} +/[\xff]/8 + >\x{ff}< + 0: \x{ff} -/Check property support in non-UTF-8 mode/ - -/\p{L}{4}/ - 123abcdefg - 0: abcd - 123abc\xc4\xc5zz - 0: abc\xc4 +/[^\xFF]/ + XYZ + 0: X -/\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}/8 - \x{102A4}\x{AA52}\x{A91D}\x{1C46}\x{10283}\x{1092E}\x{1C6B}\x{A93B}\x{A8BF}\x{1BA0}\x{A50A}==== - 0: \x{102a4}\x{aa52}\x{a91d}\x{1c46}\x{10283}\x{1092e}\x{1c6b}\x{a93b}\x{a8bf}\x{1ba0}\x{a50a} - -/\x{a77d}\x{1d79}/8i - \x{a77d}\x{1d79} - 0: \x{a77d}\x{1d79} - \x{1d79}\x{a77d} - 0: \x{1d79}\x{a77d} - -/\x{a77d}\x{1d79}/8 - \x{a77d}\x{1d79} - 0: \x{a77d}\x{1d79} - ** Failers -No match - \x{1d79}\x{a77d} +/[^\xff]/8 + XYZ + 0: X + \x{123} + 0: \x{123} + +/^[ac]*b/8 + xb No match -/^\p{Xan}/8 - ABCD - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - ** Failers +/^[ac\x{100}]*b/8 + xb No match - _ABC + +/^[^x]*b/8i + xb No match -/^\p{Xan}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A - ** Failers +/^[^x]*b/8 + xb No match - _ABC + +/^\d*b/8 + xb No match -/^\p{Xan}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A -11: - -/^\p{Xan}{2,9}/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca} - 1: ABCD1234 - 2: ABCD123 - 3: ABCD12 - 4: ABCD1 - 5: ABCD - 6: ABC - 7: AB - -/^[\p{Xan}]/8 - ABCD1234_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} +/(|a)/g8 + catac + 0: + 0: a + 1: + 0: + 0: a + 1: + 0: + 0: + a\x{256}a + 0: a + 1: + 0: + 0: a + 1: + 0: + +/^\x{85}$/8i + \x{85} + 0: \x{85} + +/^abc./mgx8 + abc1 \x0aabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\x0aabc6 \x{0085}abc7 \x{2028}abc8 \x{2029}abc9 JUNK + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + 0: abc8 + 0: abc9 + +/abc.$/mgx8 + abc1\x0a abc2\x0b abc3\x0c abc4\x0d abc5\x0d\x0a abc6\x{0085} abc7\x{2028} abc8\x{2029} abc9 + 0: abc1 + 0: abc2 + 0: abc3 + 0: abc4 + 0: abc5 + 0: abc6 + 0: abc7 + 0: abc8 + 0: abc9 + +/^a\Rb/8 + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0cb + 0: a\x{0c}b + a\x{85}b + 0: a\x{85}b + a\x{2028}b + 0: a\x{2028}b + a\x{2029}b + 0: a\x{2029}b + ** Failers +No match + a\n\rb +No match + +/^a\R*b/8 + ab + 0: ab + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0c\x{2028}\x{2029}b + 0: a\x{0c}\x{2028}\x{2029}b + a\x{85}b + 0: a\x{85}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}\x0cb + 0: a\x{0a}\x{0d}\x{85}\x{0c}b + +/^a\R+b/8 + a\nb + 0: a\x{0a}b + a\rb + 0: a\x{0d}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x0bb + 0: a\x{0b}b + a\x0c\x{2028}\x{2029}b + 0: a\x{0c}\x{2028}\x{2029}b + a\x{85}b + 0: a\x{85}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}\x0cb + 0: a\x{0a}\x{0d}\x{85}\x{0c}b + ** Failers +No match + ab +No match + +/^a\R{1,3}b/8 + a\nb + 0: a\x{0a}b + a\n\rb + 0: a\x{0a}\x{0d}b + a\n\r\x{85}b + 0: a\x{0a}\x{0d}\x{85}b + a\r\n\r\nb + 0: a\x{0d}\x{0a}\x{0d}\x{0a}b + a\r\n\r\n\r\nb + 0: a\x{0d}\x{0a}\x{0d}\x{0a}\x{0d}\x{0a}b + a\n\r\n\rb + 0: a\x{0a}\x{0d}\x{0a}\x{0d}b + a\n\n\r\nb + 0: a\x{0a}\x{0a}\x{0d}\x{0a}b + ** Failers +No match + a\n\n\n\rb +No match + a\r +No match + +/\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} + +/\V?\v{3,4}/8 + \x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + 0: X\x{0a}\x{0b}\x{0c}\x{0d} + 1: X\x{0a}\x{0b}\x{0c} + +/\h+\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + 0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a} + +/\V?\v{3,4}/8 + >\x09\x20\x{a0}X\x0a\x0a\x0a< + 0: X\x{0a}\x{0a}\x{0a} + +/\H\h\V\v/8 + X X\x0a + 0: X X\x{0a} + X\x09X\x0b + 0: X\x{09}X\x{0b} ** Failers No match - _ABC + \x{a0} X\x0a No match - -/^[\p{Xan}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 1: ABCD1234\x{6ca}\x{a6c} - 2: ABCD1234\x{6ca} - 3: ABCD1234 - 4: ABCD123 - 5: ABCD12 - 6: ABCD1 - 7: ABCD - 8: ABC - 9: AB -10: A - ** Failers + +/\H*\h+\V?\v{3,4}/8 + \x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c} + \x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c}\x{0d} + 1: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + \x09\x20\x{a0}\x0a\x0b\x0c + 0: \x{09} \x{a0}\x{0a}\x{0b}\x{0c} + ** Failers No match - _ABC + \x09\x20\x{a0}\x0a\x0b No match - -/^>\p{Xsp}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} + +/\H\h\V\v/8 + \x{3001}\x{3000}\x{2030}\x{2028} + 0: \x{3001}\x{3000}\x{2030}\x{2028} + X\x{180e}X\x{85} + 0: X\x{180e}X\x{85} ** Failers No match - \x{0b} + \x{2009} X\x0a No match - -/^>\p{Xsp}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > - -/^>\p{Xsp}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > - 8: > - -/^>\p{Xsp}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} -/^>[\p{Xsp}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\p{Xsp}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 3: > \x{09}\x{0a}\x{0c}\x{0d} - 4: > \x{09}\x{0a}\x{0c} - 5: > \x{09}\x{0a} - 6: > \x{09} - 7: > - -/^>\p{Xps}/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680} - >\x{a0} - 0: >\x{a0} - ** Failers +/\H*\h+\V?\v{3,4}/8 + \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a + 0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d} + 1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c} + \x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a + 0: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c}\x{2028} + 1: \x{09}\x{205f}\x{a0}\x{0a}\x{2029}\x{0c} + \x09\x20\x{202f}\x0a\x0b\x0c + 0: \x{09} \x{202f}\x{0a}\x{0b}\x{0c} + ** Failers No match - \x{0b} + \x09\x{200a}\x{a0}\x{2028}\x0b No match - -/^>\p{Xps}+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > - -/^>\p{Xps}+?/8 - >\x{1680}\x{2028}\x{0b} - 0: >\x{1680}\x{2028}\x{0b} - 1: >\x{1680}\x{2028} - 2: >\x{1680} - -/^>\p{Xps}*/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > - 9: > - -/^>\p{Xps}{2,9}/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - -/^>\p{Xps}{2,9}?/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - -/^>[\p{Xps}]/8 - >\x{2028}\x{0b} - 0: >\x{2028} - -/^>[\p{Xps}]+/8 - > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b} - 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028} - 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680} - 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0} - 4: > \x{09}\x{0a}\x{0c}\x{0d} - 5: > \x{09}\x{0a}\x{0c} - 6: > \x{09}\x{0a} - 7: > \x{09} - 8: > - -/^\p{Xwd}/8 - ABCD - 0: A - 1234 - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\Rb/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers No match - [] + a\x{85}b\ +No match + a\x0bb\ No match - -/^\p{Xwd}+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A - -/^\p{Xwd}*/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A -12: - -/^\p{Xwd}{2,9}/8 - A_12\x{6ca}\x{a6c}\x{10a7} - 0: A_12\x{6ca}\x{a6c}\x{10a7} - 1: A_12\x{6ca}\x{a6c} - 2: A_12\x{6ca} - 3: A_12 - 4: A_1 - 5: A_ -/^[\p{Xwd}]/8 - ABCD1234_ - 0: A - 1234abcd_ - 0: 1 - \x{6ca} - 0: \x{6ca} - \x{a6c} - 0: \x{a6c} - \x{10a7} - 0: \x{10a7} - _ABC - 0: _ - ** Failers +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_anycrlf utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + ** Failers +No match + a\x{85}b +No match + a\x0bb +No match + +/a\R?b/I8 +Capturing subpattern count = 0 +Options: bsr_unicode utf +First char = 'a' +Need char = 'b' + a\rb + 0: a\x{0d}b + a\nb + 0: a\x{0a}b + a\r\nb + 0: a\x{0d}\x{0a}b + a\x{85}b + 0: a\x{85}b + a\x0bb + 0: a\x{0b}b + ** Failers +No match + a\x{85}b\ No match - [] + a\x0bb\ No match -/^[\p{Xwd}]+/8 - ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_ - 1: ABCD1234\x{6ca}\x{a6c}\x{10a7} - 2: ABCD1234\x{6ca}\x{a6c} - 3: ABCD1234\x{6ca} - 4: ABCD1234 - 5: ABCD123 - 6: ABCD12 - 7: ABCD1 - 8: ABCD - 9: ABC -10: AB -11: A +/X/8f + A\x{1ec5}ABCXYZ + 0: X -/-- Unicode properties for \b abd \B --/ +/abcd*/8 + xxxxabcd\P + 0: abcd + 1: abc + xxxxabcd\P\P +Partial match: abcd -/\b...\B/8W - abc_ - 0: abc - \x{37e}abc\x{376} - 0: abc - \x{37e}\x{376}\x{371}\x{393}\x{394} - 0: \x{376}\x{371}\x{393} - !\x{c0}++\x{c1}\x{c2} - 0: ++\x{c1} - !\x{c0}+++++ - 0: \x{c0}++ +/abcd*/i8 + xxxxabcd\P + 0: abcd + 1: abc + xxxxabcd\P\P +Partial match: abcd + XXXXABCD\P + 0: ABCD + 1: ABC + XXXXABCD\P\P +Partial match: ABCD + +/abc\d*/8 + xxxxabc1\P + 0: abc1 + 1: abc + xxxxabc1\P\P +Partial match: abc1 -/-- Without PCRE_UCP, non-ASCII always fail, even if < 256 --/ +/abc[de]*/8 + xxxxabcde\P + 0: abcde + 1: abcd + 2: abc + xxxxabcde\P\P +Partial match: abcde -/\b...\B/8 - abc_ - 0: abc - ** Failers - 0: Fai - \x{37e}abc\x{376} -No match - \x{37e}\x{376}\x{371}\x{393}\x{394} -No match - !\x{c0}++\x{c1}\x{c2} -No match - !\x{c0}+++++ -No match +/\bthe cat\b/8 + the cat\P + 0: the cat + the cat\P\P +Partial match: the cat + +/ab\Cde/8 + abXde +Error -16 (item unsupported for DFA matching) + +/(?<=ab\Cde)X/8 +Failed: \C not allowed in lookbehind assertion at offset 10 + +/./8 + \r\P + 0: \x{0d} + \r\P\P +Partial match: \x{0d} + +/.{2,3}/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d}\x{0d} + 1: \x{0d}\x{0d} + \r\r\r\P\P +Partial match: \x{0d}\x{0d}\x{0d} + +/.{2,3}?/8 + \r\P +Partial match: \x{0d} + \r\P\P +Partial match: \x{0d} + \r\r\P + 0: \x{0d}\x{0d} + \r\r\P\P +Partial match: \x{0d}\x{0d} + \r\r\r\P + 0: \x{0d}\x{0d}\x{0d} + 1: \x{0d}\x{0d} + \r\r\r\P\P +Partial match: \x{0d}\x{0d}\x{0d} -/-- With PCRE_UCP, non-UTF8 chars that are < 256 still check properties --/ +/[^\x{100}]/8 + \x{100}\x{101}X + 0: \x{101} -/\b...\B/W - abc_ - 0: abc - !\x{c0}++\x{c1}\x{c2} - 0: ++\xc1 - !\x{c0}+++++ - 0: \xc0++ +/[^\x{100}]+/8 + \x{100}\x{101}X + 0: \x{101}X + 1: \x{101} /-- End of testinput9 --/ diff -Nru pcre3-8.12/ucp.h pcre3-8.31/ucp.h --- pcre3-8.12/ucp.h 2010-03-01 16:19:41.000000000 +0000 +++ pcre3-8.31/ucp.h 2012-02-28 14:28:09.000000000 +0000 @@ -153,7 +153,19 @@ ucp_Old_Turkic, ucp_Samaritan, ucp_Tai_Tham, - ucp_Tai_Viet + ucp_Tai_Viet, + /* New for Unicode 6.0.0: */ + ucp_Batak, + ucp_Brahmi, + ucp_Mandaic, + /* New for Unicode 6.1.0: */ + ucp_Chakma, + ucp_Meroitic_Cursive, + ucp_Meroitic_Hieroglyphs, + ucp_Miao, + ucp_Sharada, + ucp_Sora_Sompeng, + ucp_Takri }; #endif